SSD Nodes Learn Hosting plans →
Guias Matt ConnorPor Matt Connor · Atualizado 2026-08-25

Docker Compose iniciar serviços automaticamente no boot

Configure restart: always ou unless-stopped para o Compose voltar após o reboot. Veja por que on-failure não sobrevive e quando usar uma unidade systemd.

A resposta curta

Os serviços do Docker Compose arrancam no boot quando duas condições são cumpridas ao mesmo tempo. O daemon do Docker tem de estar ativado como serviço do sistema, e cada serviço no ficheiro tem de incluir uma política de reinício com unless-stopped ou always. Adicione restart: unless-stopped a todos os serviços, execute docker compose up -d uma vez e os contentores voltarão a arrancar automaticamente depois de um reboot. No caso comum, não é necessária mais nenhuma configuração.

Só precisa de uma unidade systemd quando a ordem de arranque é importante: por exemplo, uma stack que dependa de um disco montado, de uma interface VPN ou de um compartilhamento de rede que ainda não esteja disponível quando o daemon do Docker arrancar. Esse caso é real, e a segunda metade deste guia trata dele. Se ainda estiver a familiarizar-se com definições de serviços e volumes, comece por os conceitos básicos do Docker Compose numa VPS e volte depois.

Defina a política de reinício em compose.yaml

A política é definida uma vez por serviço. Não existe uma opção global. Por isso, um serviço que ficar de fora permanece parado depois do reboot, enquanto o restante da stack inicia.

services:
  app:
    image: nginx:1.27
    restart: unless-stopped
    ports:
      - "8080:80"
  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: change-me
    volumes:
      - dbdata:/var/lib/postgresql/data

volumes:
  dbdata:

Aplique a alteração e depois leia a política do container em execução:

docker compose up -d
docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' $(docker compose ps -q app)

Isto mostra unless-stopped. Se mostrar no, o ficheiro foi editado, mas o container nunca foi recriado.

Esta é a falha mais comum. A política de reinício fica armazenada no container, não no ficheiro YAML. Editar compose.yaml não altera um container que já existe. docker compose restart também não resolve, porque para e inicia o mesmo objeto de container sem alterar a sua configuração. Apenas docker compose up -d compara o ficheiro com os containers em execução, deteta que a política mudou e recria os containers.

Para um container que não pretende recriar agora, altere a política diretamente:

docker update --restart unless-stopped my-container

Edite também o ficheiro YAML. docker update altera o container em execução, e o próximo docker compose up -d lê o ficheiro e repõe o valor anterior.

O que cada valor de reinício faz na prática

O Docker define quatro valores. A diferença entre eles só se manifesta quando a máquina reinicia ou quando o daemon é reiniciado.

  • no é o valor predefinido. O contentor nunca é reiniciado automaticamente, em nenhuma circunstância.
  • always reinicia o contentor sempre que este para. Se o parou manualmente, ele volta a arrancar na próxima vez que o daemon do Docker iniciar. Isto causa frequentemente surpresas: um contentor que parou deliberadamente na semana passada está novamente em execução depois de um reboot.
  • unless-stopped comporta-se como always, mas um contentor parado manualmente permanece parado depois do reinício do daemon. Este é o valor adequado para um serviço que é ocasionalmente parado para manutenção.
  • on-failure reinicia o contentor apenas quando este termina com um código de saída diferente de zero. Pode limitar o número de tentativas, como em restart: on-failure:3.

Para uma stack que deve estar simplesmente em execução sempre que o servidor estiver ativo, unless-stopped é o valor predefinido adequado. Escolha always apenas quando quiser um contentor que não permaneça parado.

Por que restart: on-failure não sobrevive a um reboot

Muitas pessoas escolhem on-failure porque parece uma opção cuidadosa, mas depois encontram todos os contentores parados após o primeiro reboot. O motivo está na definição. on-failure reage apenas a uma situação: o processo do contentor termina com um código de erro.

Um reboot não é um erro. Quando o host é desligado, o systemd para docker.service, e o daemon para deliberadamente cada contentor. O contentor não falhou, portanto a política não tem nada a que reagir. No arranque seguinte, o daemon verifica os contentores que precisa de retomar, e um contentor on-failure que foi parado corretamente não está entre eles. Permanece no estado exited.

Pode verificar isto diretamente. Defina restart: on-failure num serviço, execute docker compose up -d, faça reboot e execute:

docker compose ps -a

O serviço aparece com o estado Exited e um estado semelhante a Exited (0) 2 minutes ago. Nada está avariado e nada é registado como erro, o que dificulta o diagnóstico. A política fez exatamente o que está definido para fazer.

