Como executar docker-compose up -d na inicialização do sistema?

114

Para permitir que os contêineres sejam iniciados automaticamente no ponto de inicialização, tentei adicionar o comando:

cd directory_has_docker-compose.yml && docker-compose up -d em /etc/rc.local.

mas depois de reiniciar a máquina, os contêineres não funcionam.

Como funciona docker-compose up -dna inicialização do sistema?

user39544
fonte
3
use --restart alwaysou --restart unless-stoppedou em docker-compose.yml use restart: always-> Ref . Mas talvez não funcione em alguns recipientes!
Benyamin Jafari

Respostas:

129

Quando usamos crontabou o /etc/rc.localarquivo obsoleto , precisamos de um atraso (por exemplo sleep 10, dependendo da máquina) para garantir que os serviços do sistema estejam disponíveis. Normalmente, systemd(ou upstart) é usado para gerenciar quais serviços iniciam quando o sistema é inicializado. Você pode tentar usar a configuração semelhante para isso:

# /etc/systemd/system/docker-compose-app.service

[Unit]
Description=Docker Compose Application Service
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/srv/docker
ExecStart=/usr/local/bin/docker-compose up -d
ExecStop=/usr/local/bin/docker-compose down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target

Ou, se você quiser executar sem a -dbandeira:

# /etc/systemd/system/docker-compose-app.service

[Unit]
Description=Docker Compose Application Service
Requires=docker.service
After=docker.service

[Service]
WorkingDirectory=/srv/docker
ExecStart=/usr/local/bin/docker-compose up
ExecStop=/usr/local/bin/docker-compose down
TimeoutStartSec=0
Restart=on-failure
StartLimitIntervalSec=60
StartLimitBurst=3

[Install]
WantedBy=multi-user.target

Altere o WorkingDirectoryparâmetro com o caminho do projeto encaixado. E habilite o serviço para iniciar automaticamente:

systemctl enable docker-compose-app
Oleg Belostotsky
fonte
Existe uma maneira simples de testar se funciona sem reiniciar o Framboesa?
dmigo
2
Esta é a resposta mais elegante IMO
kuzyn
2
@dmigo systemctl start docker-compose-appe systemctl status docker-compose-appsão o que você está procurando, eu acho.
HectorJ
não funcionou para mim, quando eu corri systemctl start docker-compose-appencontrei com isso:Job for docker-compose-app.service failed because the control process exited with error code. See "systemctl status docker-compose-app.service" and "journalctl -xe" for details
Benyamin Jafari
1
@dmigo: teste a inicialização do seu serviço com service docker-compose-app startservice docker-compose-app statusservice docker-compose-app stop
:,
96

Você deve ser capaz de adicionar:

restart: always 

a cada serviço que você deseja reiniciar no arquivo docker-compose.yml

MaxiReglisse
fonte
6
Lembre-se de que eles precisam estar em execução quando ocorre uma reinicialização, portanto, não os interrompa manualmente antes da reinicialização.
Tom
alguns serviços como o Nginx nem mesmo começam com essa opção.
Benyamin Jafari
15
Esta é a resposta adequada à pergunta. Existe uma maneira projetada de reiniciar contêineres, por que entrar em tarefas cron e outras maneiras de reinventar a roda.
Taha Rehman Siddiqui
Esta é a resposta certa. Quando você começar a usar o Kubernetes em vez do cron, ficará feliz por tê-lo usado.
pferrel
9
@TahaRehmanSiddiqui Note que restart: alwaystem alguns bugs sérios: montagens de host não serão anexadas na reinicialização, por exemplo. Na minha opinião, é melhor reinventar a roda, se a roda existente for quadrada.
okdewit
73

Se docker.serviceestiver ativado na inicialização do sistema

$ sudo systemctl enable docker

e seus serviços em seu docker-compose.ymltem

restart: always

todos os serviços executados quando você reinicializa o sistema se você executar o comando abaixo apenas uma vez

docker-compose up -d
Masoud Vatandoost
fonte
2
esta deve ser a solução mais elegante
Carl Cheung,
34

Eu tentei restart: always, funciona em alguns contêineres (como php-fpm), mas enfrentei o problema de alguns contêineres (como o nginx) ainda não reiniciam após a reinicialização.

Resolveu o problema.

crontab -e

@reboot (sleep 30s ; cd directory_has_dockercomposeyml ; /usr/local/bin/docker-compose up -d )&
user39544
fonte
2
Por que um voto negativo para esta resposta? A resposta não é útil? Isso está errado em algum sentido? Um comentário seria útil para permitir que quem responde e outras pessoas saibam o que está errado.
Ayushya de
5
Você deve desconfiar de sono nua, pois eles apresentam comportamento não determinístico: martinfowler.com/articles/…
giorgiosironi
@giorgiosironi dormir é bom neste caso. A inicialização do contêiner deve ser capaz de lidar com o comportamento não determinístico de qualquer maneira.
z0r
4
Também está introduzindo até 30 segundos de latência que podem não ser necessários.
giorgiosironi
@ z0r dormir não está bem! O sono pode "funcionar", mas qualquer sequência de inicialização deve ser determinística. Os serviços Linux usam dependências para garantir que coisas como a rede estejam disponíveis, etc., antes de iniciar. Você deveria fazer o mesmo.
colm.anseo
25

Use restart: sempre em seu arquivo docker compose.

Docker-compose up -diniciará o contêiner a partir das imagens novamente. Use docker-compose startpara iniciar os contêineres parados, nunca inicia novos contêineres de imagens.

nginx:   
    restart: always   
    image: nginx   
    ports:
      - "80:80"
      - "443:443"   links:
      - other_container:other_container

Além disso, você pode escrever o código no arquivo docker para que seja criado primeiro, caso seja dependente de outros contêineres.

Vaseem007
fonte
1
Você pode não querer usar always, mas talvez unless-stopped. Outras opções são on-failuree no. Isso é conhecido como política de reinicialização .
Paul
5

Além user39544da resposta de, mais um tipo de sintaxe para crontab -e:

@reboot sleep 60 && /usr/local/bin/docker-compose -f /path_to_your_project/docker-compose.yml up -d
TitanFighter
fonte
Isso funcionou para mim em março de 2018 em um RPi3 executando Raspian. Corri crontab -ecomo usuário pi, com pi um membro do grupo docker ...
Scott Veirs