Как сделать так, чтобы контейнер Docker запускался автоматически при загрузке системы?

102

Предположим, у меня есть контейнер Docker, который я хочу запустить, тогда я могу вызвать

$ docker run ...

и все нормально. Есть ли встроенный способ запустить контейнер таким образом, чтобы он автоматически перезапускался, если система выйдет из строя и перезагрузится?

Если да, доступно ли это также в Docker Compose?

Голо Роден
источник

Ответы:

126

Да, у докера есть политики перезапуска , docker run --restart=alwaysкоторые справятся с этим. Это также доступно в конфигурационном файле compose.yml как restart: always.

Питер Лайонс
источник
24
Это первый и принятый ответ, однако, вероятно, большинство людей, которые ищут эту функцию, действительно хотят запустить свой контейнер как службу. В ответ @kon»с с использованием в Systemdкачестве менеджера услуг является одним из лучших решений для этой цели , и нужно больше upvotes.
Реми Бешерас
1
У меня это не сработало. У меня есть контейнер под названием «crmpicco-MySQL» , и я побежал , docker run --restart=always crmpicco-mysqlи я получил ошибку: Unable to find image 'crmpicco-mysql:latest' locally.
crmpicco
2
Ваша ошибка не имеет отношения. Вы можете задать отдельный вопрос, но похоже, что вы путаете имена образов докеров и имена контейнеров докеров. Команда docker runожидает имя изображения, которое вы можете просмотреть через docker images.
Питер Лайонс
11
Единственная проблема с этим заключается в том, что «всегда» также будет бесконечно перезапускать контейнер, если он был остановлен из-за ошибки (см. Документацию). Должна быть политика, которая запускается только при запуске демона
lostiniceland
4
Я думал, что одним из основных преимуществ контейнеров / докеров является то, что мне не нужно устанавливать и управлять каждым из моих сервисов в systemd (что может быть проблемой).
Marc
133

Если вы хотите, чтобы контейнер запускался, даже если ни один пользователь не выполнил вход в систему (например, виртуальная машина VirtualBox, которую я только запускаю и не хочу входить каждый раз). Вот шаги, которые я выполнил для Ubuntu 16.04 LTS. В качестве примера я установил контейнер oracle db:

$ docker pull alexeiled/docker-oracle-xe-11g
$ docker run -d --name=MYPROJECT_oracle_db --shm-size=2g -p 1521:1521 -p 8080:8080 alexeiled/docker-oracle-xe-11g
$ vim /etc/systemd/system/docker-MYPROJECT-oracle_db.service

и добавьте следующий контент:

[Unit]
Description=Redis container
Requires=docker.service
After=docker.service

[Service]
Restart=always
ExecStart=/usr/bin/docker start -a MYPROJECT_oracle_db
ExecStop=/usr/bin/docker stop -t 2 MYPROJECT_oracle_db

[Install]
WantedBy=default.target

и включить службу при запуске

sudo systemctl enable docker-MYPROJECT-oracle_db.service

Для получения дополнительной информации https://docs.docker.com/engine/admin/host_integration/

кон
источник
8
Для тех, кто хочет сделать это с помощью docker-compose, вы можете заменить приведенную dockerвыше команду docker-composeкомандой, используя -fфлаг для указания местоположения файла docker-compose:/usr/bin/docker-compose -f /path/to/docker-compose.yml up
charlesreid1
1
Чтобы добавить к тому, что сказал @ charlesreid1, если вы docker-compose.ymlуказываете .envфайл, используйте --project-directory /path/to в дополнение к явному указанию вашего файла компоновки докеров.
whlteXbread
1
Docker имеет свою систему журналов и диспетчер процессов. К сожалению, у него нет правильной политики перезапуска.
Франклин Ю
Есть идеи, как это сделать на Windows Server 2012? Я не могу запустить докер, пока не
Алекс Лорд Мордор
Некоторым также может быть интересно, что есть полезная [Unit]директива под названием Before=. Особенно при запуске таких вещей, как системы управления базами данных, может быть полезно убедиться, что он запускается до определенных других служб.
Миха
88

Политика перезапуска по умолчанию - no.

Для созданных контейнеров используйте docker updateдля обновления политики перезапуска.

docker update --restart=always 0576df221c0b

0576df221c0b это идентификатор контейнера.

