Skip to content

Fix container lifecycle: signals, worker queues, healthcheck - #850

Merged
nkiryanov merged 1 commit into
masterfrom
fix/container-lifecycle
Jul 25, 2026
Merged

Fix container lifecycle: signals, worker queues, healthcheck#850
nkiryanov merged 1 commit into
masterfrom
fix/container-lifecycle

Conversation

@nkiryanov

Copy link
Copy Markdown
Contributor

#844 added tini and closed #802, but the signal still does not arrive:
tini hands SIGTERM to the shell, and the shell dies without passing it on.

  1. Signals never reach the appexec in all three CMDs.
    sh -c "..." stays the parent and takes SIGTERM for itself.
    Celery and uwsgi are killed together with the container, with no warm shutdown: in-flight tasks and requests are lost.

  2. uwsgi reloads on SIGTERM instead of exiting--die-on-term.
    exec alone makes it worse: the signal arrives, uwsgi reloads its workers and hangs until SIGKILL 10 seconds later.

  3. Worker is nailed to a single queue--queues=${QUEUES:-celery}, --hostname=${WORKER_NAME:-celery}@%h.
    The queue was not set at all and the hostname was hardcoded.
    A project with several queues no longer has to rewrite the CMD.

  4. Worker healthcheck is always red--destination=${WORKER_NAME:-celery}@$HOSTNAME.
    It was $QUEUE@$HOSTNAME, and nothing ever sets $QUEUE, so it stayed @hostname.
    celery inspect ping answers No nodes replied, exit 69.

Params are also split one per line: there are many of them, and on a single line you cannot see what changed.

SIGTERM died in the shell wrapper, so nothing shut down warmly.
The worker had no queue setting and its healthcheck never passed.

Refs #802.

CMD ["sh", "-c", "python manage.py migrate && uwsgi --master --http=:8000 --venv=/code/.venv/ --wsgi=app.wsgi --workers=2 --threads=2 --harakiri=25 --max-requests=1000 --log-x-forwarded-for --logformat '%(addr) - - [%(ltime)] \"%(method) %(uri) %(proto)\" %(status) %(size) \"%(referer)\" \"%(uagent)\"'"]
CMD ["sh", "-c", "python manage.py migrate \
&& exec uwsgi \

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь и в других местах: exec убирает sh из цепочки tini → sh → приложение.

Почему нужно: dash (shell-оболочка в контейнере) не передаёт SIGTERM дальше, а выходит сам, и uwsgi с celery про остановку не узнают. То есть когда добавили tini, контейнеры стали быстро завершаться, но по факту убивались, т.к. сигнал для корректной остановки не доходил до приложения.

CMD ["sh", "-c", "python manage.py migrate \
&& exec uwsgi \
--master \
--die-on-term \

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

без этого uwsgi релоадит воркеров, а не останавливается

CMD ["sh", "-c", "exec celery \
--app=${_CELERY_APP} \
worker \
--queues=${QUEUES:-celery} \

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Добавил флаг с очередями. Его не было, и чтобы запустить второй воркер на другой очереди, приходилось переписывать CMD в Dockerfile. Теперь очередь задаётся через QUEUES, а по умолчанию всё как раньше — celery

CMD celery --app=${_CELERY_APP} inspect ping --destination=$QUEUE@$HOSTNAME

CMD ["sh", "-c", "celery --app=${_CELERY_APP} worker --concurrency=${CONCURRENCY:-2} --hostname=celery@%h --max-tasks-per-child=${MAX_REQUESTS_PER_CHILD:-50} --time-limit=${TIME_LIMIT:-900} --soft-time-limit=${SOFT_TIME_LIMIT:-45}"]
CMD celery --app=${_CELERY_APP} inspect ping --destination=${WORKER_NAME:-celery}@$HOSTNAME

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут поправили healthcheck у воркеров: было$QUEUE@$HOSTNAME, но $QUEUE никто не выставляет — оставалось @hostname и хэлсчек падал.

ENV _CELERY_APP=app.celery
HEALTHCHECK NONE
CMD ["sh", "-c", "celery --app=${_CELERY_APP} beat --pidfile=/tmp/celerybeat.pid --schedule=${_SCHEDULER_DB_PATH}/celerybeat-schedule.db"]
CMD ["sh", "-c", "exec celery \

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь и везде переписал аргументы в столбик: так понятнее дифы и блеймы смотреть, что к чему относиться и комментить в PR :)

@nkiryanov
nkiryanov merged commit dedfe8a into master Jul 25, 2026
3 checks passed
@nkiryanov
nkiryanov deleted the fix/container-lifecycle branch July 25, 2026 14:22
@nkiryanov

Copy link
Copy Markdown
Contributor Author

fyi: @kazqvaizer, @f213
мержу изменения в которых уверен, но если будут комменты — по факту поправлю или откачу.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Починить запуск CMD команд в docker контейнерах

1 participant