Какие параметры обычно используются для настройки режима работы Docker
Что проверяют
Понимаете ли вы, какими настройками контейнер превращается из «у меня запустилось» в сервис, который переживает перезапуск, не съедает память хоста и корректно останавливается. Следом обычно спрашивают, что происходит при docker stop.
Как отвечать
Разделите параметры по уровням. Запуск контейнера, docker run или то же в compose.yaml:
- режим:
-dв фоне,-itинтерактивно,--rmудалить после остановки; - перезапуск:
--restartсо значениямиno(по умолчанию),on-failure,always,unless-stopped; - ресурсы:
--memoryи--cpus. При превышении памяти ядро убивает процесс, код выхода 137; - сеть:
-p 8000:8000,--network; - данные и настройки:
-vили--mount,-e,--env-file; - безопасность:
--user,--read-only,--cap-drop ALL; - здоровье и логи:
--health-cmd,--log-driver,--log-opt max-size=10m.
Уровень демона: /etc/docker/daemon.json, там задают драйвер логов и ротацию по умолчанию, live-restore, зеркала реестра.
Для Python добавьте свою специфику. В образе ставят PYTHONUNBUFFERED=1, иначе логи в docker logs приходят с задержкой. CMD пишут в exec-форме (["gunicorn", ...]), чтобы сигнал получало приложение, а не оболочка. os.cpu_count() в контейнере видит ядра хоста, а не лимит --cpus, поэтому число воркеров gunicorn или uvicorn задают явно.
Где спотыкаются
Пишут в compose-файле поле version. В современном Docker Compose оно устарело и только выдаёт предупреждение.
Не ограничивают логи. Драйвер json-file по умолчанию хранит всё без ротации, и через пару месяцев диск хоста заполнен.
Не думают о PID 1. Процесс с этим номером ядро не завершает сигналом, для которого нет обработчика. Самописный скрипт SIGTERM не ловит, docker stop ждёт 10 секунд и добивает контейнер SIGKILL. Помогает --init (или init: true в Compose) либо свой обработчик сигнала, gunicorn и uvicorn ставят его сами.