Conteúdo
Tutorial de ciclo de vida de contêineres Docker: criar, iniciar, parar e remover
Um contêiner passa por vários estados desde a criação até a remoção. Ao entendê-los, você sabe por que às vezes um contêiner "roda por um instante e para", por que um contêiner parado ainda ocupa seu nome e por que docker stop às vezes espera 10 segundos.
Estados do contêiner
| Estado | Significado | STATUS em docker ps -a |
|---|---|---|
created | Criado, mas nunca iniciado | Created |
running | O processo principal está em execução | Up 3 minutes |
paused | Todos os processos estão congelados | Up 3 minutes (Paused) |
exited | O processo principal terminou, mas o contêiner continua existindo | Exited (0) 10 seconds ago |
restarting | Reiniciando de acordo com a política de reinicialização | Restarting (1) 2 seconds ago |
O número entre parênteses após Exited é o código de saída do processo principal. 0 significa que ele terminou normalmente; explicaremos em detalhes mais adiante.
Quando um contêiner para
A vida do contêiner = a vida do processo principal (PID 1). Quando o processo principal termina, o contêiner para.
Isso explica uma dúvida muito comum:
$ docker run ubuntu:26.04
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
66e6f85c66e0 ubuntu:26.04 "/bin/bash" Less than a second ago Exited (0) Less than a second ago dreamy_solomon
docker run ubuntu:26.04 terminou sem exibir nada, e ele também não aparece em docker ps. Só é possível vê-lo com docker ps -a: seu processo principal é /bin/bash, mas, como você não adicionou -it, o bash não tem nenhuma entrada para ler e termina logo após iniciar. Por isso, o contêiner para (Exited (0)).
Adicione -it para fornecer a ele um terminal interativo; assim, o bash continua aguardando sua entrada:
docker run -it ubuntu:26.04
Em imagens de serviços como nginx e PostgreSQL, o processo principal permanece em execução em primeiro plano, então o contêiner continua funcionando.
Criar e iniciar
Na verdade, docker run combina docker create (criar) com docker start (iniciar). Você também pode executá-los separadamente:
$ docker create --name web nginx:1.30
ad99713ea5acddf70d854365e882fd0a3b6d4508d50da25993b94c9878f1c3bc
$ docker ps -a --filter name=web
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad99713ea5ac nginx:1.30 "/docker-entrypoint.…" Less than a second ago Created web
$ docker start web
web
$ docker ps --filter name=web
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad99713ea5ac nginx:1.30 "/docker-entrypoint.…" Less than a second ago Up Less than a second 80/tcp web
Após a criação, o estado é Created; depois de iniciar, passa a ser Up. --filter name=web lista somente os contêineres cujo nome contém web.
Os nomes não podem se repetir
Cada vez que você executa docker run, um contêiner novo é criado. Se um nome já estiver em uso, ocorrerá um erro mesmo que o contêiner correspondente esteja parado:
$ docker run -d --name web nginx:1.30
docker: Error response from daemon: Conflict. The container name "/web" is already in use by container "ad99713ea5acddf70d854365e882fd0a3b6d4508d50da25993b94c9878f1c3bc". You have to remove (or rename) that container to be able to reuse that name.
Run 'docker run --help' for more information
Para iniciar novamente o contêiner anterior, use docker start web. Para recriá-lo com novas configurações, primeiro execute docker rm -f web e depois docker run.
Parar: diferença entre stop e kill
| Comando | Comportamento |
|---|---|
docker stop | Envia SIGTERM primeiro para que o programa possa encerrar corretamente; se não terminar em 10 segundos, envia SIGKILL para encerrá-lo à força |
docker kill | Envia SIGKILL diretamente e encerra imediatamente |
stop dá ao programa a chance de "encerrar corretamente", por exemplo, para que um banco de dados grave os dados no disco ou um servidor web termine de processar as requisições em andamento. Use sempre stop no dia a dia e recorra a kill somente quando o programa travar.
$ docker start web
web
$ docker kill web
web
$ docker ps -a --filter name=web
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad99713ea5ac nginx:1.30 "/docker-entrypoint.…" 14 seconds ago Exited (137) Less than a second ago web
O código de saída do contêiner encerrado com kill é 137 (128 + 9; 9 é o número de SIGKILL).
Por que às vezes docker stop espera 10 segundos?
Abaixo, compare na prática quanto tempo três contêineres levam para parar:
$ time docker stop web
web
real 0m 0.10s
user 0m 0.01s
sys 0m 0.00s
$ docker run -d --name slow alpine:3.23 sh -c "sleep 300"
Unable to find image 'alpine:3.23' locally
3.23: Pulling from library/alpine
d0c1d894c237: Pull complete
Digest: sha256:85fe1e81d6758c208f3e1eed4338a1997e19d4be002d4dd32d3100c9a8c010a0
Status: Downloaded newer image for alpine:3.23
170d08a64bb8ec1519d183f8c20508d669358eea4d5a978fa4f4675ffcec41ab
$ time docker stop slow
slow
real 0m 10.17s
user 0m 0.00s
sys 0m 0.01s
$ docker run -d --name slow2 --init alpine:3.23 sh -c "sleep 300"
d1854be4790b5fc9375004e05708d27a27d56c2c540a8159424351985db20ef9
$ time docker stop slow2
slow2
real 0m 0.13s
user 0m 0.00s
sys 0m 0.01s
| Contêiner | Tempo para parar | Motivo |
|---|---|---|
| nginx | 0.10 segundo | nginx recebe SIGTERM e encerra normalmente na hora |
sh -c "sleep 300" | 10.17 segundos | O processo principal é sh, que ignora SIGTERM quando executado como PID 1. O Docker espera os 10 segundos completos e então o encerra à força com SIGKILL |
O mesmo acima, com --init | 0.13 segundo | --init usa um pequeno processo init como PID 1, que encaminha o sinal ao processo filho |
No Linux, há uma regra especial para o PID 1: se o PID 1 não tratar SIGTERM, o sinal será ignorado. Portanto, se uma imagem que você criou leva 10 segundos para parar a cada docker stop, normalmente é porque o processo principal está sendo executado como PID 1 e o programa não trata SIGTERM. Por exemplo, um programa Node.js cujo processo principal é iniciado diretamente com node server.js também leva 10 segundos nos testes. Veja a comparação prática em Referência completa das instruções do Dockerfile. Para resolver, trate SIGTERM no programa ou adicione --init.
Código de saída
$ docker run --name exit3 alpine:3.23 sh -c "exit 3"
$ docker ps -a --filter name=exit3
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84996cca5ec5 alpine:3.23 "sh -c 'exit 3'" 1 second ago Exited (3) Less than a second ago exit3
$ docker inspect --format '{{.State.ExitCode}}' exit3
3
Exited (...) mostra o código com que o processo principal terminou. Códigos comuns:
| Código | Causa comum |
|---|---|
0 | Encerramento normal |
1 e outros números | Erro informado pelo próprio programa; consulte docker logs |
137 | Encerrado por SIGKILL: docker kill, docker stop que demorou demais ou término pelo sistema por falta de memória (OOM) |
143 | Encerrado normalmente após receber SIGTERM (128 + 15) |
Pausar e retomar
$ docker start web
web
$ docker pause web
web
$ docker ps --filter name=web
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad99713ea5ac nginx:1.30 "/docker-entrypoint.…" 15 seconds ago Up Less than a second (Paused) 80/tcp web
$ docker unpause web
web
pause congela todos os processos dentro do contêiner (sem encerrá-los), e o estado exibido é (Paused). É pouco usado e serve para liberar CPU temporariamente, mantendo o estado na memória.
Remover contêineres
$ docker rm web
Error response from daemon: cannot remove container "web": container is running: stop the container before removing or force remove
$ docker rm -f web
web
Não é possível remover diretamente um contêiner em execução: primeiro use stop ou use -f para removê-lo à força (equivale a kill e depois rm).
Remover de uma vez todos os contêineres parados
Depois de praticar por um tempo, muitos contêineres parados se acumulam em docker ps -a:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
75ee00dc4081 nginx:1.30 "/docker-entrypoint.…" 1 second ago Up Less than a second 80/tcp web
5dfb843c0b40 alpine:3.23 "sh -c 'echo startin…" 26 seconds ago Exited (1) 24 seconds ago flaky
84996cca5ec5 alpine:3.23 "sh -c 'exit 3'" 27 seconds ago Exited (3) 26 seconds ago exit3
d1854be4790b alpine:3.23 "sh -c 'sleep 300'" 29 seconds ago Exited (143) 28 seconds ago slow2
170d08a64bb8 alpine:3.23 "sh -c 'sleep 300'" 39 seconds ago Exited (137) 29 seconds ago slow
66e6f85c66e0 ubuntu:26.04 "/bin/bash" 43 seconds ago Exited (0) 42 seconds ago dreamy_solomon
$ docker container prune -f
Deleted Containers:
5dfb843c0b400146827fe138890ee4d62a24104cad5531aff4100fc471b0727f
84996cca5ec5bfe7ca51c6365b60ef89e49055cf06a3f0dd3a49f9e50e08d6f4
d1854be4790b5fc9375004e05708d27a27d56c2c540a8159424351985db20ef9
170d08a64bb8ec1519d183f8c20508d669358eea4d5a978fa4f4675ffcec41ab
66e6f85c66e0f2b586c5919a900a0e16d6f0fc49535d35fa7d30f77747f1ce0e
Total reclaimed space: 24.58kB
container prune remove apenas contêineres parados; o web em execução não é afetado. Observe também os códigos de saída acima: slow foi encerrado à força e terminou com 137, enquanto slow2, que recebeu --init, recebeu SIGTERM normalmente e terminou com 143.
Para remover automaticamente um contêiner temporário ao terminar, adicione --rm ao executá-lo:
docker run --rm alpine:3.23 echo "Descartar depois de usar"
Política de reinicialização: --restart
Quando o servidor reinicia ou o programa trava, você quer que o contêiner reinicie automaticamente? Configure com --restart:
| Valor | Comportamento |
|---|---|
no | Valor padrão; não reinicia automaticamente |
on-failure[:número] | Reinicia somente se o código de saída for diferente de 0; é possível limitar o número de tentativas |
always | Sempre reinicia; mesmo após um stop manual, o Docker o inicia novamente quando o próprio Docker reinicia |
unless-stopped | Parecido com always, mas não reinicia automaticamente se tiver sido parado manualmente |
Veja o on-failure na prática
O contêiner abaixo imprime starting a cada inicialização e termina com o código 1, simulando um programa que trava repetidamente:
$ docker run -d --name flaky --restart on-failure:3 alpine:3.23 sh -c "echo starting; exit 1"
5dfb843c0b400146827fe138890ee4d62a24104cad5531aff4100fc471b0727f
$ docker ps -a --filter name=flaky
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5dfb843c0b40 alpine:3.23 "sh -c 'echo startin…" 25 seconds ago Exited (1) 23 seconds ago flaky
$ docker inspect --format '{{.RestartCount}} {{.State.Status}} {{.State.ExitCode}}' flaky
3 exited 1
$ docker logs flaky
starting
starting
starting
starting
Há 4 ocorrências de starting no log: a inicialização inicial mais 3 reinicializações (RestartCount é 3). Ao atingir o limite, ele para em Exited (1). Entre cada reinicialização, o Docker aumenta gradualmente o tempo de espera para evitar que reinicializações contínuas sobrecarreguem o host.
Alterar a política de reinicialização de um contêiner existente
Para serviços de longa duração, geralmente é recomendável usar unless-stopped. Você também pode alterar a política de um contêiner que já está em execução:
$ docker run -d --name web --restart unless-stopped nginx:1.30
75ee00dc4081f4c2849562fbd89edfdd9386839a161ea9d66956eaa41257d4cf
$ docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' web
unless-stopped
$ docker update --restart always web
web
$ docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' web
always
No Linux, para iniciar os contêineres junto com o sistema, o próprio Docker também precisa iniciar automaticamente:
sudo systemctl enable docker. No Docker Desktop, ative "Start Docker Desktop when you sign in" nas configurações.
Resumo dos comandos
| Comando | Função |
|---|---|
docker run | Criar e iniciar um novo contêiner |
docker create | Apenas criar |
docker start / stop / restart | Iniciar / parar / reiniciar um contêiner existente |
docker kill | Encerrar à força (SIGKILL) |
docker pause / unpause | Pausar / retomar |
docker rm [-f] | Excluir um contêiner |
docker container prune | Excluir todos os contêineres parados |
docker ps [-a] | Listar contêineres (-a inclui os parados) |
docker update --restart | Alterar a política de reinicialização |
A próxima seção reúne os parâmetros mais usados de docker run.
Resumo
- Estados do contêiner: created, running, paused, exited, restarting.
- O contêiner para quando o processo principal termina;
docker stopenvia SIGTERM primeiro e, após 10 segundos, envia SIGKILL. - Se o processo principal for o PID 1 e não tratar SIGTERM, o stop aguardará os 10 segundos completos. Você pode resolver isso com
--init. - Adicione
--restart unless-stoppedaos serviços de longa duração.
Exercícios
Exercício 1: Inicie um contêiner com docker run -d --name t1 alpine:3.23 sh -c "exit 3". Qual será o estado e o código de saída?
Resposta
docker ps -a mostra Exited (3). Você também pode usar docker inspect -f "{{.State.ExitCode}}" t1 para obter o código de saída 3.
Exercício 2: Inicie docker run -d --name t2 alpine:3.23 sleep 300 e compare o tempo necessário para parar com time docker stop t2 (lembre-se de recriá-lo antes) e com a versão que inclui --init.
Dica
Sem --init, sleep é o PID 1 e ignora SIGTERM, então só será encerrado à força após cerca de 10 segundos. Com --init, o processo init encaminha o sinal para sleep, que para quase imediatamente.
Perguntas frequentes
O que significa Exited (137)?
137 = 128 + 9: significa que o contêiner foi encerrado à força com SIGKILL. Isso pode ocorrer com docker kill, quando docker stop demora demais ou quando o sistema o encerra por falta de memória.
O contêiner inicia automaticamente depois que o servidor reinicia?
É preciso configurar uma política de reinicialização (por exemplo, --restart unless-stopped), e o próprio Docker também precisa iniciar automaticamente com o sistema (no Linux, execute sudo systemctl enable docker).
Qual é a diferença entre pausar (pause) e parar (stop)?
pause congela todos os processos dentro do contêiner e mantém o conteúdo da memória; ao retomar, eles continuam do ponto em que estavam. stop encerra os processos e o estado que estava na memória é perdido.
Atualizado 14 de outubro de 2026