on-failure continua a ser útil. É adequado para um contentor que executa uma tarefa e pode falhar, quando pretende um número limitado de novas tentativas sem criar um ciclo de reinício. É a ferramenta errada para manter um serviço de execução contínua ativo entre reboots.

As políticas de reinício só funcionam se o serviço Docker arrancar no boot

As políticas de reinício são aplicadas pelo daemon do Docker. Se o daemon não arrancar, nada as aplica. Verifique:

systemctl is-enabled docker
systemctl is-enabled containerd

Ambos devem apresentar enabled. Os pacotes do repositório oficial do Docker ativam estas unidades durante a instalação, por isso este teste normalmente passa num servidor novo. Se algum apresentar disabled, corrija-o:

sudo systemctl enable --now docker containerd

Há uma particularidade importante. O Ubuntu também fornece docker.socket, que inicia o daemon a pedido quando algo comunica pela primeira vez com a API do Docker. É comum ver docker.socket ativado, assumir que o daemon está coberto e desativar docker.service para poupar memória. No boot, nada chama a API. Por isso, o socket nunca é acedido, o daemon nunca arranca e nenhum contentor é iniciado até executar o primeiro comando docker. A ativação por socket não substitui docker.service ativado.

Quando uma unidade systemd é a melhor opção

As políticas de reinício não têm noção da ordem de arranque em relação ao resto do sistema. O daemon inicia e coloca os contentores em execução assim que pode. Se a sua stack monta uma diretoria de um volume separado, uma partilha NFS (sistema de ficheiros de rede) ou um disco encriptado através de bind mount, os contentores podem iniciar antes de esse caminho existir. O Docker cria automaticamente uma diretoria vazia no ponto de montagem e inicia o contentor com base nela. A base de dados fica então sem dados.

Crie uma unidade systemd quando alguma destas condições se aplicar. A stack precisa que um sistema de ficheiros, uma interface VPN ou outra unidade esteja pronta primeiro. Quer que systemctl stop myapp e systemctl start myapp funcionem como funcionam para qualquer outro serviço do sistema. Ou quer que a stack seja terminada de forma limpa durante o encerramento, em vez de ser terminada juntamente com o daemon. Se as unidades systemd forem novas para si, criar um serviço e um temporizador systemd explica o formato do ficheiro com mais detalhe.

Escrevendo a unidade systemd

Coloque a stack num caminho fixo fora de um diretório pessoal. /srv/myapp é uma boa escolha, porque uma unidade que arranca antes de qualquer utilizador iniciar sessão não precisa de ler /home.

Crie /etc/systemd/system/myapp.service:

[Unit]
Description=myapp docker compose stack
Requires=docker.service
After=docker.service network-online.target
Wants=network-online.target
RequiresMountsFor=/srv/myapp/data

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

[Install]
WantedBy=multi-user.target

Ative e inicie-a:

sudo systemctl daemon-reload
sudo systemctl enable --now myapp.service
systemctl status myapp.service

Uma unidade saudável mostra Active: active (exited). À primeira vista, isso parece errado. Está correto: Type=oneshot com RemainAfterExit=yes significa que a unidade executou o comando, o comando terminou e o systemd mantém a unidade marcada como ativa para que ExecStop seja executado no encerramento.

Cada linha tem uma função. Requires=docker.service faz a unidade falhar rapidamente, em vez de executar docker compose contra um socket inativo. After= define a ordem, porque Requires=, por si só, não a define. RequiresMountsFor= faz o systemd incluir a unidade de montagem desse caminho e aguardar por ela. Esta é precisamente a razão para usar uma unidade em vez de uma política de reinício. TimeoutStartSec=0 impede o systemd de terminar o job de arranque enquanto uma imagem grande ainda está a ser obtida.

Uma nota sobre a combinação dos dois mecanismos. A documentação do Docker recomenda não combinar políticas de reinício com um gestor de processos no host. O aviso refere-se a um gestor de processos que supervisiona diretamente o processo do contentor e o reinicia enquanto o daemon tenta fazer o mesmo. Uma unidade Type=oneshot não supervisiona nada. Por isso, manter restart: unless-stopped no ficheiro compose juntamente com esta unidade é correto e é o que pretende. O systemd trata da ordem durante o arranque e o daemon trata de um contentor que falhe às três da manhã.

A unidade é diferente quando aquilo que pretende manter ativo é um processo simples de longa duração, e não uma stack. Nesse caso, não existe um daemon subjacente e o próprio Restart= do systemd tem de fazer a supervisão; executar o dsh sem interface gráfica sob o systemd é um exemplo completo desse modelo, incluindo o utilizador dedicado e o journal.

