Docker Compose down vs stop: qual usar?
stop mantém containers e dados; down remove containers e a rede do projeto. Nenhum apaga volumes nomeados, a menos que você use a flag -v.
A resposta curta
docker compose stop interrompe os containers e os mantém no disco. docker compose down os interrompe e depois exclui os containers e a rede que o Compose criou para o projeto. Nenhum dos comandos afeta um volume nomeado. O banco de dados só é excluído quando você adiciona -v, como em docker compose down -v, que remove os volumes nomeados declarados na seção volumes do arquivo Compose.
Essa é toda a diferença em um parágrafo. O restante deste guia comprova isso com um volume do Postgres que você pode observar sobreviver a um down e desaparecer com um down -v, além de explicar os dois casos em que você precisa de --force-recreate.
docker compose stop: os containers permanecem
stop envia SIGTERM ao processo principal de cada container, aguarda e, em seguida, envia SIGKILL se o processo ainda estiver ativo. A espera padrão é de 10 segundos, e -t a altera. Nada é excluído. O container mantém seu ID, sua camada gravável, sua reserva de IP e seus logs.
docker compose stop
docker compose ps -adocker compose ps, usado sozinho, mostra apenas os containers em execução. Por isso, depois de stop, ele exibe uma tabela vazia, e algumas pessoas acham que os containers foram removidos. ps -a inclui os containers parados. É nessa saída que você verá Exited (0) ao lado de cada serviço. Reative-os com docker compose start, que reutiliza exatamente os mesmos containers.
Como os containers ainda existem, tudo que foi gravado neles fora de um volume permanece lá. Isso inclui um pacote instalado manualmente com docker compose exec e um arquivo de configuração editado dentro do container. Esse é o motivo prático para preferir stop durante a depuração: você pode reiniciar no mesmo estado.
docker compose down: contêineres e redes são removidos
down interrompe os contêineres e depois os remove, junto com a rede padrão que o Compose criou para o projeto. A documentação do Docker descreve esse comando como responsável por interromper contêineres e remover contêineres, redes, volumes e imagens criados por up, mas os volumes e as imagens só são removidos quando você solicita isso com -v e --rmi.
docker compose down
docker compose ps -a
docker network lsDepois de executar down, ps -a não exibe nada para o projeto, e a rede <project>_default deixa de existir. O nome do projeto vem do nome do diretório, a menos que você defina name: no arquivo do Compose ou passe -p. Todas as alterações feitas na camada gravável de um contêiner agora são irrecuperáveis. Portanto, trate down como um comando que descarta o contêiner e preserva os dados armazenados nos volumes.
Se você executar o comando no diretório errado, verá no configuration file provided: not found. O Compose não sabe a qual projeto você se refere e, por isso, recusa a operação. Use docker compose -f /srv/myapp/compose.yaml down quando não estiver no diretório do projeto.
docker compose down exclui meus volumes?
Não. Um volume nomeado declarado na chave de nível superior volumes permanece após down e após a remoção do contêiner ao qual estava anexado. Esse é o receio mais comum em relação ao comando, e a resposta permanece a mesma no Compose v2.
Configure uma pilha para testar. Coloque o conteúdo a seguir em compose.yaml, em um 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 pilha e grave uma linha que você possa reconhecer depois.
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 remova o contêiner e verifique o volume.
docker compose down
docker volume lsA saída ainda lista voltest_pgdata. O contêiner foi removido, mas os dados permanecem. Inicie a pilha novamente e leia a linha.
docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "select * from marker;"Você obtém uma linha contendo survived. O novo contêiner é diferente e tem um ID diferente, mas está anexado ao mesmo volume. Para entender o contexto mais amplo, o guia básico do Compose compara volumes nomeados com montagens bind e mostra onde cada um realmente fica no host.
O que down -v remove exatamente
-v (forma longa --volumes) remove os volumes nomeados declarados na seção volumes do arquivo Compose, além dos volumes anônimos anexados aos contêineres. Execute-o na mesma stack.
docker compose down -v
docker volume lsvoltest_pgdata não aparece mais na lista. Inicie a stack novamente. O entrypoint do Postgres encontra um diretório de dados vazio e inicializa um cluster novo. O log do contêiner confirma isso claramente.
The files belonging to this database system will be owned by user "postgres".
PostgreSQL init process complete; ready for start up.Encontrar esse bloco em uma stack que está em execução há meses significa que o volume foi removido. A tabela marker foi perdida, e a única forma de recuperá-la é usar um backup.
Alguns tipos de armazenamento nunca são removidos por -v. Um bind mount é um caminho do host. Portanto, o Docker apenas o desmonta, e os arquivos permanecem no mesmo local. Um volume marcado como external: true é declarado como pertencente a algo externo a este projeto, e o Compose nunca o remove. Um volume nomeado que você excluiu do arquivo Compose antes de executar down -v não está mais declarado. Portanto, o Compose não sabe que deve removê-lo, e ele permanece como órfão por docker volume prune.
Esse último caso costuma ocorrer durante uma refatoração. Remova um serviço e seu volume do arquivo, execute down -v, e o volume permanecerá porque o arquivo não faz mais referência a ele. Execute down -v antes de editar o arquivo, não depois.
Quando você realmente precisa de --force-recreate
docker compose up -d não recria tudo sempre. O Compose armazena um hash da configuração resolvida de cada serviço no container, como um label. Se o hash e o ID da imagem forem iguais, o container não é alterado 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.
Essa também é a razão pela qual algumas edições parecem não fazer nada. O Compose calcula o hash da definição resolvida do serviço, não do conteúdo dos arquivos aos quais essa definição aponta. 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 de montagem não mudou. O serviço continua em execução com os valores lidos na inicialização.
docker compose up -d --force-recreateEsse comando 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 divergido para 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 executar o pull.
docker compose pull
docker compose up -dpull obtém o novo ID da imagem, e up -d detecta então um ID de imagem diferente do usado pelo container em execução e o recria automaticamente. Adicionar --force-recreate sem pull fornece 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 do 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 ser mantido
Os containers são substituíveis. Um container é um processo mais uma camada gravável fina, e o Compose pode criar outro idêntico a partir do arquivo em cerca de um segundo. Os volumes não são substituíveis, pois contêm a única cópia do estado que nenhum arquivo do seu repositório pode regenerar.
Cada comando do Compose corresponde a essa separação. stop e start preservam o container. down e up substituem o container e preservam o volume. down -v é o único comando de rotina que remove o estado, por isso exige uma flag explícita. Antes de executá-lo em qualquer ambiente real, confirme que você tem um backup que já restaurou pelo menos uma vez.
A mesma lógica se aplica aos secrets. Uma senha definida por meio de POSTGRES_PASSWORD é lida apenas na primeira inicialização do banco de dados, portanto alterá-la no arquivo de ambiente e executar up -d resulta em password authentication failed for user "postgres". O container é novo e o volume é antigo, e o volume antigo ainda contém a senha antiga. Como o Compose resolve arquivos de ambiente e secrets explica qual camada prevalece quando a mesma variável é definida duas vezes.
Modos de falha e as mensagens que você verá
no configuration file provided: not found significa que o Compose está sendo executado em um diretório sem compose.yaml e sem docker-compose.yml. Passe -f com o caminho completo.
network voltest_default has active endpoints em down significa que um container fora deste projeto está conectado à rede do projeto, geralmente um container iniciado manualmente com docker run --network. Remova esse container e execute down novamente.
Found orphan containers ([voltest-old-1]) for this project aparece depois que você renomeia ou exclui um serviço. O container antigo ainda mantém o label do projeto. docker compose down --remove-orphans remove esses containers, e é seguro executá-lo em uma stack íntegra.
Error response from daemon: remove voltest_pgdata: volume is in use em um docker volume rm manual significa que algum container ainda referencia o volume, inclusive um container parado. Execute docker compose down primeiro e remova o volume, ou simplesmente use down -v. Em um projeto maior, uma stack Compose com vários serviços mostra quantos volumes um único projeto pode acumular.
FAQ
O comando docker compose down exclui meu banco de dados?
Não, se o banco de dados estiver em um volume nomeado ou em uma montagem de bind. down remove os contêineres e a rede do projeto, mas o volume permanece no disco com os dados intactos. O próximo docker compose up -d conecta um novo contêiner ao mesmo volume, e os dados continuam disponíveis. Somente docker compose down -v remove volumes nomeados, e apenas os declarados na seção volumes do arquivo Compose.
Qual é a diferença entre stop e down para um contêiner que quero reutilizar?
stop mantém o contêiner, portanto docker compose start retorna ao mesmo contêiner com a mesma camada gravável. Tudo o que você instalou ou editou manualmente dentro do contêiner continua presente. down exclui o contêiner, portanto o próximo up -d cria um novo a partir da imagem, e essas alterações manuais são perdidas. Enquanto estiver depurando, use stop.
Como removo tudo o que um projeto Compose criou?
docker compose down -v --rmi all --remove-orphans remove os contêineres, a rede do projeto, os volumes nomeados declarados no arquivo, as imagens usadas pelos serviços e qualquer contêiner que ainda tenha um rótulo com o nome do projeto. Ele não altera montagens de bind nem volumes marcados com external: true. Verifique o que será perdido com docker volume ls antes de executá-lo.
Por que meu contêiner ignora a alteração que fiz em um arquivo de configuração montado?
O Compose decide se deve recriar um contêiner comparando um hash da definição de serviço resolvida, e esse hash não inclui o conteúdo de um arquivo montado. O caminho não foi alterado, portanto o Compose mantém o contêiner em execução com os valores lidos na inicialização. Execute docker compose up -d --force-recreate para criar um novo contêiner que leia o arquivo novamente.
Por que meu novo POSTGRES_PASSWORD não funciona depois que o alterei?
A imagem do Postgres lê POSTGRES_PASSWORD somente quando inicializa um diretório de dados vazio. Seu volume já contém um cluster inicializado, portanto a variável é ignorada e a senha antiga continua válida. Você verá password authentication failed for user "postgres". Altere a senha com ALTER USER dentro do banco de dados em execução ou aceite perder os dados e comece novamente com docker compose down -v.