Перезапустить докер контейнер с консольным PHP

Иногда мне нужно заставить процесс перечитать свой конфиг, или свой исходный код, если это скрипт.

Как я это делаю:

  • Nginx: docker-compose exec nginx sh -c 'nginx -s reload' - у Nginx есть для этого специальный сигнал
  • unbound: docker-compose exec dns sh -c 'unbound-control reload'
  • php-fpm: docker-compose exec php-fpm sh -c 'kill 1' - просто прибиваю процесс PID 1, а в docker-compose.yml стоит политика перезапуска restart: always, поэтому контейнер перезапускается

И так далее. Если перечитывание не предусмотрено, то помогает kill 1.

И вот столкнулся с непонятным поведением: kill 1 не работает. Итак, по порядку.

Есть докер-контейнер, в котором выполняется консольная команда php /var/www/artisan queue:work --sleep=1, она держит соединение с Redis и обрабатывает очереди.

Я выполняю в этом контейнере kill 1, и ничего не происходит. Сама программа продолжает успешно обрабатывать очереди.

ps aux:

USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.1  0.1 183592 50544 ?        Ss   19:11   0:10 php /var/www/artisan queue:work --sleep=1

Почему такая ситуация? Из-за ожидания ввода-вывода? Или игнорирование сигналов?

PS. Конечно, я могу перезапустить контейнер средствами докера. Но интересно, почему такая ситуация.


Ответы (1 шт):

Автор решения: Alexander Pavlov

kill по умолчанию посылает SIGTERM, который может быть перехвачен самим процессом и проигнорирован. Вероятно, это и происходит. Можно через какое-то время посылать SIGKILL, который не может быть перехвачен (kill -9 1)


Ещё и баги у них были, так что стоит проверить свою версию

https://divinglaravel.com/queue-workers-how-they-work


Конечно, я могу перезапустить контейнер средствами докера. Но интересно, почему такая ситуация.

Это, кстати, будет самое правильное, потому что docker stop как раз сначала пошлёт SIGTERM, а потом SIGKILL.

Из документации https://docs.docker.com/engine/reference/commandline/stop/

The main process inside the container will receive SIGTERM, and after a grace period, SIGKILL.

→ Ссылка