Ubuntu docker compose автозапуск

Обновлено: 02.07.2024

Docker provides restart policies to control whether your containers start automatically when they exit, or when Docker restarts. Restart policies ensure that linked containers are started in the correct order. Docker recommends that you use restart policies, and avoid using process managers to start containers.

Restart policies are different from the --live-restore flag of the dockerd command. Using --live-restore allows you to keep your containers running during a Docker upgrade, though networking and user input are interrupted.

Use a restart policy

To configure the restart policy for a container, use the --restart flag when using the docker run command. The value of the --restart flag can be any of the following:

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.

The following example starts a Redis container and configures it to always restart unless it is explicitly stopped or Docker is restarted.

This command changes the restart policy for an already running container named redis .

And this command will ensure all currently running containers will be restarted unless stopped.

Restart policy details

Keep the following in mind when using restart policies:

A restart policy only takes effect after a container starts successfully. In this case, starting successfully means that the container is up for at least 10 seconds and Docker has started monitoring it. This prevents a container which does not start at all from going into a restart loop.

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.

Restart policies only apply to containers. Restart policies for swarm services are configured differently. See the flags related to service restart.

Use a process manager

If restart policies don’t suit your needs, such as when processes outside Docker depend on Docker containers, you can use a process manager such as upstart, systemd, or supervisor instead.

Warning

Do not try to combine Docker restart policies with host-level process managers, because this creates conflicts.

To use a process manager, configure it to start your container or service using the same docker start or docker service command you would normally use to start the container manually. Consult the documentation for the specific process manager for more details.

Using a process manager inside containers

Process managers can also run within the container to check whether a process is running and starts/restart it if not.

Warning

These are not Docker-aware and just monitor operating system processes within the container. Docker does not recommend this approach, because it is platform-dependent and even differs within different versions of a given Linux distribution.

and everything is fine. Is there a built-in way to run a container in a way that it will be restarted automatically, if the system crashes and reboots?

If so, is this also available in Docker Compose?

120k 82 82 gold badges 273 273 silver badges 387 387 bronze badges

12 Answers 12

Yes, docker has restart policies such as docker run --restart=always that will handle this. This is also available in the compose.yml config file as restart: always .


135k 29 29 gold badges 267 267 silver badges 268 268 bronze badges Your error is unrelated. You may want to post a separate question but it looks like you are confusing docker image names and docker container names. The docker run command expects the name of an image which you can list via docker images . The only problem with this is that "always" will also infinitely restart the container when it was stopped due to an error (see docs). There should be a policy which only starts on daemon-start

If you want the container to be started even if no user has performed a login (like the VirtualBox VM that I only start and don't want to login each time). Here are the steps I performed to for Ubuntu 16.04 LTS. As an example, I installed a oracle db container:

and add the following content:

and enable the service at startup

2,886 3 3 gold badges 24 24 silver badges 32 32 bronze badges

For the created containers use docker update to update restart policy.

0576df221c0b is the container id.


1,500 1 1 gold badge 9 9 silver badges 8 8 bronze badges @Marc: no. See the documentation: 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.

You can use docker update --restart=on-failure <container ID or name> .

On top of what the name suggests, on-failure will not only restart the container on failure, but also at system boot.

Per the documentation, there are multiple restart options:


14.4k 15 15 gold badges 72 72 silver badges 88 88 bronze badges This helped me, too, confirmed with sudo systemctl restart docker . Well spotted!

1) First of all, you must enable docker service on boot

2) Then if you have docker-compose .yml file add restart: always or if you have docker container add restart=always like this:

docker run --restart=always and run docker container

If you manually stop a container, its restart policy is ignored until the Docker daemon restarts or the container is manually restarted.

see this restart policy on Docker official page

3) If you want start docker-compose, all of the services run when you reboot your system So you run below command only once

More "gentle" mode from the documentation:


1,900 1 1 gold badge 11 11 silver badges 13 13 bronze badges

This is what crontab is for:

Access your user crontab by crontab -e or show it with crontab -l or edit your system crontab at /etc/crontab


What is cron service start before docker service. this would fail in this case.

To start a container and set it to restart automatically on system reboot use

Where ecstatic_ritchie is an example name specifying the container in interest. Use docker ps -a to list all container names.

To make particular running containers start automatically on system reboot

To make all running containers start automatically on system reboot

See more on Docker homepage

882 1 1 gold badge 12 12 silver badges 34 34 bronze badges

I wanted to achieve on-boot container startup on Windows.

Therefore, I just created a scheduled Task which launches on system boot. That task simply starts "Docker for Windows.exe" (or whatever is the name of your docker executable).

Then, all containers with a restart policy of "always" will start up.

You can run a container that restart always by:

If you want to change a running container's configs, you should update it by:

And if you want to see current policy of the container, run the following command before above at the first place:

After all, Not to forget to make installed docker daemon enable at system boot by:

To see a full list of restart policies, see: Restart Policies