Эдвард Янг
источник
Это не alwaysзначит, что контейнер перезапустится, даже если я его остановлю? Конечно, есть способ перезапустить контейнер при перезагрузке без такого постоянного запуска ...
Marc
4
@Marc: нет. См. Документацию :If you manually stop a container, its restart policy is ignored until the Docker daemon restarts or the container is manually restarted. This is another attempt to prevent a restart loop.
SaeX,
12

Вы можете использовать docker update --restart=on-failure <container ID or name>.

Помимо того, что следует из названия, on-failureбудет перезапускать контейнер не только в случае сбоя, но и при загрузке системы.

Согласно документации , существует несколько вариантов перезапуска:

Flag            Description
no              Do not automatically restart the container. (the default)
on-failure      Restart the container if it exits due to an error, which manifests as a non-zero exit code.
always          Always restart the container if it stops. If it is manually stopped, it is restarted only when Docker daemon restarts or the container itself is manually restarted. (See the second bullet listed in restart policy details)
unless-stopped  Similar to always, except that when the container is stopped (manually or otherwise), it is not restarted even after Docker daemon restarts.
SaeX
источник
2
Вау, хорошо, что вы обнаружили это, учитывая, что это не упоминается в документации. Идеальное решение для меня.
Кэмерон Хадсон
Одна вещь, которую следует отметить об использовании при сбое, если у вас есть контейнер, который зависит от другого, уже запущенного, похоже, нет «порядка запуска», поэтому можно запустить и сразу же выйти из строя и никогда не запускаться при загрузке ОС
ferr
8

Более «щадящий» режим из документации:

docker run -dit --restart unless-stopped <image_name>
Ребро47
источник
2
К сожалению, когда демон docker останавливается перезагрузкой, демон «останавливает» контейнеры, помечая их как остановленные. Затем, когда система загружается, они фактически не запускаются. Это глупо. Вот ошибка: github.com/docker/for-linux/issues/652
mlissner
7

1) Прежде всего, вы должны включить службу докеров при загрузке

$ sudo systemctl enable docker

2) Затем, если у вас есть файл docker-compose .yml, restart: alwaysили если у вас есть контейнер докера, добавьте restart = always следующим образом:

docker run --restart=always и запустите контейнер докеров

Удостовериться

Если вы остановите контейнер вручную, его политика перезапуска будет игнорироваться до тех пор, пока демон Docker не перезапустится или контейнер не будет перезапущен вручную.

см. эту политику перезапуска на официальной странице Docker

3) Если вы хотите запустить docker-compose, все службы запускаются при перезагрузке системы, поэтому вы запускаете команду ниже только один раз

$ docker-compose up -d
Абдул Басит
источник
2

Вот для чего нужен crontab:

@reboot sleep 10 ; docker start <container name> 2>&1 | /usr/bin/logger -t 'docker start'

Получите доступ к своему пользовательскому crontab crontab -eили покажите его crontab -lили отредактируйте системный crontab по адресу/etc/crontab

Трэвис Руньярд
источник
Что такое запуск службы cron перед службой
докеров
1
@AkhilJalagam Я не уверен, что понимаю вашу проблему. "Sleep 10" дает crond достаточно времени для запуска, а затем запускает контейнер после загрузки / перезагрузки системы. Этот метод не требует от кого-либо входа в систему перед запуском и позволяет избежать запутанных и сложных служебных модулей systemd. Метод служебной единицы systemd кажется даже более хакерским, чем мой пример.
Трэвис Руньярд,
2

Вы можете запустить контейнер, который всегда перезапускается:

$ docker run -dit --restart unless-stopped <image name OR image hash>

Если вы хотите изменить конфигурацию работающего контейнера, вы должны обновить его:

$ docker update --restart=<options> <container ID OR name>

И если вы хотите увидеть текущую политику контейнера, сначала выполните следующую команду перед указанным выше:

docker inspect gateway | grep RestartPolicy -A 3

В конце концов, не забудьте включить установленный демон docker при загрузке системы :

$ systemctl enable docker

Чтобы увидеть полный список политик перезапуска, см. Политики перезапуска.

Мохсен Абаси
источник
1

Я хотел добиться запуска контейнера при загрузке в Windows.

Поэтому я просто создал запланированную задачу, которая запускается при загрузке системы. Эта задача просто запускает «Docker для Windows.exe» (или как там называется исполняемый файл вашего докера).

Затем запустятся все контейнеры с политикой перезапуска «всегда».

TostMaster
источник