# Проблема зомби в процессах Docker-контейнера **Category:** [Ввод сервиса](https://discuss.rabkesov.ru/c/service/5) **Created:** 2026-04-22 10:43 UTC **Views:** 30 **Replies:** 0 **URL:** https://discuss.rabkesov.ru/t/problema-zombi-v-proczessah-docker-kontejnera/403 --- ## Post #1 by @ivan Проблема классическая: python запущен PID 1 в контейнере, и при таймаутах SSH (особенно с ProxyCommand/bastion) внуки переподвешиваются на PID 1, который их не жнёт — отсюда зомби. Чиню двумя слоями: ставлю tini как init в самом образе (защищает любой docker run), и включаю init: true в compose как явный сигнал. ``` RUN apt-get update \ && apt-get install -y --no-install-recommends openssh-client \ && apt-get install -y --no-install-recommends openssh-client tini \ && rm -rf /var/lib/apt/lists/* ENTRYPOINT ["python3", "/app/server.py", "--host", "0.0.0.0", "--config", "/config/config.yaml"] # tini как PID 1: жнёт осиротевших внуков (ProxyCommand/bastion, ssh-таймауты) # и корректно прокидывает сигналы в python-сервер. ENTRYPOINT ["/usr/bin/tini", "-g", "--", "python3", "/app/server.py", "--host", "0.0.0.0", "--config", "/config/config.yaml"] restart: always # На случай, если ENTRYPOINT в образе был переопределён: docker-init (tini) # подхватит зомби от ssh/ProxyCommand при таймаутах. init: true ports: ``` Что изменилось и почему: - `Dockerfile`: ставлю пакет `tini` и оборачиваю команду `tini -g -- python3 …`. Теперь PID 1 — это `tini`, который: - реапит осиротевших внуков (главный источник зомби — `ssh` с `ProxyCommand`/bastion, убитый по `ConnectTimeout`/`SSH_TIMEOUT_SEC`, оставляет дочерний `ssh` к bastion подвешенным на init); - корректно прокидывает `SIGTERM`/`SIGINT` всей группе процессов (флаг `-g`), чтобы `docker stop` не висел 10 секунд и не оставлял ssh-хвостов. - `docker-compose.yml`: `init: true` — пояс поверх подтяжек, на случай если кто-то локально переопределит `entrypoint:` (тогда tini из образа исчезнет, но docker-init всё равно встанет PID 1). Применить: ```bash docker compose build --no-cache ansible-status docker compose up -d ``` Проверить, что зомби больше не плодятся (внутри контейнера не должно быть строк с `Z` в STAT): ```bash docker compose exec ansible-status sh -c 'ps -e -o pid,ppid,stat,comm | awk "NR==1 || /Z/"' ``` Если хочется ещё аккуратнее — можно отдельным шагом добавить в `ssh_check_for_target` опции `-o ControlMaster=no -o ControlPath=none` и `start_new_session=True` в `subprocess.run`, чтобы `ssh` не плодил долгоживущих мультиплексоров и при `TimeoutExpired` мы могли убивать всю process group, а не только головной `ssh`. Но это уже улучшение поведения, а самой причины зомби — отсутствия init — уже нет. --- **Canonical:** https://discuss.rabkesov.ru/t/problema-zombi-v-proczessah-docker-kontejnera/403 **Original content:** https://discuss.rabkesov.ru/t/problema-zombi-v-proczessah-docker-kontejnera/403