Docker Compose: diferença entre down e stop
stop para os containers sem removê-los; down remove containers e a rede, mas preserva volumes nomeados. Use --volumes apenas para apagar os dados.
A resposta curta
docker compose stop para os containers e deixa-os no disco. docker compose down para os containers e depois elimina os containers e a rede que o Compose criou para o projeto. Nenhum dos comandos afeta um volume nomeado. A base de dados só é eliminada quando adiciona -v, como em docker compose down -v, que remove os volumes nomeados declarados na secção volumes do ficheiro Compose.
Essa é toda a diferença, resumida num parágrafo. O restante deste guia demonstra-a com um volume do Postgres que pode observar sobreviver a um down e desaparecer durante um down -v, além de explicar os dois casos em que precisa de --force-recreate.
docker compose stop: os containers permanecem
stop envia SIGTERM para o processo principal de cada container, aguarda e depois envia SIGKILL se o processo ainda estiver ativo. A espera padrão é de 10 segundos, e -t altera esse valor. Nada é eliminado. O container mantém o seu ID, a sua camada gravável, a reserva do seu IP e os seus logs.
docker compose stop
docker compose ps -adocker compose ps, usado isoladamente, mostra apenas os containers em execução. Por isso, depois de stop, apresenta uma tabela vazia, e pode parecer que os containers desapareceram. ps -a inclui os containers parados. É aí que verá Exited (0) junto de cada serviço. Inicie-os novamente com docker compose start, que reutiliza exatamente os mesmos containers.
Como os containers continuam a existir, tudo o que foi escrito neles fora de um volume permanece disponível. Isso inclui um pacote instalado manualmente com docker compose exec e um ficheiro de configuração editado dentro do container. Esta é a razão prática para preferir stop durante a depuração: pode reiniciar no mesmo estado.
docker compose down: contentores e redes são removidos
down para os contentores e depois remove-os, juntamente com a rede predefinida que o Compose criou para o projeto. A documentação do Docker descreve-o como uma operação que para os contentores e remove os contentores, as redes, os volumes e as imagens criados por up, mas as partes relativas a volumes e imagens só ocorrem quando as solicita com -v e --rmi.
docker compose down
docker compose ps -a
docker network lsDepois de down, ps -a não imprime nada relativo ao projeto e a rede <project>_default deixa de existir. O nome do projeto vem do nome do diretório, exceto se definir name: no ficheiro Compose ou passar -p. Todas as alterações feitas na camada gravável de um contentor ficam agora irrecuperáveis. Por isso, trate down como um comando que elimina o contentor e preserva os dados colocados nos volumes.
Se o executar no diretório errado, verá no configuration file provided: not found. O Compose não sabe a que projeto se refere e recusa a operação. Use docker compose -f /srv/myapp/compose.yaml down quando não estiver na pasta do projeto.
O comando docker compose down elimina os meus volumes?
Não. Um volume nomeado declarado na chave de nível superior volumes permanece depois de down e depois do contentor ao qual estava ligado. Este é o receio mais comum em relação ao comando, e a resposta mantém-se no Compose v2.
Configure uma stack que possa usar para testar. Coloque o conteúdo seguinte em compose.yaml, num diretório vazio chamado voltest.
services:
db:
image: postgres:16.4
restart: unless-stopped
environment:
POSTGRES_PASSWORD: example
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:Inicie a stack e escreva uma linha que possa reconhecer mais tarde.
docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "create table marker (note text);"
docker compose exec -T db psql -U postgres -c "insert into marker values ('survived');"Agora elimine o contentor e verifique o volume.
docker compose down
docker volume lsA saída continua a listar voltest_pgdata. O contentor desapareceu, mas os dados permanecem. Inicie novamente a stack e leia a linha.
docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "select * from marker;"É apresentada uma linha que contém survived. O novo contentor é um contentor diferente, com um ID diferente, ligado ao mesmo volume. Para obter uma visão mais ampla, o guia básico do Compose explica a diferença entre volumes nomeados e bind mounts, bem como o local exato onde cada um fica no host.
O que down -v remove, exatamente
-v (forma longa: --volumes) remove os volumes nomeados declarados na secção volumes do ficheiro Compose, além dos volumes anónimos associados aos contentores. Execute-o na mesma stack.
docker compose down -v
docker volume lsvoltest_pgdata já não aparece na lista. Inicie novamente a stack. O entrypoint do Postgres encontra um diretório de dados vazio e inicializa um cluster novo. O log do contentor indica isso claramente.
The files belonging to this database system will be owned by user "postgres".
PostgreSQL init process complete; ready for start up.Ver esse bloco numa stack que está em execução há meses significa que o volume foi removido. A tabela marker desapareceu e a única forma de recuperar os dados é usar uma cópia de segurança.
Alguns tipos de armazenamento nunca são removidos por -v. Um bind mount aponta para um caminho no host. Por isso, o Docker apenas o desmonta e os seus ficheiros permanecem no mesmo local. Um volume marcado como external: true é declarado como pertencente a algo fora deste projeto. O Compose nunca o remove. Um volume nomeado que tenha sido eliminado do ficheiro Compose antes de executar down -v já não está declarado. Por isso, o Compose não sabe que deve removê-lo e deixa-o para trás como órfão durante docker volume prune.
Este último caso causa problemas durante uma refatorização. Remova um serviço e o respetivo volume do ficheiro, execute down -v, e o volume permanece porque o ficheiro já não o referencia. Execute down -v antes de editar o ficheiro, não depois.
Quando você realmente precisa de --force-recreate
docker compose up -d não recria tudo sempre. O Compose armazena no container um hash da configuração resolvida de cada serviço, como um label. Se o hash e o ID da imagem forem iguais, o container permanece inalterado e você obtém Container voltest-db-1 Running em vez de Recreated. Esse é quase sempre o comportamento desejado, porque torna up -d seguro para execução repetida.
Isso também explica por que algumas edições parecem não ter efeito. O Compose calcula o hash da definição de serviço resolvida, não do conteúdo dos arquivos referenciados por essa definição. Um arquivo de configuração montado no container e lido apenas na inicialização não dispara uma recriação quando é editado, porque o caminho do mount não mudou. O serviço continua em execução com os valores lidos no boot.
docker compose up -d --force-recreateIsso para e remove cada container e cria um novo a partir da mesma definição. Use-o depois de editar um arquivo de configuração montado e quando um container tiver entrado em um estado que você não consegue explicar. Os volumes não são alterados, portanto um banco de dados sobrevive a uma recriação forçada. Para obter uma imagem mais recente usando a mesma tag, você também precisa fazer o pull.
docker compose pull
docker compose up -dpull obtém o novo ID da imagem, e up -d identifica então um ID de imagem diferente do container em execução e recria o container por conta própria. Adicionar --force-recreate sem pull cria um novo container a partir da mesma imagem antiga. Por isso, “forcei a recriação e ele ainda está na versão antiga” é uma reclamação tão comum.
docker compose restart não faz nada disso. Ele reinicia os containers existentes e não relê o arquivo Compose, portanto uma variável de ambiente alterada ou um mapeamento de porta alterado não será aplicado. Se você editou o arquivo, use up -d.
O modelo mental a manter
Os containers podem ser substituídos. Um container é um processo com uma camada gravável fina, e o Compose consegue criar outro idêntico a partir do ficheiro em cerca de 1 segundo. Os volumes não podem ser substituídos, porque contêm a única cópia do estado que nenhum ficheiro do seu repositório consegue gerar novamente.
Cada comando do Compose corresponde a essa separação. stop e start mantêm o container. down e up substituem o container e mantêm o volume. down -v é o único comando de rotina que remove o estado, razão pela qual requer uma flag explícita. Antes de o executar num sistema real, confirme que tem uma cópia de segurança que já restaurou pelo menos uma vez.
A mesma lógica aplica-se aos secrets. Uma palavra-passe definida através de POSTGRES_PASSWORD só é lida na primeira inicialização da base de dados. Por isso, alterar a palavra-passe no ficheiro de ambiente e executar up -d dá-lhe password authentication failed for user "postgres". O container é novo e o volume é antigo, e o volume antigo continua a conter a palavra-passe antiga. Como o Compose resolve ficheiros env e secrets explica qual camada prevalece quando a mesma variável é definida duas vezes.
Modos de falha e as mensagens que verá
no configuration file provided: not found significa que o Compose está a ser executado num diretório sem compose.yaml nem docker-compose.yml. Passe -f com o caminho completo.
network voltest_default has active endpoints em down significa que um contentor fora deste projeto está ligado à rede do projeto, normalmente um contentor iniciado manualmente com docker run --network. Remova esse contentor e execute down novamente.
Found orphan containers ([voltest-old-1]) for this project aparece depois de mudar o nome ou eliminar um serviço. O contentor antigo ainda mantém o rótulo do projeto. docker compose down --remove-orphans remove esses contentores e é seguro executá-lo numa stack saudável.
Error response from daemon: remove voltest_pgdata: volume is in use num docker volume rm manual significa que ainda há um contentor a referenciar o volume, incluindo um contentor parado. Execute primeiro docker compose down e remova o volume, ou use simplesmente down -v. Num projeto maior, uma stack Compose com vários serviços mostra quantos volumes um projeto pode acumular.
FAQ
O comando docker compose down elimina a minha base de dados?
Não, se a base de dados estiver num volume com nome ou num bind mount. down remove os contentores e a rede do projeto, mas o volume permanece no disco com os dados intactos. O docker compose up -d seguinte associa um novo contentor ao mesmo volume, e os dados continuam disponíveis. Apenas docker compose down -v remove volumes com nome, e apenas os volumes declarados na secção volumes do ficheiro Compose.
Qual é a diferença entre stop e down para um contentor que quero voltar a usar?
stop mantém o contentor, por isso docker compose start devolve-o ao mesmo contentor, com a mesma camada gravável. Tudo o que instalou ou editou manualmente dentro do contentor continua presente. down elimina o contentor, por isso o up -d seguinte cria um novo a partir da imagem, e essas alterações manuais perdem-se. Enquanto estiver a diagnosticar o problema, use stop.
Como removo tudo o que um projeto Compose criou?
docker compose down -v --rmi all --remove-orphans remove os contentores, a rede do projeto, os volumes com nome declarados no ficheiro, as imagens utilizadas pelos serviços e qualquer contentor que ainda tenha uma etiqueta com o nome do projeto. Não afeta bind mounts nem volumes marcados com external: true. Confirme o que está prestes a perder com docker volume ls antes de executar o comando.
Por que motivo o meu contentor ignora a alteração que fiz num ficheiro de configuração montado?
O Compose decide se deve recriar um contentor comparando um hash da definição de serviço resolvida. Esse hash não inclui o conteúdo de um ficheiro montado. O caminho não mudou, por isso o Compose mantém o contentor em execução com os valores lidos no arranque. Execute docker compose up -d --force-recreate para criar um novo contentor que leia novamente o ficheiro.
Por que motivo o meu novo POSTGRES_PASSWORD não funciona depois de o alterar?
A imagem Postgres só lê POSTGRES_PASSWORD quando inicializa um diretório de dados vazio. O seu volume já contém um cluster inicializado, por isso a variável é ignorada e a palavra-passe antiga continua a ser aplicada. Irá ver password authentication failed for user "postgres". Altere a palavra-passe com ALTER USER dentro da base de dados em execução ou aceite perder os dados e recomece com docker compose down -v.