Learning Platform
Глоссарий Troubleshooting
Урок 05.05 · 16 мин
Начальный
dockerrestart-policylifecyclecontainer-name

—name и —restart

Эти два флага мы уже встречали в предыдущих уроках мимоходом. Сейчас разберём подробно: как Docker именует контейнеры, как работает auto-restart, и какие вообще состояния бывает у контейнера.

В конце урока — диаграмма жизненного цикла, которую полезно держать в голове.


—name — имена контейнеров

Без --name Docker даёт случайное имя из двух слов: прилагательное + фамилия известного учёного. Например, silly_einstein, inspiring_curie, competent_torvalds. Это и забавно, и проблема: через 5 минут ты не помнишь, какой именно silly_einstein это твой Postgres.

С --name:

docker run -d --name pg postgres:16.4

Теперь во всех командах можно обращаться по имени:

docker logs pg
docker exec -it pg bash
docker stop pg
docker rm pg

Правила для имен

  • Только [a-zA-Z0-9][a-zA-Z0-9_.-]*. Никаких пробелов, спецсимволов.
  • Длина до 255 символов.
  • Имя должно быть уникальным на хосте.

Если контейнер с таким именем уже существует (даже если он остановлен) — docker run упадёт:

docker: Error response from daemon: Conflict. The container name "/pg" is already in use by container "abc123...".

Решение: или удалить старый (docker rm pg), или дать новое имя.

DNS-иерархия — root, TLD, authoritative, recursive resolvers

DNS-имя в Docker network

Имя контейнера используется как DNS-имя внутри Docker сети. Если в одной сети есть контейнеры pg и app, контейнер app может обратиться к Postgres по адресу pg:5432. Никаких IP, никакого /etc/hosts.

docker network create demo
docker run -d --name pg --network demo postgres:16.4
docker run --rm -it --network demo alpine sh -c 'apk add bind-tools && nslookup pg'
# вернёт IP контейнера pg в этой сети

Это базовая фича Docker networking. Подробнее в модуле 10.


—restart: политики автоперезапуска

docker run -d --name pg --restart=unless-stopped postgres:16.4

Флаг --restart говорит Docker’у, что делать, если процесс контейнера завершился (упал, ребутнулся хост, и т.д.).

Четыре политики restart
noDefault. Не перезапускать никогда. Если контейнер упал — лежит в exited. Используется для одноразовых задач
on-failureПерезапускать, только если процесс завершился с non-zero exit code. Если exit 0 — не трогать. Опционально с лимитом попыток
alwaysВсегда перезапускать, независимо от exit code. Перезапуск работает даже после рестарта хоста (для запущенных раньше)
unless-stoppedКак always, но НЕ перезапускает контейнеры, которые были явно остановлены через docker stop. Самая часто используемая в DE-сценариях

no (по умолчанию)

docker run -d --name etl python:3.12 python -c 'print("hi")'

Контейнер запустится, выполнит команду, завершится с exit 0 — лежит в exited. Не перезапускается.

on-failure

docker run -d --name worker --restart=on-failure:3 my-worker

on-failure:3 — максимум 3 попытки. Если все 3 раза упало — контейнер остаётся в exited, больше не пробует.

Полезно для ETL-задач, где «упало — попробуй ещё раз» — нормально, но «упало 100 раз подряд» — это уже бесконечный цикл.

always

docker run -d --name pg --restart=always postgres:16.4

Всегда перезапускать. Даже если ты делаешь docker stop pg, после рестарта Docker daemon (например, перезагрузка хоста) контейнер снова стартует.

Это бывает раздражающе: ты явно остановил, а оно само поднимается.

unless-stopped

docker run -d --name pg --restart=unless-stopped postgres:16.4

Это рекомендуемый default для большинства сервисов. Семантика:

  • Контейнер упал -> перезапустится.
  • Хост перезагрузился -> контейнер запустится при старте Docker.
  • Ты сделал docker stop pg -> контейнер не запустится. Даже после рестарта хоста.

То есть «стартуй сам, но если я явно остановил — уважай это».


После рестарта хоста

Что произойдёт с контейнерами при перезагрузке machine’ы:

Restart policyБыл запущенБыл остановленБыл exited (упал)
noНЕ стартуетНЕ стартуетНЕ стартует
on-failureстартует (если упал)НЕ стартуетстартует
alwaysстартуетстартуетстартует
unless-stoppedстартуетНЕ стартуетстартует

Это критично, например, для production — если у тебя на VPS Postgres с --restart=unless-stopped, после перезагрузки VPS он сам поднимется. Без явного --restart — будешь поднимать руками.


