Фоновый и интерактивный режим запуска контейнеров
Режим меняет подключение терминала, но не природу контейнера: он живёт, пока жив PID 1.
Detached
docker run -d --name demo-app demo-app:1.0
docker logs -f demo-app
docker stop demo-app-d возвращает управление shell и оставляет контейнер работать. Для сервисов это обычный режим. Сигнал остановки получает PID 1; приложение должно корректно завершать работу за отведённый timeout.
Interactive
docker run --rm -it eclipse-temurin:21-jdk jshell
docker exec -it demo-app sh-iдержит stdin открытым.-tсоздаёт pseudo-TTY.runсоздаёт новый контейнер.execзапускает дополнительный процесс в уже работающем.
Для non-interactive pipeline TTY может мешать:
docker exec demo-app printenv APP_MODEAttach и сигналы
docker attach подключается к основному процессу. Нажатие Ctrl+C может передать сигнал приложению и остановить контейнер. Для диагностики обычно безопаснее logs или exec.
Если shell-скрипт стал PID 1 и не использует exec для запуска Java, сигналы могут не дойти до JVM:
#!/bin/sh
exec java -jar app.jarТипичные сбои
- Запустить сервер без
-d, закрыть терминал и принять остановку за падение. - Использовать
-itв CI без TTY. - Подключиться через
attachи случайно остановить основной процесс. - Запустить daemon внутри контейнера, а PID 1 завершить — контейнер всё равно остановится.
- Ожидать
bashв image, где есть толькоshили нет shell вообще.
Вопросы для собеседования
Что делает -d? Отключает терминал клиента после запуска; процесс остаётся основным процессом контейнера.
Чем exec отличается от run? exec добавляет процесс в существующий container, run создаёт новый.
Зачем -t? Для псевдотерминала, удобного человеку; машинам он часто не нужен.
Почему важен PID 1? Его завершение останавливает контейнер, а обработка сигналов определяет graceful shutdown.