Обычно команду запускают так:
nginx -g 'daemon off;'
Shell остаётся родительским процессом, а nginx запускается как дочерний процесс.
В обычном терминале это почти незаметно. Но в Docker-контейнерах, entrypoint-скриптах и service-wrapper’ах это может стать проблемой: сигналы приходят в shell, а не напрямую в основной процесс.
Например, такой entrypoint выглядит рабочим:
#!/usr/bin/env bash
nginx -g 'daemon off;'
Но если контейнер останавливают через docker stop, сигнал SIGTERM сначала получает shell. Если он не передаст сигнал дочернему процессу корректно, приложение может завершаться не так, как ожидается.
Для основного процесса лучше использовать exec:
#!/usr/bin/env bash
exec nginx -g 'daemon off;'
exec не создаёт новый дочерний процесс, а заменяет текущий shell указанной командой.
То есть nginx становится главным процессом:
PID 1 -> nginx
А не так:
PID 1 -> bash -> nginx
Это особенно важно для контейнеров:
docker stop app
Теперь сигнал остановки приходит напрямую в приложение, и оно может корректно завершить работу: закрыть соединения, сбросить буферы и освободить ресурсы.
exec также полезен в скриптах-обёртках:
#!/usr/bin/env bash
export APP_ENV=prod
exec ./server
После подготовки окружения shell больше не нужен, поэтому его можно заменить настоящим процессом приложения.
➡️ DevOps Ready | #совет