Жизненный цикл контейнера

Контейнер проходит через несколько состояний:

Состояния контейнера от created до dead
createddocker create отработал. Контейнер существует, его конфигурация и rootfs готовы. Но процесс ещё не запущен
start
runningПроцесс запущен. State.Running=true. docker ps без -a покажет именно это
pause
pausedПроцессы заморожены через cgroup freezer. CPU не получает. Память сохранена. docker unpause возобновит
exitedГлавный процесс завершился (exit code 0 или non-zero). Контейнер существует, но процесс мёртв. docker start вернёт в running
stop / процесс упал
running(тот же что выше)
deadРедкое состояние: контейнер не удалось убить, или storage driver упал. Обычно требует ручного docker rm
restartingПромежуточное: --restart=on-failure и контейнер только что упал, daemon ждёт чтобы стартовать его снова

Переходы

  • docker create -> created.
  • docker start -> running.
  • docker run -> created -> running (за одну команду).
  • docker pause -> paused.
  • docker unpause -> running.
  • docker stop или процесс завершился -> exited.
  • docker start <exited> -> снова running.
  • docker rm <not-running> -> контейнер исчезает.

Что показывает inspect

docker inspect pg --format '{{.State.Status}}'
# running

docker inspect pg --format '{{json .State}}' | jq

Покажет полное состояние: Status, Running, Paused, Restarting, OOMKilled, Dead, Pid, ExitCode, Error, StartedAt, FinishedAt.

Поля типа OOMKilled: true или Error: "..." — это первый сигнал, почему контейнер упал. Не надо лезть в логи, если inspect сразу говорит «убит OOM-киллером».


Связь с production

В production стэке с правильным orchestrator (k8s) restart policy управляется на уровне Pod’а / Deployment’а. Чистый Docker с --restart=unless-stopped — это про single-host stage / dev / lightweight production.

Для dev-машины и Compose:

services:
  pg:
    image: postgres:16.4
    restart: unless-stopped

Это эквивалент --restart=unless-stopped. Подробно про Compose — в модулях 10-11.


Попробуй сам

# 1. Контейнер с unless-stopped
docker run -d --name pg --restart=unless-stopped \
  -e POSTGRES_PASSWORD=s postgres:16.4
sleep 3

# 2. Посмотри restart policy
docker inspect pg --format '{{.HostConfig.RestartPolicy.Name}}'
# unless-stopped

# 3. Симулируй "крах" — убей главный процесс
docker exec pg pkill -9 postgres
# подожди пару секунд
sleep 3
docker ps --filter name=pg
# увидишь "Up X seconds" — Docker перезапустил его

# 4. Явный stop — restart не сработает
docker stop pg
docker ps --filter name=pg
# пусто
docker ps -a --filter name=pg
# Exited

# 5. Прибраться
docker rm -f pg

Сводка

  • --name CONTAINER — обязательно для всего, что живёт дольше минуты. Удобство обращения + DNS-имя в Docker сети.
  • --restart=unless-stopped — для daily DE-стэка (Postgres, Redis, etc.). Авто-рестарт + уважение явного stop.
  • Жизненный цикл: created -> running -> paused/exited. dead и restarting — служебные.
  • docker inspect ... .State — отвечает на вопрос «почему контейнер не работает» в 50% случаев.

Проверка знанийKnowledge check
Какие политики --restart существуют, и какая из них рекомендуется как default для daily DE-сервисов вроде Postgres?
ОтветAnswer
Docker поддерживает четыре политики restart. no — default, не перезапускать никогда, используется для одноразовых задач. on-failure[:N] — перезапускать только если процесс упал с non-zero exit, опционально с лимитом попыток (например, on-failure:3 — максимум 3 попытки). always — всегда перезапускать, включая случаи, когда ты явно сделал docker stop, и после рестарта хоста. unless-stopped — как always, но НЕ перезапускает контейнеры, которые были явно остановлены через docker stop, при этом после рестарта хоста контейнер стартует, если был запущен до перезагрузки. Для daily DE-сервисов (Postgres, Redis, Kafka на dev-машине) рекомендуется именно unless-stopped. Семантика «стартуй сам, но если я явно остановил — уважай моё решение» наиболее предсказуема. always раздражает: ты остановил контейнер для отладки, а он сам поднимается. no опасно: упал контейнер при перезагрузке VPS, и сервис недоступен до твоего ручного вмешательства. В Compose это пишется как restart: unless-stopped в секции service.

Проверьте понимание

Результат: 0 из 0
Прикладной
Вопрос 1 из 5. Зачем использовать --name pg при запуске контейнера?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5