I have a similar issue running Linux systems. After the system was booted, a container with a restart policy of "unless-stopped" would not restart automatically unless I typed a command that used docker in some way such as "docker ps". I was surprised as I expected that command to just report some status information. Next I tried the command "systemctl status docker". On a system where no docker commands had been run, this command reported the following:

On a system where "docker ps" had been run with no other Docker commands, I got the following:

Требуется настроить автозапуск всех имеющихся контейнеров в системе после перезагрузки ОС.

Пробую вот так:
vi /etc/systemd/system.conf
Добавляю


Но после reboot контейнеры так и не стартуют.
Второй момент, какой самый простой способ чтобы добавить в portainer поддержку ssl/tls ? Так как пароли он выводит в отрытом виде, это же просто жесть.

Простой 1 комментарий

OnYourLips

1. sudo docker run --restart=always -d your_image
2. Забайндить его на локалхост. Ходить через ssh туннель.

Еще вопрос, к примеру я в docker-compose поднимаю сервер СУБД и хочу что бы в нем крутились сразу 3-5 баз данных а не одна как например:


.
db:
image: mysql:5.7
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_USER=root
- MYSQL_PASSWORD=root
- MYSQL_DATABASE=dbname
- MYSQL_DATABASE=test
networks:
- gitea
volumes:
- /var/lib/docker/volumes/mysql:/var/lib/mysql

Понятно что можно просто запустить еще один сервер на другом порту но мне кажется что должно быть более умное решение.

OnYourLips

HexUserHex, если они для разных сервисов, то можно их поднять в разных сетях.

но в любом случае в своем .yml я получу по сути дублирущийся код


db:
image: mysql:5.7
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_USER=root
- MYSQL_PASSWORD=root
- MYSQL_DATABASE=dbname
- MYSQL_DATABASE=test
networks:
- gitea
volumes:
- /var/lib/docker/volumes/mysql:/var/lib/mysql

db2:
image: mysql:5.7
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_USER=root
- MYSQL_PASSWORD=root
- MYSQL_DATABASE=dbname
- MYSQL_DATABASE=test
networks:
- gitea
volumes:
- /var/lib/docker/volumes/mysql:/var/lib/mysql

OnYourLips

Для запуска контейнеров не надо трогать демон Докера. Дело в том, что сам докер не знает что вам надо поднимать после ребута, а что нет и надо ему просто указать на это. К тому же, одни контейнеры нужно поднимать, а другие нет. Поэтому нет смысла поднимать все, надо просто при запуске указать дополнительный флаг для контейнеров, которые должны быть подняты. Например, контейнер запускается такой командой:
docker run my-container

Для перезапуска добавьте --restart=>, например:
docker run --restart=always my-container

Подробнее о вариантах перезапуска в документации

Еще вопрос, к примеру я в docker-compose поднимаю сервер СУБД и хочу что бы в нем крутились сразу 3-5 баз данных а не одна как например:

Понятно что можно просто запустить еще один сервер на другом порту но мне кажется что должно быть более умное решение.

Существует много статей про запуск контейнеров и написание docker-compose.yml. Но для меня долгое время оставался не ясным вопрос, как правильно поступить, если какой-то контейнер не должен запускаться до тех пор, пока другой контейнер не будет готов обрабатывать его запросы или не выполнит какой-то объём работ.

Вопрос этот стал актуальным, после того, как мы стали активно использовать docker-compose, вместо запуска отдельных докеров.

Действительно, пусть приложение в контейнере B зависит от готовности сервиса в контейнере A. И вот при запуске, приложение в контейнере B этот сервис не получает. Что оно должно делать?

  • первый — умереть (желательно с кодом ошибки)
  • второй — подождать, а потом всё равно умереть, если за отведённый тайм-аут приложение в контейнере B так и не ответило

Так будет продолжаться, пока сервис в контейнере A не будет готов отвечать на запросы, либо пока мы не заметим, что у нас постоянно перегружается контейнер.
И по сути, это нормальный путь для многоконтейнерной архитектуры.

Но, мы, в частности, столкнулись с ситуацией, когда контейнер А запускается и готовит данные для контейнера B. Приложение в контейнере B не умеет само проверять готовы данные или нет, оно сразу начинает с ними работать. Поэтому, сигнал о готовности данных нам приходится получать и обрабатывать самостоятельно.

Думаю, что можно ещё привести несколько вариантов использования. Но главное, надо точно понимать зачем вы этим занимаетесь. В противном случае, лучше пользоваться стандартными средствами docker-compose

Если внимательно читать документацию, то там всё написано. А именно — каждый
контейнер единица самостоятельная и должен сам позаботиться о том, что все сервисы, с
которыми он собирается работать, ему доступны.

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

Для решения этой задачи мне сильно помогло описание docker-compose, вот эта её часть
и статья, рассказывающая про правильное использование entrypoint и cmd.

Итак, что нам нужно получить:

  • есть приложение А, которое мы завернули в контейнер А
  • оно запускается и начинает отвечать OK по порту 8000
  • а также, есть приложение B, которое мы стартуем из контейнера B, но оно должно начать работать не ранее, чем приложение А начнёт отвечать на запросы по 8000 порту