Verifique com um reboot real

Não há substituto para o teste real. systemctl restart docker não testa a ordem de montagem, e docker compose down seguido de docker compose up -d não testa nada relacionado com o boot.

sudo reboot

Aguarde, volte a ligar-se e verifique pela seguinte ordem:

uptime
systemctl is-active docker
docker compose ps

uptime confirma que está a consultar uma máquina que realmente fez reboot. docker compose ps, executado a partir do diretório da stack, deve listar todos os serviços como running, com um uptime próximo do da máquina. Um serviço que apareça como Exited é o que deve verificar.

Se algo não iniciou, o log do daemon cobre a janela do boot:

journalctl -u docker.service -b --no-pager | tail -50

Para uma stack gerida por uma unit, journalctl -u myapp.service -b --no-pager mostra o resultado exato de docker compose desde o boot, incluindo uma falha ao obter uma imagem ou um ficheiro .env em falta. O reboot que agenda é aquele que acompanha, por isso deixe a unit informá-lo sobre os outros: uma linha OnFailure= apontada para um servidor ntfy autoalojado transforma uma stack que não voltou a iniciar numa notificação push, em vez de ser algo que só descobre dias depois.

Coisas que interrompem silenciosamente o arranque automático

Os contentores criados com docker compose run nunca recebem a política de reinício definida no ficheiro. O Compose trata-os como contentores executados uma única vez. Se um serviço parecer ignorar a sua política, confirme se foi iniciado com run em vez de up.

Um caminho relativo num volume ou numa entrada env_file é resolvido relativamente ao diretório do ficheiro compose. Isso funciona a partir da sua shell e também funciona a partir de uma unidade que define WorkingDirectory. Falha a partir de uma unidade sem essa definição, porque o diretório de trabalho passa a ser /.

O Docker rootless é um caso separado. O daemon é executado como um serviço de utilizador, e um serviço de utilizador para quando termina a última sessão desse utilizador. Ative-o para o utilizador e permita que continue em execução sem ninguém autenticado:

systemctl --user enable docker
sudo loginctl enable-linger $USER

Sem enable-linger, o daemon rootless é encerrado quando termina a sessão e os contentores também param. Isso parece exatamente uma política de reinício avariada.

Há ainda um último ponto. As atualizações de segurança automáticas podem reiniciar um servidor a uma hora fixa. Isso só é positivo se a sua stack arrancar novamente sozinha. Configurar esse comportamento numa máquina nova faz parte do restante trabalho da primeira hora, descrito em os primeiros dez minutos num novo VPS.

FAQ

Qual é a diferença entre restart: always e restart: unless-stopped?

Ambos reiniciam o contentor quando este para por iniciativa própria. A diferença ocorre depois de parar um contentor manualmente. Com always, o contentor inicia novamente na próxima vez que o daemon do Docker arrancar, pelo que um reboot anula a paragem manual. Com unless-stopped, o daemon memoriza que o contentor foi parado deliberadamente e deixa-o parado. Use unless-stopped, a menos que queira especificamente um contentor que permaneça parado.

Adicionei restart: unless-stopped, mas o contentor continua a não iniciar depois de um reboot. Porquê?

A política fica definida no contentor, não no ficheiro, e editar o YAML não atualiza um contentor que já existe. Execute docker compose up -d para que o Compose o recrie e confirme depois com docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' $(docker compose ps -q app). Se esse comando apresentar no, o contentor foi criado antes da sua alteração. A outra causa comum é docker.service não estar ativado, o que pode verificar com systemctl is-enabled docker.

Preciso de uma unidade systemd se já uso políticas de reinício?

Normalmente, não. Uma política de reinício é suficiente para uma stack que apenas precisa da rede, o que abrange a maioria das stacks. Adicione uma unidade quando os contentores dependerem de algo que não esteja pronto quando o daemon do Docker arrancar, como um disco externo, um volume encriptado, uma partilha NFS ou uma interface VPN. A unidade permite definir a ordem através de After= e RequiresMountsFor=, algo que uma política de reinício não consegue expressar.

Como paro uma stack permanentemente sem que ela volte no próximo reboot?

Com unless-stopped, docker compose stop é suficiente, porque um contentor parado manualmente não é retomado quando o daemon reinicia. Com always, parar o contentor não é suficiente e ele volta depois de um reboot. Execute docker compose down, que remove os contentores, ou altere primeiro a política com docker update --restart no my-container. Se uma unidade systemd gerir a stack, execute também sudo systemctl disable myapp.service, caso contrário a unidade iniciá-la-á novamente.