Olá! Seja bem-vindo de volta.
Na lição anterior, você aprendeu a usar o docker run para iniciar contêineres nos modos detached e interactive, além de usar o docker ps para visualizar os que estão em execução. Executar um contêiner é apenas o começo da história. Assim como qualquer aplicação ou serviço, os contêineres têm um ciclo de vida que precisa ser gerenciado: eles são iniciados, parados, reiniciados e, eventualmente, removidos.
O objetivo desta lição é capacitá-lo a gerenciar o ciclo de vida de um contêiner usando os comandos docker start, stop, restart e remove. Dominar esses comandos é fundamental para a operação diária, desde o desenvolvimento local até a manutenção de aplicações em produção.
Visualizando o Ciclo de Vida do Contêiner
Antes de mergulharmos nos comandos, é útil ter um modelo mental dos diferentes estados pelos quais um contêiner pode passar. Dado seu interesse em entender os fundamentos, pensar nisso como uma máquina de estados pode ser muito esclarecedor.

Os estados mais importantes para nossa lição de hoje são:
- Running: O contêiner está ativo e seu processo principal está em execução. Você chega aqui com
docker runoudocker start. - Exited (Stopped): O processo principal do contêiner foi finalizado. O contêiner ainda existe no sistema (seu sistema de arquivos e configuração são preservados), mas não está consumindo CPU. Você chega aqui com
docker stopou quando o processo principal termina por conta própria. - (Removed): O estado final, onde o contêiner é permanentemente excluído do sistema usando
docker rm.
Parando e Iniciando Contêineres
Na lição anterior, você iniciou contêineres com docker run. Agora, vamos aprender a gerenciá-los sem precisar recriá-los toda vez.
Vamos começar um contêiner Nginx em modo detached e dar a ele um nome para facilitar a referência:
docker run -d --name webserver nginx
Você pode verificar que ele está rodando com docker ps.
docker stop: A Parada Controlada
Para parar um contêiner em execução, usamos o comando docker stop.
docker stop webserver
Como funciona?
Isso é mais sofisticado do que simplesmente "matar" o processo. Por padrão, docker stop faz o seguinte:
- Envia um sinal
SIGTERMao processo principal dentro do contêiner. Este é um sinal de término "gentil", que permite que a aplicação realize um desligamento controlado (por exemplo, finalizar requisições em andamento, salvar dados em disco, fechar conexões de banco de dados). - Aguarda um período de carência (o padrão é 10 segundos).
- Se o processo não terminar nesse tempo, o Docker envia um sinal
SIGKILL, que força o encerramento imediato do processo pelo sistema operacional.
Essa abordagem de desligamento controlado é crucial em ambientes de produção para evitar corrupção de dados e garantir a integridade do sistema, um conceito com o qual você, como desenvolvedor de back-end, já está familiarizado.
Após executar docker stop, se você rodar docker ps, o contêiner webserver não aparecerá mais. No entanto, ele não foi excluído. Para vê-lo, use a flag -a (all):
docker ps -a
Você verá o contêiner webserver com o status Exited.
docker start: Trazendo de Volta à Vida
Um contêiner parado pode ser reiniciado a qualquer momento com docker start.
docker start webserver
Este comando pega o contêiner existente, com seu ID, nome e sistema de arquivos (incluindo quaisquer alterações que tenham sido feitas) e inicia seu processo principal novamente. Se você executar docker ps agora, verá o webserver rodando novamente.
O vídeo a seguir demonstra rapidamente esses comandos em ação.
Docker Crash Course for Absolute Beginners [NEW]
Para visualizar o fluxo que acabamos de discutir, este trecho do 'Docker Crash Course for Absolute Beginners' do canal TechWorld with Nana demonstra como parar um contêiner, listar todos os contêineres (incluindo os parados) e iniciar um contêiner parado.
Assista do timestamp 00:43:52 a 00:45:15. Preste atenção em como o comando docker ps -a é usado para encontrar o ID ou nome de um contêiner parado para que ele possa ser iniciado novamente.
Reiniciando e Removendo Contêineres
docker restart: Uma Conveniência Útil
Se você precisa simplesmente reiniciar um contêiner que já está rodando (por exemplo, para que ele releia um arquivo de configuração que foi alterado), você pode usar o comando docker restart.
docker restart webserver
Internamente, docker restart executa um docker stop seguido por um docker start. Ele respeita o mesmo tempo de espera para o desligamento controlado antes de forçar a parada e reiniciar o contêiner.
docker rm: A Limpeza Final
Contêineres parados ainda ocupam espaço em disco, pois seus sistemas de arquivos são mantidos. Quando você tem certeza de que não precisa mais de um contêiner, pode removê-lo permanentemente com docker rm.
Primeiro, pare o contêiner:
docker stop webserver
Agora, remova-o:
docker rm webserver
Se você tentar remover um contêiner que ainda está em execução, o Docker retornará um erro. Isso é uma medida de segurança para evitar a remoção acidental de serviços ativos. Para contornar isso, você pode usar a flag -f (--force), que primeiro envia um sinal SIGKILL e depois remove o contêiner.
# Crie um novo contêiner para testar
docker run -d --name temp_web nginx
# Tente remover sem parar (vai falhar)
docker rm temp_web
# Force a remoção
docker rm -f temp_web
Para aprofundar seu conhecimento sobre o que acontece internamente durante cada um desses estágios, o recurso a seguir é uma excelente leitura.
The Complete Docker Container Lifecycle: States, ...
Para entender o que realmente acontece 'sob o capô' quando você gerencia o ciclo de vida de um contêiner, este artigo é excelente. Ele detalha os processos internos para cada estado e comando, o que se alinha perfeitamente com seu interesse em 'como as coisas funcionam'.
Leia as seções intituladas 'START STAGE: docker start', 'STOPPED STATE', 'RESTARTED STATE', e 'REMOVAL STAGE'. Preste atenção especial na descrição do que acontece internamente, como a manipulação de namespaces e o envio de sinais (SIGTERM/SIGKILL).
Teste seu entendimento!
Você está executando dois contêineres: api_v1 e db_v1. Você acabou de implantar uma nova versão da sua API, api_v2, que se conecta ao mesmo banco de dados. Você quer desativar a versão antiga da API para liberar recursos, mas manter o banco de dados em execução. Qual é a sequência correta de comandos para fazer isso de forma limpa?
docker stop api_v1docker rm api_v1
Você precisaria de ambos os comandos? A ordem importa?
Show answer
Sim, você precisaria de ambos os comandos, e a ordem é crucial.
docker stop api_v1: Primeiro, você para o contêiner da API antiga de forma controlada. Isso garante que ele encerre suas operações corretamente antes de ser desligado.docker rm api_v1: Uma vez que o contêiner está no estadoExited, você o remove para liberar o nome e os recursos do disco que ele estava ocupando.
Tentar executar docker rm api_v1 enquanto o contêiner está rodando resultaria em um erro (a menos que a flag -f fosse usada, o que não é considerado uma prática "limpa" para desativação planejada). O contêiner db_v1 não é tocado e permanece em execução.
Conclusão
Nesta lição, você aprendeu a gerenciar o ciclo de vida básico de um contêiner. Agora você está equipado para ir além de apenas criar contêineres e pode controlá-los de forma eficaz.
Principais pontos a reter:
- Ciclo de Vida: Contêineres transitam entre estados como
running,exited, e são eventualmenteremoved. docker stop <nome>: Para um contêiner de forma controlada, enviandoSIGTERMe depoisSIGKILL.docker start <nome>: Inicia um contêiner que foi previamente parado, reutilizando seu estado.docker restart <nome>: Um atalho conveniente parastopseguido destart.docker rm <nome>: Remove permanentemente um contêiner parado. Userm -fpara forçar a remoção de um contêiner em execução.docker ps -a: Seu comando essencial para ver todos os contêineres, incluindo os que estão parados.
Agora que você pode criar e gerenciar o ciclo de vida básico de um contêiner, o próximo passo natural é aprender a configurar seu comportamento. Na próxima lição, focaremos em como passar informações para dentro de um contêiner no momento da execução, começando com o método fundamental de usar variáveis de ambiente (--env), algo que você usará constantemente para configurar suas aplicações .NET.