Pular para o conteúdo
Cursos

DevClub

LógicaFront-endBack-endMobile

IA Club

IA na prática
Estudar programaçãoEstudar IA
LiçãoIniciantecódigo testado

Imagem e contêiner Docker: diferença, ciclo e comandos

Entenda a diferença entre imagem e contêiner, acompanhe o ciclo de vida real e resolva o conflito de nome que impede um novo docker run.

Rodolfo Mori5 min de leitura

Uma imagem Docker é o pacote imutável com arquivos, configuração e runtime; um contêiner é um processo isolado iniciado a partir desse pacote. Nesta lição você vai baixar uma imagem, criar um contêiner, observar suas mudanças e resolver um conflito de nome reproduzido no Docker 29.5.3.

Antes de continuar, confirme a instalação com a lição instalar Docker. Aqui a gente parte do ponto em que docker version já mostra cliente e servidor.

O roteiro guardado e a apresentação acontecendo

Imagine uma peça de teatro. O roteiro, o cenário planejado e a lista de objetos formam um pacote que pode ser usado em várias apresentações. Esse pacote é a imagem. Cada apresentação com atores no palco é um contêiner: começa, executa e termina independentemente das outras.

O mapeamento ajuda a separar molde de execução, mas tem limite. Tecnicamente a imagem não guarda só instruções; ela contém um sistema de arquivos em camadas e metadados como comando padrão. O contêiner não é uma cópia de computador: é um processo isolado que enxerga as camadas da imagem e recebe uma camada gravável própria.

Por isso uma imagem pode originar cem contêineres sem virar cem imagens. E por isso editar um arquivo dentro de um contêiner não altera o pacote original nem os outros contêineres.

Baixar não é executar

docker pull busca a imagem no registro e a armazena localmente. Ele não cria um processo:

bash
docker pull node:24-alpine
24-alpine: Pulling from library/node Digest: sha256:d32cdf619f63fe0471182d08996dd516c6275bb5fd31ae06e55a570bd9e1ad43 Status: Image is up to date for node:24-alpine docker.io/library/node:24-alpine

Leia node:24-alpine em duas partes. node é o repositório; 24-alpine é a tag. A tag é um nome móvel. O digest sha256:... identifica o conteúdo obtido naquele teste com muito mais precisão.

Inspecione dois metadados do pacote:

bash
docker image inspect node:24-alpine --format 'ID curto: {{printf "%.19s" .Id}} | arquitetura: {{.Architecture}}'
ID curto: sha256:d32cdf619f63 | arquitetura: arm64

Nesta máquina o Docker escolheu a variante ARM64. Num computador Intel, a mesma tag normalmente baixa a variante AMD64. Um manifesto multi-plataforma permite usar o mesmo nome, mas o binário de cada arquitetura continua diferente.

Camadas são partes reutilizáveis da imagem

Imagens são formadas por camadas somente leitura. Cada mudança feita durante o build acrescenta outra camada; imagens podem reutilizar partes iguais. Veja as quatro entradas superiores de node:24-alpine:

bash
docker image history node:24-alpine --format '{{.CreatedBy}} | {{.Size}}' | head -4
CMD ["node"] | 0B ENTRYPOINT ["docker-entrypoint.sh"] | 0B COPY docker-entrypoint.sh /usr/local/bin/ # … | 20.5kB RUN /bin/sh -c apk add --no-cache --virtual … | 5.48MB

history não reconstrói toda a receita original, mas mostra a ordem e o custo das camadas. Essa ordem vai importar quando a gente escrever um Dockerfile para Node.

docker run cria e inicia um contêiner

Agora há execução. Tudo depois do nome da imagem é o comando dentro do contêiner:

bash
docker run --rm node:24-alpine node -e "console.log('Node do pacote:', process.version)"
Node do pacote: v24.19.0

docker run reúne duas ações: docker create e docker start. --rm pede a remoção automática quando o processo termina. Sem --rm, o contêiner parado continua no inventário.

Para observar um contêiner em execução, inicie um processo que mantém a fila da cantina aberta:

bash
docker run -d --name dc-aula-processo node:24-alpine node -e "console.log('fila aberta'); setInterval(()=>{}, 1000)"
4b48be4ee02c6d21ee84a65b4bc3525a7170f552a0bd29234e0f6a6207df8e06

-d significa detached, ou segundo plano. O texto devolvido é o ID do novo contêiner. --name adiciona um identificador humano sem substituir esse ID.

Confira o estado com colunas escolhidas por você:

bash
docker ps --filter name=dc-aula-processo --format 'Nome={{.Names}} | Imagem={{.Image}} | Estado={{.State}}'
Nome=dc-aula-processo | Imagem=node:24-alpine | Estado=running

docker ps mostra apenas os que estão rodando. O filtro evita confundir a aula com outros projetos da máquina.

Logs e exec observam coisas diferentes

docker logs lê o que o processo principal escreveu em saída padrão e saída de erro:

bash
docker logs dc-aula-processo
fila aberta

docker exec inicia outro processo dentro do contêiner que já está rodando:

bash
docker exec dc-aula-processo node -e "console.log('processo extra:', process.pid)"
processo extra: 14

O PID diferente comprova que exec não entra magicamente no processo principal; ele cria um processo adicional com o mesmo sistema de arquivos e a mesma rede. Use logs primeiro para diagnosticar. Use exec quando você precisar fazer uma inspeção que os logs não respondem.

A camada gravável pertence ao contêiner

Crie um segundo contêiner que grava um recibo e permanece ativo:

bash
docker run -d --name dc-aula-camada node:24-alpine node -e "require('node:fs').writeFileSync('/tmp/recibo.txt','pedido 42'); setInterval(()=>{},1000)"
docker diff dc-aula-camada
C /tmp A /tmp/recibo.txt

A indica arquivo adicionado e C, diretório alterado. Essas mudanças estão na camada gravável de dc-aula-camada, não em node:24-alpine. Remover o contêiner remove essa camada. Dados que precisam sobreviver pertencem a um volume Docker, assunto da quarta lição.

Parar não significa remover

Pare o processo principal e procure também entre os contêineres encerrados:

bash
docker stop dc-aula-processo
docker ps -a --filter name=dc-aula-processo --format 'Nome={{.Names}} | Estado={{.State}} | Status={{.Status}}'
dc-aula-processo Nome=dc-aula-processo | Estado=exited | Status=Exited (137) Less than a second ago

O tempo no seu terminal será outro. A regra observável é Estado=exited: o processo acabou, mas o objeto contêiner ainda existe com nome, configuração e camada gravável.

Erro real: o nome continua ocupado

Tente criar outro contêiner com o mesmo nome antes de remover o anterior:

bash
docker run --name dc-aula-processo node:24-alpine node --version
docker: Error response from daemon: Conflict. The container name "/dc-aula-processo" is already in use by container "4b48be4ee02c6d21ee84a65b4bc3525a7170f552a0bd29234e0f6a6207df8e06". You have to remove (or rename) that container to be able to reuse that name.

Run ‘docker run –help’ for more information

O termo é name conflict. Em palavras simples, a etiqueta continua colada ao contêiner parado. docker stop não libera nome; docker rm libera:

bash
docker rm dc-aula-processo
docker rm -f dc-aula-camada
dc-aula-processo dc-aula-camada

-f encerra e remove, por isso exige atenção. Em scripts descartáveis, prefira --rm no docker run. Em serviços que você pretende reiniciar, mantenha o contêiner e use docker start.

Missão: duas execuções, uma imagem

Inicie dois contêineres de node:24-alpine com nomes turno-manha e turno-tarde. Em cada um, imprima um texto diferente e mantenha o processo ativo. O critério de sucesso tem três partes: docker ps mostra dois nomes e a mesma imagem; docker logs mostra a mensagem correta de cada turno; remover um não encerra o outro.

Finalize removendo apenas os dois contêineres da missão. A imagem deve continuar visível em docker image ls node. Quando você consegue prever qual objeto cada comando afeta, imagem e contêiner deixam de parecer dois nomes para a mesma coisa. O próximo passo é transformar código seu em imagem, seguindo a sequência da trilha Docker.

  • docker
  • imagem docker
  • container
  • docker run
  • docker ps
  • terminal

Perguntas frequentes

Uma imagem Docker ocupa espaço toda vez que crio um contêiner?
A parte somente leitura da imagem é compartilhada. Cada contêiner ganha uma camada gravável própria para suas mudanças, por isso vários contêineres da mesma imagem não duplicam todas as camadas do pacote.
Parar um contêiner apaga os arquivos que criei nele?
Não imediatamente. Um contêiner parado ainda conserva sua camada gravável. Os arquivos desaparecem quando esse contêiner é removido, a menos que estejam num volume ou bind mount.
Posso alterar uma imagem Docker pronta?
Imagens são imutáveis. Você pode criar outra imagem acrescentando camadas, normalmente por meio de um Dockerfile, mas não edita a imagem existente no lugar.
Qual a diferença entre docker run e docker start?
docker run cria um contêiner novo a partir de uma imagem e então o inicia. docker start reinicia um contêiner que já existe, preservando sua configuração e camada gravável.

Dúvidas e comentários

Travou em algum passo? Pergunte aqui — a equipe e outros alunos respondem.

Todo o código deste artigo foi executado em Docker Engine 29.5.3, Docker Compose 5.1.4 e Node 24.19.0 (node:24-alpine) no macOS ARM64, e as saídas exibidas são as reais — como produzimos este conteúdo.

Fontes consultadas

  1. Docker Docs — What is a container? — docs.docker.com
  2. Docker Docs — What is an image? — docs.docker.com
  3. Docker Docs — Understanding the image layers — docs.docker.com
  4. Docker Docs — Running containers — docs.docker.com

Continue por aqui