Первый это написание собственной entrypoint в контейнере, которая выполнит все проверки, а потом запустит рабочее приложение.

Второй это использование уже написанного командного файла wait-for-it.sh.
Мы попробовали оба пути.

Написание собственной entrypoint

Что такое entrypoint?

Это просто исполняемый файл, который вы указываете при создании контейнера в Dockerfile в поле ENTRYPOINT. Этот файл, как уже было сказано, выполняет проверки, а потом запускает основное приложение контейнера.

Итак, что у нас получается:

Создадим папку Entrypoint.

В ней две подпапки — container_A и container_B. В них будем создавать наши контейнеры.

Для того, чтобы наш эксперимент был более явным, поставим перед запуском сервера задержку в 15 секунд.

Получается следующий докер файл для контейнера А:


Для контейнера B создадим следующий докер файл для контейнера B:


И положим наш исполняемый файл entrypoint.sh в эту же папку. Он у нас будет вот такой


Что у нас происходит в контейнере B:

  • При своём старте он запускает ENTRYPOINT, т.е. запускает entrypoint.sh
  • entrypoint.sh, с помощью curl, начинает опрашивать порт 8000 у контейнера A. Делает он это до тех пор, пока не получит ответ 200 (т.е. curl в этом случае завершится с нулевым результатом и цикл закончится)
  • Когда 200 получено, цикл завершается и управление передаётся команде, указанной в переменной $cmd. А в ней указано то, что мы указали в докер файле в поле CMD, т.е. . Почему это так, рассказывается в указанной выше статье
  • Печатаем —

docker-compose.yml у нас вот такой:

Также, контейнер B не перезапускаем после завершения работы.


Получаем ответ на свой запрос, печатаем и завершаемся.

Использование wait-for-it.sh

Сразу стоит сказать, что этот путь у нас не заработал так, как это описано в документации.
А именно, известно, что если в Dockerfile прописать ENTRYPOINT и CMD, то при запуске контейнера будет выполняться команда из ENTRYPOINT, а в качестве параметров ей будет передано содержимое CMD.

Также известно, что ENTRYPOINT и CMD, указанные в Dockerfile, можно переопределить в docker-compose.yml

Формат запуска wait-for-it.sh следующий:


Тогда, как указано в статье, мы можем определить новую ENTRYPOINT в docker-compose.yml, а CMD подставится из Dockerfile.

Докер файл для контейнера А остаётся без изменений:


Докер файл для контейнера B


Docker-compose.yml выглядит вот так:


Запускаем команду wait-for-it, указываем ей ждать 20 секунд пока оживёт контейнер A и указываем ещё один параметр «--», который должен отделять параметры wait-for-it от программы, которую он запустит после своего завершения.

Пробуем!
И к сожалению, ничего не получаем.

Если мы проверим с какими аргументами у нас запускается wait-for-it, то мы увидим, что передаётся ей только то, что мы указали в entrypoint, CMD из контейнера не присоединяется.

As I hosted a WordPress site in docker containers and i want these containers to be started at boot time always, so need to done it manually.


6,835 17 17 gold badges 27 27 silver badges 42 42 bronze badges


661 1 1 gold badge 5 5 silver badges 4 4 bronze badges Crossposted. Please pick one site, not many, for posting things on.

4 Answers 4

It is a very common use case to add the restart policy on an existing container.

This could be done with the following command: docker update --restart container_name

This solved my problem perfectly! I had a container with my database, and wanted it to start when my Mac started. By specifying that its image was always restarted (unless stopped), this did the trick! A downside to using systemd is that if I use docker stop then systemd restarts it

! You have to use systemd stop to stop the container

Till now I don't think there is a way to do that normally. A tricky solution is to use restart policy

This means whenever you shut down this will exit your container so as you start your host then this lead to restart the docker.

1,273 1 1 gold badge 10 10 silver badges 13 13 bronze badges 76k 50 50 gold badges 225 225 silver badges 261 261 bronze badges as i search about it there are some automation tools like chef but dont know how to use them Why not use system possibilities for this? both upstart and systemd can deal with this perfectly

As ubuntu 15 now supports systemd, sample for this manager:

More available on docker site

P.S. Pretty cute config :)


A downside to using systemd is that if I use docker stop then systemd restarts it

! You have to use systemd stop to stop the container

@FreeSoftwareServers well, if you put something to be managed by something, then you should not manage it manually and let it be managed by that tool. Alternatively, you can edit the service file to instruct systemd to start the service only at booting sequence, i showed here the generic approach - details can be tuned further by any your needs.

What I did is to use Upstart files.

You can find some examples and other solutions in the Docker website.

Create a file such like that in /etc/init :

Note, as from Docker 1.2, there are restart policies which may also help to automatically restart containers when the docker service is run (after boot for example).

Personnaly, I use puppet to provision my workstation and use this Docker module to automatically create the startup scripts which are more complete (start, stop, restart, clean options. )

Читайте также: