Ответ
Для автоматического запуска контейнеров при загрузке системы в Docker-среде используется политика перезапуска (restart policy). Это настраивается либо в docker run, либо в docker-compose.yml.
1. Использование политики перезапуска
docker run -d --name my_app --restart unless-stopped nginx:alpine
Доступные политики:
no(по умолчанию): Не перезапускать автоматически.on-failure[:max-retries]: Перезапускать только при ошибке выхода контейнера (ненулевой код). Можно указать максимальное количество попыток.always: Всегда перезапускать. Если контейнер остановлен вручную (docker stop), Docker перезапустит его при старте демона.unless-stopped: Наиболее часто используемая мной политика. Всегда перезапускать, кроме случаев, когда контейнер был явно остановлен пользователем (docker stop). После перезагрузки системы такие контейнеры запустятся снова.
2. Настройка в Docker Compose
В файле docker-compose.yml:
version: '3.8'
services:
database:
image: postgres:15
restart: unless-stopped
environment:
POSTGRES_PASSWORD: example
webapp:
image: my-webapp:latest
restart: on-failure:3
depends_on:
- database
3. Интеграция с systemd (для контейнеров без Docker Daemon)
Если вы управляете контейнерами через podman или другой инструмент без демона, можно создать systemd-сервис:
# /etc/systemd/system/myapp-container.service
[Unit]
Description=My Application Container
After=network-online.target
[Service]
Type=forking
ExecStart=/usr/bin/podman run -d --name myapp --restart=no my-image:tag
ExecStop=/usr/bin/podman stop -t 10 myapp
ExecStopPost=/usr/bin/podman rm -f myapp
Restart=always
[Install]
WantedBy=multi-user.target
Затем выполнить sudo systemctl enable myapp-container.service.
Мой выбор: Для большинства сервисных контейнеров я использую restart: unless-stopped в Docker Compose, так как это обеспечивает авто-восстановление после сбоев системы и дает контроль для плановых остановок.
Ответ 18+ 🔞
Слушай, а вот это реально важная тема, про которую многие забывают, пока их сервис не накроется медным тазом после ребута сервера. Я тебе щас популярно объясню, как заставить эти ёбанько-контейнеры сами вставать, как ни в чём не бывало.
1. Политика перезапуска — твой главный рычаг Вот смотри, когда ты запускаешь контейнер вручную, он как мартышка — сделал своё дело и сдох. Чтобы он воскресал, надо ему прямо в команде прописать волшебные слова:
docker run -d --name my_app --restart unless-stopped nginx:alpine
Тут главное — этот самый --restart. Вариантов несколько, и доверия к ним, блядь, ноль, если не понимаешь разницы:
no(стоит по умолчанию): Не перезапускать вообще. Упал — и хуй с горы. Для тестовых штук сойдёт.on-failure[:max-retries]: Перезапустит, только если контейнер сдох с ошибкой (код выхода не ноль). Можно даже указать, сколько раз пытаться — типаon-failure:5. Удобно, если твоё приложение — хитрая жопа, которая иногда глючит.always: Воскрешать ВСЕГДА. Даже если ты его вручную прибил черезdocker stop. Демон Docker'а стартанёт — и он тут как тут. Иногда это овердохуища назойливо.unless-stopped: Вот это, ёпта, мой любимый вариант. Он умный: сам воскресает при сбоях и при перезагрузке системы, НО если ты его лично и явно остановил (docker stop), то он тебя послушается и не полезет обратно. Идеальный баланс.
2. Как это в Docker Compose прописать Тут вообще красота, всё аккуратненько в файлике. Смотри:
version: '3.8'
services:
database:
image: postgres:15
restart: unless-stopped # Вот тут прописал — и спи спокойно
environment:
POSTGRES_PASSWORD: example
webapp:
image: my-webapp:latest
restart: on-failure:3 # А этому дай три попытки, если с первого раза не взлетело
depends_on:
- database
Собрал стек через docker-compose up -d и забыл. Они теперь сами будут друг друга поднимать, если что.
3. А если у тебя не Docker, а, например, Podman? Бывает же, демона нету. Тогда, чувак, тебе прямая дорога в systemd. Делаешь файлик сервиса — и вуаля, система сама будет за твоим контейнером присматривать.
# /etc/systemd/system/myapp-container.service
[Unit]
Description=My Application Container
After=network-online.target
[Service]
Type=forking
ExecStart=/usr/bin/podman run -d --name myapp --restart=no my-image:tag # Тут restart=no, потому что перезапуском займётся systemd!
ExecStop=/usr/bin/podman stop -t 10 myapp
ExecStopPost=/usr/bin/podman rm -f myapp
Restart=always # А вот это — команда уже systemd'у перезапускать сервис
[Install]
WantedBy=multi-user.target
Потом говоришь системе: sudo systemctl enable myapp-container.service — и всё, при загрузке ОС твой контейнер стартанёт автоматически. Красота, да?
Итог мой личный: Для всего, что должно работать всегда, я юзаю restart: unless-stopped в композе. Это, блядь, золотая середина — и от сбоев защита, и возможность планово остановить сервис без того, чтобы он потом как упырь из могилы лез.