Tutorial Docker Completo
Capítulo 1: Instalação do Docker no Windows
Neste primeiro capítulo, abordaremos o processo de instalação do Docker Desktop no
sistema operacional Windows. O Docker Desktop é a maneira mais fácil e recomendada
de instalar e gerenciar o Docker em ambientes Windows, oferecendo uma interface
gráfica intuitiva e integração com o sistema.
Requisitos do Sistema
Antes de iniciar a instalação, é crucial verificar se o seu sistema atende aos requisitos
mínimos. A documentação oficial do Docker especifica os seguintes pré-requisitos para
a instalação utilizando o backend WSL 2 (Windows Subsystem for Linux 2), que é a opção
padrão e recomendada:
• WSL: Versão [Link] ou posterior instalada e habilitada. O WSL permite executar um
ambiente Linux diretamente no Windows, sem a necessidade de uma máquina
virtual tradicional.
• Sistema Operacional:
◦ Windows 11 (64 bits): Home ou Pro versão 22H2 ou superior; Enterprise ou
Education versão 22H2 ou superior.
◦ Windows 10 (64 bits): Home ou Pro 22H2 (build 19045) ou superior;
Enterprise ou Education 22H2 (build 19045) ou superior.
• Hardware:
◦ Processador de 64 bits com Suporte à Virtualização (SLAT - Second Level
Address Translation).
◦ Pelo menos 4GB de memória RAM.
◦ Virtualização de hardware habilitada na BIOS/UEFI do sistema. Consulte a
documentação do fabricante do seu computador para obter instruções sobre
como habilitar essa funcionalidade.
É importante notar que o Docker Desktop, por padrão, utiliza o WSL 2 como backend.
Embora ainda seja possível utilizar o backend Hyper-V (a tecnologia de virtualização
nativa do Windows), o WSL 2 geralmente oferece melhor desempenho e integração. A
escolha entre WSL 2 e Hyper-V depende das suas necessidades específicas, mas para a
maioria dos usuários, o WSL 2 é a opção preferencial. A documentação oficial detalha
como habilitar o WSL 2, caso ainda não esteja ativo em seu sistema [1].
O Docker Desktop não é oficialmente suportado em versões de servidor do Windows,
como Windows Server 2019 ou 2022. Para esses ambientes, a Microsoft oferece outras
soluções para execução de contêineres [1]. Além disso, para executar contêineres
Windows (em oposição aos contêineres Linux, que são mais comuns), é necessário ter as
edições Professional ou Enterprise do Windows 10 ou 11. As edições Home e Education
suportam apenas contêineres Linux [1].
Processo de Instalação
Existem duas maneiras principais de instalar o Docker Desktop no Windows:
interativamente (através de um assistente gráfico) ou pela linha de comando.
Instalação Interativa:
1. Download: Baixe o instalador do Docker Desktop ( Docker Desktop [Link] )
diretamente do site oficial do Docker [1]. O site oferece versões para processadores
x86_64 (Intel/AMD) e também uma versão Early Access para ARM.
2. Execução: Dê um duplo clique no arquivo Docker Desktop [Link] para iniciar
o assistente de instalação.
3. Configuração: Durante a instalação, o assistente apresentará uma tela de
configuração. Certifique-se de que a opção "Use WSL 2 instead of Hyper-V" esteja
marcada (a menos que você tenha um motivo específico para usar o Hyper-V). Se o
seu sistema suportar apenas um dos backends, o instalador selecionará
automaticamente a opção disponível.
4. Autorização e Instalação: Siga as instruções do assistente, concedendo as
permissões necessárias para a instalação prosseguir. Por padrão, o Docker Desktop
será instalado em C:\Program Files\Docker\Docker .
5. Conclusão: Após a conclusão bem-sucedida da instalação, clique em "Close".
6. Iniciar o Docker Desktop: Procure por "Docker Desktop" no menu Iniciar e execute
a aplicação.
Instalação pela Linha de Comando:
Para usuários que preferem a linha de comando ou precisam automatizar a instalação, é
possível executar o instalador com parâmetros específicos.
1. Download: Baixe o Docker Desktop [Link] como na instalação interativa.
2. Abra o Terminal: Abra o Prompt de Comando ([Link]) ou o PowerShell como
administrador.
3. Execute o Comando: Navegue até o diretório onde você baixou o instalador e
execute o seguinte comando (ajuste o caminho se necessário):
◦ No Prompt de Comando: bash "Docker Desktop [Link]" install --quiet --
accept-license
◦ No PowerShell: powershell Start-Process "Docker Desktop [Link]" -Wait
-ArgumentList "install", "--quiet", "--accept-license"
◦ Flags Comuns:
▪ --quiet : Suprime a saída de informações durante a instalação.
▪ --accept-license : Aceita os termos de serviço automaticamente.
▪ --installation-dir=<path> : Especifica um diretório de instalação
diferente.
▪ --backend=<backend name> : Permite escolher explicitamente o
backend ( wsl-2 , hyper-v , windows ).
A documentação oficial lista todas as flags disponíveis para personalizar a
instalação [1].
Pós-Instalação: Grupo docker-users
Se a sua conta de usuário do Windows for diferente da conta de administrador utilizada
para a instalação, você precisará adicionar sua conta de usuário ao grupo docker-users
para poder gerenciar o Docker sem privilégios elevados constantemente.
1. Execute o "Gerenciamento do Computador" (Computer Management) como
administrador.
2. Navegue até "Usuários e Grupos Locais" > "Grupos".
3. Encontre o grupo docker-users , clique com o botão direito e selecione "Adicionar
ao Grupo...".
4. Adicione sua conta de usuário.
5. Faça logout e login novamente no Windows para que as alterações tenham efeito.
Iniciando o Docker Desktop
Após a instalação, o Docker Desktop não inicia automaticamente. Você precisa iniciá-lo
manualmente pela primeira vez através do menu Iniciar. Ao iniciar, você será solicitado a
aceitar o Docker Subscription Service Agreement. É importante ler os termos,
especialmente em relação ao uso comercial em empresas maiores, que pode exigir uma
assinatura paga [1].
Com o Docker Desktop instalado e em execução, um ícone de baleia aparecerá na área
de notificação do Windows, indicando que o serviço Docker está ativo e pronto para uso.
Você pode clicar com o botão direito neste ícone para acessar configurações, tutoriais e
outras opções.
Referências
[1] Docker Inc. "Install Docker Desktop on Windows". Docker Documentation. Acessado
em 02 de junho de 2025. [Link]
install/
Capítulo 2: Baixando e Criando Imagens Docker
Com o Docker instalado, o próximo passo fundamental é trabalhar com imagens. As
imagens Docker são a base dos contêineres; elas contêm o sistema operacional, as
bibliotecas, as dependências, o código da aplicação e tudo o mais necessário para
executar uma aplicação de forma isolada. Neste capítulo, exploraremos como obter
imagens prontas de registros públicos e como construir suas próprias imagens
personalizadas.
Baixando Imagens (docker pull)
A maneira mais comum de obter imagens é baixá-las de um registro de contêineres. O
Docker Hub é o registro público padrão e mais popular, hospedando milhares de
imagens oficiais e da comunidade para diversas tecnologias (sistemas operacionais,
bancos de dados, linguagens de programação, etc.).
O comando principal para baixar imagens é docker image pull (ou sua forma abreviada,
docker pull ). A sintaxe básica é:
docker pull NOME_DA_IMAGEM[:TAG|@DIGEST]
• NOME_DA_IMAGEM: Identifica a imagem que você deseja baixar. Geralmente,
segue o formato [registro/][usuário/]nome_repositório . Se o registro não for
especificado, o Docker assume o Docker Hub. Se o usuário não for especificado,
assume-se que é uma imagem oficial do Docker Hub (como ubuntu , python ,
nginx ).
• TAG (Opcional): Especifica uma versão particular da imagem. Tags comuns
incluem latest (a versão mais recente, que é o padrão se nenhuma tag for
fornecida), números de versão (como 16.04 , 3.9 ), ou nomes descritivos ( alpine ,
slim ).
• DIGEST (Opcional): É um identificador único e imutável (um hash SHA256) para
uma versão específica da imagem. Usar o digest garante que você sempre baixe
exatamente a mesma versão da imagem, independentemente de atualizações na
tag [2].
Exemplos:
1. Baixar a imagem oficial mais recente do Ubuntu: bash docker pull ubuntu # ou
explicitamente docker pull ubuntu:latest O Docker procurará a imagem ubuntu no
Docker Hub e baixará a versão marcada com a tag latest .
2. Baixar uma versão específica do Python: bash docker pull python:3.9-slim Isso
baixa a imagem oficial do Python, especificamente a versão 3.9 em sua variante
slim (geralmente menor).
3. Baixar uma imagem por digest: Primeiro, você pode obter o digest após um pull
normal ou inspecionando a imagem. Depois, use o digest: bash # Exemplo de
digest (substitua pelo digest real) docker pull
ubuntu@sha256:aabed3296a3d45cede9976809b742d53f5e7e4335f8f101985784996560b4b87
Isso garante que você está baixando exatamente aquela versão específica da
imagem Ubuntu [2].
4. Baixar de um registro diferente: Se você estiver usando um registro privado ou
outro registro público (como o Google Container Registry - [Link]), especifique o
caminho completo: bash docker pull [Link]/google-containers/busybox
Ao executar docker pull , o Docker verifica se alguma das camadas (layers) da imagem já
existe localmente. Se sim, ele reutiliza essas camadas, baixando apenas as que faltam.
Isso torna o processo eficiente em termos de tempo e espaço em disco [2]. Você pode
listar as imagens baixadas localmente usando o comando docker images ou docker
image ls .
Criando Imagens Personalizadas (Dockerfile e docker build)
Embora baixar imagens prontas seja útil, frequentemente você precisará criar suas
próprias imagens para empacotar suas aplicações e configurações específicas. Isso é
feito através de um arquivo chamado Dockerfile .
O Dockerfile:
Um Dockerfile é um arquivo de texto simples, sem extensão, que contém uma série de
instruções passo a passo sobre como construir uma imagem Docker [3]. Cada instrução
cria uma nova camada na imagem.
Instruções Comuns do Dockerfile:
• FROM <imagem_base> : Obrigatória e deve ser a primeira instrução. Define a
imagem base sobre a qual sua nova imagem será construída (ex: FROM ubuntu:
22.04 , FROM python:3.10-alpine ).
• WORKDIR /caminho/no/container : Define o diretório de trabalho padrão para as
instruções subsequentes ( RUN , CMD , ENTRYPOINT , COPY , ADD ). Se o
diretório não existir, ele será criado.
• COPY <origem_no_host> <destino_no_container> : Copia arquivos ou diretórios do
seu sistema (host) para dentro da imagem.
• RUN <comando> : Executa um comando dentro da imagem durante o processo de
build (ex: RUN apt-get update && apt-get install -y nginx , RUN pip install -r
[Link] ). Cada RUN cria uma nova camada.
• EXPOSE <porta> : Informa ao Docker que o contêiner escutará em uma porta
específica em tempo de execução. Não publica a porta automaticamente, apenas
documenta.
• CMD ["executavel", "param1", "param2"] (Formato preferido: exec) ou
CMD comando param1 param2 (Formato shell): Define o comando padrão que
será executado quando um contêiner for iniciado a partir desta imagem. Só pode
haver uma instrução CMD efetiva; se houver várias, apenas a última terá efeito.
• ENTRYPOINT ["executavel", "param1", "param2"] : Configura o contêiner para ser
executado como um executável. Permite que você passe argumentos para o
ENTRYPOINT através do docker run . Se CMD também for definido, seus valores
serão passados como argumentos para o ENTRYPOINT .
• ENV <chave>=<valor> : Define variáveis de ambiente dentro da imagem.
• ARG <nome_argumento>[=<valor_padrao>] : Define variáveis que podem ser
passadas durante o build com a flag --build-arg no comando docker build .
• USER <nome_usuario_ou_uid> : Define o nome de usuário (ou UID) a ser usado ao
executar a imagem e para quaisquer instruções RUN , CMD e ENTRYPOINT que
se seguem.
Exemplo de Dockerfile Simples (Aplicação [Link]):
# 1. Usar uma imagem base oficial do [Link] (versão LTS Alpine)
FROM node:lts-alpine
# 2. Definir o diretório de trabalho dentro do container
WORKDIR /app
# 3. Copiar os arquivos de definição de dependências
COPY [Link] [Link] ./
# 4. Instalar as dependências da aplicação
RUN npm ci --only=production
# 5. Copiar o restante do código da aplicação
COPY . .
# 6. Expor a porta que a aplicação usa
EXPOSE 3000
# 7. Definir o comando padrão para iniciar a aplicação
CMD ["node", "[Link]"]
Construindo a Imagem (docker build):
Depois de criar o Dockerfile , você usa o comando docker build para construir a
imagem a partir dele. A sintaxe básica é:
docker build [OPTIONS] CAMINHO_PARA_CONTEXTO_BUILD
• OPTIONS:
◦ -t NOME_IMAGEM[:TAG] : (Tag) Atribui um nome e, opcionalmente, uma tag à
imagem construída (ex: -t minha-app:1.0 , -t meu-usuario/minha-api:latest ).
É altamente recomendado usar tags.
◦ -f /caminho/para/Dockerfile : Especifica um nome ou caminho diferente
para o Dockerfile (o padrão é Dockerfile no contexto de build).
◦ --build-arg VARIAVEL=valor : Passa argumentos de build definidos com ARG
no Dockerfile.
• CAMINHO_PARA_CONTEXTO_BUILD: O diretório no seu host que contém o
Dockerfile e quaisquer outros arquivos necessários para o build (como o código-
fonte a ser copiado). O Docker envia o conteúdo deste diretório (o "contexto") para
o daemon Docker para realizar o build. Geralmente, é . (o diretório atual).
Exemplo de Build:
Supondo que o Dockerfile acima e os arquivos da aplicação [Link] estejam no
diretório atual:
docker build -t minha-app-node:1.0 .
Este comando instrui o Docker a: 1. Usar o diretório atual ( . ) como contexto de build. 2.
Procurar por um arquivo chamado Dockerfile neste diretório. 3. Executar as instruções
dentro do Dockerfile passo a passo. 4. Se o build for bem-sucedido, marcar (tag) a
imagem resultante como minha-app-node:1.0 .
Você verá a saída do Docker mostrando cada passo do build. Após a conclusão, a nova
imagem estará disponível localmente ( docker images ).
Dominar o docker pull e o docker build é essencial para gerenciar e criar os ambientes
conteinerizados que você precisa para suas aplicações.
Referências
[2] Docker Inc. "docker image pull". Docker Documentation. Acessado em 02 de junho de
2025. [Link] [3] Docker Inc. "Writing
a Dockerfile". Docker Documentation. Acessado em 02 de junho de 2025. https://
[Link]/get-started/docker-concepts/building-images/writing-a-dockerfile/
Capítulo 3: Criando Contêineres (Terminal e Docker
Desktop)
Após baixar ou construir as imagens Docker necessárias, o próximo passo lógico é criar e
executar contêineres a partir delas. Um contêiner é, essencialmente, uma instância em
execução de uma imagem Docker. Ele encapsula a aplicação e todas as suas
dependências, executando-as de forma isolada do sistema hospedeiro e de outros
contêineres. Neste capítulo, veremos como criar contêineres utilizando tanto a linha de
comando (terminal) quanto a interface gráfica do Docker Desktop.
Criando Contêineres pelo Terminal (docker run)
A ferramenta principal para criar e iniciar contêineres via terminal é o comando docker
run . Ele é extremamente versátil e possui uma vasta gama de opções para configurar
como o contêiner será executado.
A sintaxe básica é:
docker run [OPTIONS] NOME_DA_IMAGEM[:TAG|@DIGEST] [COMANDO] [ARG...]
• OPTIONS: Modificadores que controlam o comportamento do contêiner.
• NOME_DA_IMAGEM[:TAG|@DIGEST]: A imagem a partir da qual o contêiner será
criado.
• [COMANDO] [ARG...]: (Opcional) Substitui o comando padrão ( CMD ou
ENTRYPOINT ) definido na imagem.
Opções Comuns do docker run :
• -d ou --detach : Executa o contêiner em segundo plano (modo "detached"). O
terminal fica livre e o ID do contêiner é impresso.
• -it : Combinação de -i (interativo, mantém o STDIN aberto) e -t (aloca um
pseudo-TTY). Usado para executar contêineres com os quais você precisa interagir,
como um shell.
• -p <porta_host>:<porta_container> : Mapeia uma porta do seu sistema hospedeiro
(host) para uma porta dentro do contêiner. Essencial para acessar aplicações
(como servidores web) rodando no contêiner.
◦ Exemplo: -p 8080:80 mapeia a porta 8080 do host para a porta 80 do
contêiner.
• -v <volume_host_ou_nomeado>:<caminho_container> : Monta um volume. Permite
persistir dados ou compartilhar arquivos entre o host e o contêiner.
◦ Bind Mount: -v /caminho/no/host:/caminho/no/container - Mapeia um
diretório do host diretamente para dentro do contêiner.
◦ Volume Nomeado: -v nome_volume:/caminho/no/container - Usa um
volume gerenciado pelo Docker, mais recomendado para persistência de
dados.
• --name <nome_container> : Atribui um nome específico ao contêiner, facilitando
sua identificação e gerenciamento (em vez de usar o ID longo ou um nome
aleatório gerado pelo Docker).
• --rm : Remove automaticamente o contêiner quando ele para de executar. Útil
para tarefas rápidas ou testes.
• -e <VARIAVEL>=<valor> ou --env <VARIAVEL>=<valor> : Define variáveis de
ambiente dentro do contêiner.
• --network <nome_rede> : Conecta o contêiner a uma rede Docker específica.
Exemplos de docker run :
1. Executar um servidor web Nginx simples: bash docker run --name meu-nginx -d
-p 8080:80 nginx:latest
◦ --name meu-nginx : Nomeia o contêiner como "meu-nginx".
◦ -d : Executa em segundo plano.
◦ -p 8080:80 : Mapeia a porta 8080 do seu computador para a porta 80 padrão
do Nginx dentro do contêiner.
◦ nginx:latest : Usa a imagem oficial mais recente do Nginx. Após executar este
comando, você poderá acessar a página padrão do Nginx abrindo http://
localhost:8080 no seu navegador.
2. Executar um shell interativo em um contêiner Ubuntu: bash docker run -it --rm
--name meu-ubuntu ubuntu:latest /bin/bash
◦ -it : Permite interagir com o shell do contêiner.
◦ --rm : Remove o contêiner assim que você sair do shell ( exit ).
◦ --name meu-ubuntu : Nomeia o contêiner.
◦ ubuntu:latest : Usa a imagem mais recente do Ubuntu.
◦ /bin/bash : Especifica o comando a ser executado (inicia o shell Bash). Você
terá um prompt de comando dentro do ambiente Ubuntu isolado.
3. Executar um contêiner e montar um volume: ```bash # Criar um volume
nomeado primeiro (opcional, mas boa prática) docker volume create dados-app
Executar o container montando o
volume
docker run -d --name minha-app-com-volume -v dados-app:/app/data minha-
imagem-app:1.0 `` * -v dados-app:/app/data : Monta o volume nomeado dados-
app no diretório /app/data dentro do contêiner. Quaisquer dados escritos em /app/
data pelo contêiner serão persistidos no volume dados-app`, mesmo que o
contêiner seja removido.
Criando sem Iniciar ( docker container create ):
Existe também o comando docker container create (ou docker create ) que funciona de
forma muito similar ao docker run , aceitando as mesmas opções, mas com uma
diferença crucial: ele apenas cria a camada gravável do contêiner sobre a imagem e o
configura, mas não o inicia [4]. O contêiner fica no estado "created".
docker create --name nginx-preparado -p 8081:80 nginx:latest
Isso cria um contêiner chamado nginx-preparado . Para iniciá-lo posteriormente, você
usaria o comando docker start nginx-preparado .
Criando Contêineres pelo Docker Desktop (Interface Gráfica)
O Docker Desktop oferece uma interface gráfica amigável para gerenciar imagens e
contêineres, sendo uma alternativa visual ao terminal.
Passos para Criar um Contêiner via Docker Desktop:
1. Abra o Docker Desktop: Inicie a aplicação.
2. Navegue até Imagens: No painel esquerdo, clique na aba "Images". Você verá a
lista de imagens disponíveis localmente.
3. Selecione a Imagem: Encontre a imagem que deseja usar (por exemplo, nginx ou
uma imagem que você construiu) e passe o mouse sobre ela.
4. Clique em "Run": Um botão "Run" aparecerá ao lado do nome da imagem. Clique
nele.
5. Configure as Opções (Opcional): Uma janela ou painel de configuração será
exibido, permitindo definir opções equivalentes às flags do docker run :
◦ Container Name: Equivalente a --name .
◦ Ports: Mapeamento de portas (Host Port -> Container Port), equivalente a -
p.
◦ Volumes: Mapeamento de volumes (Host Path/Named Volume -> Container
Path), equivalente a -v .
◦ Environment Variables: Definição de variáveis de ambiente, equivalente a -
e.
◦ Outras opções avançadas podem estar disponíveis dependendo da versão.
6. Clique em "Run" (novamente): Após configurar as opções desejadas (ou deixar os
padrões), clique no botão "Run" na janela de configuração.
O Docker Desktop criará e iniciará o contêiner. Ele aparecerá na aba "Containers" no
painel esquerdo. Clicando no nome do contêiner, você pode ver seus logs, inspecionar
detalhes, acessar um terminal dentro dele (CLI), pará-lo, reiniciá-lo ou removê-lo.
Exemplo (Rodando hello-world via Docker Desktop):
1. Vá para a aba "Images".
2. Se a imagem hello-world não estiver listada, você pode baixá-la usando a barra de
busca na parte superior (procure por hello-world e clique em "Pull").
3. Passe o mouse sobre a imagem hello-world e clique em "Run".
4. Não são necessárias configurações adicionais para esta imagem simples. Clique em
"Run" na janela de configuração.
5. O contêiner será executado rapidamente, imprimirá uma mensagem de
confirmação nos logs (visível na aba "Containers" ao selecionar o contêiner hello-
world ) e depois parará (estado "Exited").
Terminal vs. Docker Desktop
• Terminal (CLI):
◦ Vantagens: Poderoso, flexível, ideal para automação e scripting, todas as
opções estão disponíveis, mais rápido para usuários experientes.
◦ Desvantagens: Curva de aprendizado maior, menos visual.
• Docker Desktop (GUI):
◦ Vantagens: Intuitivo, visual, fácil para iniciantes, bom para gerenciamento
rápido e visualização de logs/status.
◦ Desvantagens: Pode não expor todas as opções avançadas do CLI, menos
adequado para automação complexa.
Ambos os métodos atingem o mesmo objetivo: criar contêineres. A escolha entre eles
muitas vezes depende da preferência pessoal, da tarefa específica e do nível de
experiência do usuário. É comum usar ambos em conjunto.
Referências
[4] Docker Inc. "docker container create". Docker Documentation. Acessado em 02 de
junho de 2025. [Link]
Capítulo 4: Executando e Gerenciando Contêineres
Uma vez que os contêineres são criados (seja com docker run ou docker create ), é
essencial saber como gerenciá-los: iniciá-los, pará-los, reiniciá-los, verificar seu status,
visualizar seus logs e interagir com os processos em execução dentro deles. Este
capítulo cobre os comandos e técnicas fundamentais para o gerenciamento do ciclo de
vida dos contêineres Docker, tanto via terminal quanto pela interface do Docker
Desktop.
Gerenciando o Ciclo de Vida (Terminal)
Listando Contêineres ( docker ps ):
O comando docker ps (ou docker container ls ) é usado para listar os contêineres.
• docker ps : Lista apenas os contêineres em execução.
• docker ps -a ou docker ps --all : Lista todos os contêineres, incluindo os que
estão parados (com status "Exited" ou "Created").
A saída mostra informações úteis como ID do Contêiner, Imagem utilizada, Comando em
execução, quando foi criado, Status atual, Portas mapeadas e o Nome do contêiner.
Iniciando Contêineres Parados ( docker start ):
Se você criou um contêiner com docker create ou parou um contêiner existente, pode
iniciá-lo (ou reiniciá-lo) com o comando docker start (ou docker container start ).
docker start ID_OU_NOME_DO_CONTAINER [ID_OU_NOME_DO_CONTAINER...]
Você pode iniciar um ou mais contêineres fornecendo seus IDs ou nomes.
Parando Contêineres em Execução ( docker stop ):
Para parar um contêiner que está em execução, use o comando docker stop (ou docker
container stop ).
docker stop [OPTIONS] ID_OU_NOME_DO_CONTAINER
[ID_OU_NOME_DO_CONTAINER...]
• Por padrão, docker stop envia um sinal SIGTERM para o processo principal
dentro do contêiner, solicitando que ele termine graciosamente. Ele aguarda um
tempo limite (padrão de 10 segundos no Linux) para o processo encerrar. Se o
processo não terminar nesse tempo, o Docker envia um sinal SIGKILL para forçar
o encerramento.
• Opções:
◦ -t ou --time : Especifica o tempo de espera (em segundos) antes de enviar o
SIGKILL .
Reiniciando Contêineres ( docker restart ):
O comando docker restart (ou docker container restart ) é um atalho conveniente que
executa um stop seguido por um start no contêiner especificado [5].
docker restart [OPTIONS] ID_OU_NOME_DO_CONTAINER
[ID_OU_NOME_DO_CONTAINER...]
• Ele aceita as mesmas opções -t (timeout) e -s (signal) que o docker stop para
controlar como o contêiner é parado antes de ser reiniciado.
Removendo Contêineres ( docker rm ):
Contêineres parados continuam ocupando espaço em disco (sua camada gravável). Para
removê-los permanentemente, use docker rm (ou docker container rm ). Importante:
Você só pode remover contêineres que estão parados.
docker rm ID_OU_NOME_DO_CONTAINER [ID_OU_NOME_DO_CONTAINER...]
• Para remover um contêiner em execução, você precisa pará-lo primeiro ( docker
stop <id> && docker rm <id> ) ou usar a flag -f (force): bash docker rm -f
ID_OU_NOME_DO_CONTAINER Usar -f envia um SIGKILL imediatamente, o que
pode levar à perda de dados se a aplicação não foi projetada para lidar com isso.
• Remover todos os contêineres parados: Um comando útil para limpeza é: bash
docker container prune # ou o comando mais antigo: docker rm $(docker ps -a -q -f
status=exited) O docker container prune pedirá confirmação antes de remover.
Visualizando Logs ( docker logs )
Para ver a saída padrão (STDOUT) e o erro padrão (STDERR) de um contêiner, use o
comando docker logs (ou docker container logs ). Isso é crucial para depurar
aplicações ou verificar o que está acontecendo dentro de um contêiner em execução (ou
que foi executado).
docker logs [OPTIONS] ID_OU_NOME_DO_CONTAINER
• Opções Comuns:
◦ -f ou --follow : Segue a saída do log em tempo real (similar ao tail -f ).
Pressione Ctrl+C para parar de seguir.
◦ --tail <numero> : Mostra as últimas N linhas do log (ex: --tail 100 ).
◦ --since <timestamp> : Mostra logs desde um timestamp específico (ex: --
since 2025-06-02T21:00:00 ).
◦ --until <timestamp> : Mostra logs até um timestamp específico.
◦ -t ou --timestamps : Mostra timestamps para cada linha de log.
Exemplo:
# Ver os últimos 50 logs do container meu-nginx
docker logs --tail 50 meu-nginx
# Seguir os logs do container minha-app em tempo real
docker logs -f minha-app
Executando Comandos em Contêineres Ativos ( docker exec )
Às vezes, você precisa executar um comando dentro de um contêiner que já está em
execução, seja para depuração, inspeção ou tarefas administrativas. O comando docker
exec (ou docker container exec ) permite fazer isso.
docker exec [OPTIONS] ID_OU_NOME_DO_CONTAINER COMANDO [ARG...]
• Opções Comuns:
◦ -i : Mantém o STDIN aberto (necessário para interação).
◦ -t : Aloca um pseudo-TTY (necessário para um shell interativo).
◦ -d : Executa o comando em segundo plano (modo detached) dentro do
contêiner.
◦ -e <VAR>=<VAL> : Define variáveis de ambiente apenas para este comando
exec .
◦ -w /caminho/ : Define o diretório de trabalho para o comando exec .
Exemplos:
1. Abrir um shell Bash interativo em um contêiner chamado meu-servidor : bash
docker exec -it meu-servidor /bin/bash Isso lhe dará um prompt de comando
dentro do contêiner meu-servidor .
2. Listar arquivos em um diretório específico dentro do contêiner meu-nginx :
bash docker exec meu-nginx ls /usr/share/nginx/html O comando ls é
executado dentro do contêiner e sua saída é mostrada no seu terminal.
3. Executar um backup de banco de dados (exemplo conceitual):
bash docker exec meu-db-container pg_dump -U usuario -d banco > [Link]
Executa o comando pg_dump dentro do contêiner meu-db-container e
redireciona a saída para um arquivo [Link] no seu sistema host.
Gerenciando Contêineres pelo Docker Desktop
A interface gráfica do Docker Desktop simplifica muitas dessas operações:
1. Listar Contêineres: Abra o Docker Desktop e clique na aba "Containers" no painel
esquerdo. Você verá todos os contêineres (em execução e parados) listados.
2. Iniciar/Parar/Reiniciar: Ao lado de cada contêiner na lista, há botões de ação
rápida (geralmente ícones de play, stop, restart) para controlar seu ciclo de vida.
3. Ver Logs: Clique no nome de um contêiner na lista. Uma nova visão se abrirá,
geralmente mostrando os logs do contêiner por padrão. Você pode pausar/seguir
os logs e limpá-los.
4. Executar Comandos (CLI): Na visão detalhada do contêiner, geralmente há uma
aba ou botão "CLI" ou "Exec". Clicar nele abre um terminal diretamente conectado
ao contêiner, permitindo que você execute comandos como se tivesse usado
docker exec -it <id> /bin/sh .
5. Inspecionar: A visão detalhada do contêiner também possui uma aba "Inspect"
que mostra a configuração completa do contêiner em formato JSON (equivalente a
docker inspect <id> ).
6. Verificar Stats: Uma aba "Stats" mostra o consumo de recursos em tempo real
(CPU, memória, rede, I/O de disco), similar ao comando docker stats .
7. Remover: Contêineres parados terão um ícone de lixeira para removê-los.
Contêineres em execução precisam ser parados antes que a opção de remoção
apareça, ou você pode usar a opção de forçar a remoção se disponível.
O Docker Desktop oferece uma maneira visual e conveniente de realizar as tarefas mais
comuns de gerenciamento de contêineres, complementando o poder e a flexibilidade da
linha de comando.
Referências
[5] Docker Inc. "docker container restart". Docker Documentation. Acessado em 02 de
junho de 2025. [Link]
Capítulo 5: Adicionando Arquivos do Windows em um
Contêiner
Uma necessidade comum ao trabalhar com Docker, especialmente em ambientes de
desenvolvimento, é compartilhar arquivos entre o sistema operacional hospedeiro
(Windows, neste caso) e os contêineres em execução. Isso permite, por exemplo, editar o
código-fonte no seu editor preferido no Windows e ver as alterações refletidas
imediatamente dentro do contêiner onde a aplicação está rodando, ou persistir dados
gerados pelo contêiner no sistema de arquivos do host.
Existem duas maneiras principais de realizar esse compartilhamento no Docker: Bind
Mounts e Volumes Nomeados. O comando docker cp também pode ser usado para
cópias pontuais, mas não é ideal para compartilhamento contínuo.
Bind Mounts: Mapeamento Direto de Diretórios
Bind mounts mapeiam um diretório ou arquivo específico do sistema de arquivos do
host diretamente para um caminho dentro do contêiner [6]. Qualquer alteração feita no
host é refletida no contêiner e vice-versa, em tempo real.
Sintaxe (Terminal - docker run ):
Existem duas sintaxes principais para definir bind mounts com docker run :
1. Flag -v (mais antiga, ainda comum): bash docker run -v /caminho/no/
windows:/caminho/no/container ... minha_imagem
2. Flag --mount (mais explícita e recomendada): bash docker run --mount
type=bind,source=/caminho/no/windows,target=/caminho/no/container ...
minha_imagem
◦ type=bind : Especifica que é um bind mount.
◦ source : O caminho absoluto do diretório ou arquivo no host (Windows).
◦ target : O caminho absoluto onde o diretório/arquivo será montado dentro
do contêiner.
Considerações sobre Caminhos no Windows (Especialmente com WSL2):
Quando você usa Docker Desktop com o backend WSL2 (o padrão), o Docker na verdade
roda dentro de uma distribuição Linux leve no WSL2. Para acessar seus arquivos do
Windows a partir deste ambiente Linux (e, por extensão, dos seus contêineres), você
precisa usar um caminho especial:
• Seus drives do Windows (C:, D:, etc.) são montados automaticamente dentro do
ambiente WSL2 sob o diretório /mnt/ . Por exemplo:
◦ C:\Users\SeuUsuario\Projeto no Windows se torna /mnt/c/Users/
SeuUsuario/Projeto dentro do WSL2 e, consequentemente, para o Docker.
Exemplo (Terminal):
Suponha que você tenha o código-fonte do seu projeto em C:\Projetos\MeuApp no
Windows e queira montá-lo em /app dentro de um contêiner [Link] para
desenvolvimento:
# Usando a flag -v
docker run -d --name dev-meu-app -p 3000:3000 -v /mnt/c/Projetos/MeuApp:/
app node:lts-alpine sh -c "npm install && npm run dev"
# Usando a flag --mount
docker run -d --name dev-meu-app -p 3000:3000 --mount type=bind,source=/mnt/
c/Projetos/MeuApp,target=/app node:lts-alpine sh -c "npm install && npm run dev"
Importante: O caminho source deve ser o caminho acessível pelo daemon Docker (no
caso do WSL2, o caminho iniciado por /mnt/ ). Usar C:\Projetos\MeuApp diretamente
na linha de comando pode não funcionar ou ter comportamento inesperado
dependendo do seu shell e configuração.
Vantagens dos Bind Mounts: * Ideal para desenvolvimento, permitindo edição de
código no host com reflexo imediato no contêiner. * Acesso direto aos arquivos do host.
Desvantagens/Cuidados: * Permissões: Podem ocorrer problemas de permissão, pois
o UID/GID (identificadores de usuário/grupo) dentro do contêiner Linux pode não
corresponder ou ter permissão para acessar os arquivos montados do host Windows.
Isso pode exigir ajustes no Dockerfile (criando um usuário específico) ou nas permissões
dos arquivos no host (menos comum/recomendado). * Dependência do Host: O
contêiner fica dependente da estrutura de diretórios do host. Se você mover o projeto
no host, o bind mount quebrará. * Performance: Em algumas operações intensivas de I/
O, bind mounts podem ser ligeiramente mais lentos que volumes nomeados,
especialmente em sistemas operacionais diferentes (como Windows host -> Linux
container). * Segurança: O contêiner tem acesso direto (leitura/escrita, por padrão) a
uma parte do sistema de arquivos do host, o que pode ser um risco de segurança se o
contêiner for comprometido.
Volumes Nomeados: Gerenciamento pelo Docker
Volumes nomeados são a maneira preferida de persistir dados gerados por contêineres.
Em vez de mapear um diretório específico do host, você cria um volume gerenciado pelo
Docker, que o Docker armazena em uma área específica do sistema de arquivos do host
(geralmente dentro da estrutura de dados do Docker ou do WSL2), mas você não
interage diretamente com essa localização.
Sintaxe (Terminal - docker run ):
1. Flag -v : bash docker run -v nome_do_volume:/caminho/no/container ...
minha_imagem
2. Flag --mount : bash docker run --mount
type=volume,source=nome_do_volume,target=/caminho/no/container ...
minha_imagem
◦ type=volume : Especifica que é um volume nomeado.
◦ source : O nome que você dá ao volume (ex: dados-db , config-app ). Se o
volume não existir, o Docker o cria automaticamente.
◦ target : O caminho absoluto onde o volume será montado dentro do
contêiner.
Exemplo (Terminal):
Montar um volume nomeado dados-postgres no diretório de dados padrão do
PostgreSQL:
docker run -d --name meu-postgres -e POSTGRES_PASSWORD=senhaforte --
mount type=volume,source=dados-postgres,target=/var/lib/postgresql/data
postgres:latest
Vantagens dos Volumes Nomeados: * Gerenciamento: Mais fáceis de gerenciar (criar,
listar, remover) com comandos Docker ( docker volume create , docker volume ls ,
docker volume rm , docker volume prune ). * Portabilidade: Não dependem da
estrutura de diretórios do host. * Performance: Geralmente oferecem melhor
performance para I/O intensivo em contêineres Linux. * Segurança: Isolados do sistema
de arquivos principal do host. * Inicialização: Se você montar um volume nomeado
vazio em um diretório de contêiner que já contém arquivos (definidos na imagem), o
Docker copiará esses arquivos da imagem para o volume na primeira vez que ele for
montado.
Desvantagens: * Não são ideais para compartilhar código-fonte durante o
desenvolvimento, pois o acesso direto aos arquivos no host é mais complicado.
Adicionando Arquivos via Docker Desktop (Interface Gráfica)
Ao criar ou executar um contêiner pelo Docker Desktop (conforme visto no Capítulo 3), a
interface gráfica oferece campos para configurar montagens:
1. Na janela de configuração "Run a new container":
2. Procure pela seção "Volumes" (ou similar).
3. Você terá opções para adicionar montagens:
◦ Bind Mount: Geralmente pede um "Host Path" (onde você navegará ou
digitará o caminho do Windows, ex: C:\Projetos\MeuApp ) e um "Container
Path" (ex: /app ). O Docker Desktop (com WSL2) geralmente faz a tradução
do caminho do Windows para o formato /mnt/c/... automaticamente nos
bastidores.
◦ Named Volume: Pede um "Volume Name" (você digita um nome, ex: dados-
app ) e um "Container Path" (ex: /app/data ). Se o volume não existir, ele
será criado.
4. Adicione quantas montagens forem necessárias e prossiga com a execução do
contêiner.
Copiando Arquivos Pontualmente ( docker cp )
Se você precisa apenas copiar arquivos ou diretórios para dentro ou para fora de um
contêiner (em execução ou parado), sem a necessidade de um mapeamento contínuo,
pode usar o comando docker cp .
Sintaxe:
# Copiar do Host para o Contêiner
docker cp /caminho/local/[Link] ID_OU_NOME_CONTAINER:/caminho/no/
container/
# Copiar do Contêiner para o Host
docker cp ID_OU_NOME_CONTAINER:/caminho/no/container/[Link] /
caminho/local/
Exemplo:
# Copiar um arquivo de configuração para um container nginx em execução
docker cp [Link] meu-nginx:/etc/nginx/[Link]
# Copiar logs de um container para o host
docker cp minha-app:/app/logs/[Link] C:/Temp/
Lembre-se de usar a sintaxe de caminho apropriada ( /mnt/c/... ) se estiver executando
docker cp de dentro do ambiente WSL2 para interagir com arquivos do Windows.
Escolher entre bind mounts e volumes nomeados depende do caso de uso: bind mounts
são ótimos para desenvolvimento e acesso direto ao código no host, enquanto volumes
nomeados são a melhor prática para persistir dados de aplicações de forma gerenciada
e segura.
Referências
[6] Docker Inc. "Part 5: Use bind mounts". Docker Documentation. Acessado em 02 de
junho de 2025. [Link]
Capítulo 6: Erros Comuns no Docker (Windows/WSL2) e
Soluções
Ao longo da sua jornada com Docker, especialmente no ambiente Windows com a
integração WSL2, é natural encontrar alguns obstáculos. Este capítulo aborda os erros
mais frequentes que os usuários enfrentam e oferece soluções práticas para superá-los.
Lembre-se que a depuração faz parte do processo de aprendizado e desenvolvimento.
1. Problemas de Integração e Inicialização do WSL2
O Docker Desktop no Windows depende fortemente do Subsistema Windows para Linux
(WSL2) para executar contêineres Linux. Problemas na comunicação ou no estado do
WSL2 podem impedir o Docker de funcionar corretamente.
• Erro: "Docker Desktop requires a newer WSL kernel version" ou similar.
◦ Causa: O kernel do WSL2 está desatualizado.
◦ Solução: Abra o PowerShell ou Prompt de Comando como administrador e
execute wsl --update . Após a atualização, reinicie o WSL com wsl --
shutdown (aguarde alguns segundos) e, em seguida, reinicie o Docker
Desktop.
• Erro: "An unexpected WSL error occurred", "Docker Desktop stopping...", ou falha
ao iniciar.
◦ Causa: Pode haver um problema no estado interno do WSL2, conflitos ou
falha na comunicação.
◦ Soluções (Tente em ordem):
1. Reiniciar WSL: No PowerShell/CMD (admin), execute wsl --shutdown .
Aguarde um momento e tente iniciar o Docker Desktop novamente.
2. Reiniciar o Computador: Uma reinicialização completa do Windows
pode resolver problemas temporários.
3. Verificar Instalação WSL: Certifique-se de que uma distribuição WSL2
está instalada e definida como padrão. Use wsl --list --verbose para
verificar as distribuições e suas versões (deve ser 2). Se necessário,
instale uma distribuição (ex: wsl --install Ubuntu ) e defina-a como
padrão ( wsl --set-default Ubuntu ).
4. Verificar Configurações do Docker Desktop: Vá em Settings >
Resources > WSL Integration. Garanta que a opção "Enable integration
with my default WSL distro" esteja marcada e que a integração esteja
habilitada para a sua distribuição padrão.
5. Resetar Docker Desktop: Como último recurso, vá em Settings >
Troubleshoot (ícone de inseto) > Reset to factory defaults. Atenção: Isso
removerá todas as suas imagens, contêineres e volumes. Faça backup se
necessário.
6. Reinstalar WSL (Avançado): Em casos raros, pode ser necessário
desinstalar e reinstalar o WSL. Consulte a documentação da Microsoft
[7].
2. Conflitos de Porta ( address already in use )
• Erro: Ao tentar executar um contêiner com -p <porta_host>:<porta_container> ,
você recebe um erro como Error starting userland proxy: listen tcp4
[Link]:<porta_host>: bind: address already in use .
◦ Causa: Outro processo no seu computador (seja no Windows ou dentro do
WSL) já está utilizando a <porta_host> que você especificou.
◦ Soluções:
1. Identificar e Parar o Processo Conflitante:
▪ No Windows (CMD/PowerShell): netstat -ano |
findstr :<porta_host> . Anote o PID (Process ID) na última coluna e
use o Gerenciador de Tarefas (Ctrl+Shift+Esc > Detalhes) para
encontrar e finalizar o processo com esse PID.
▪ Dentro do WSL: sudo netstat -tulnp | grep :<porta_host> .
Identifique o processo e use sudo kill <PID> .
2. Usar Outra Porta no Host: Modifique o mapeamento no comando
docker run para usar uma porta diferente no host que esteja livre. Ex:
Mude -p 8080:80 para -p 8081:80 .
3. Erros de Permissão (Bind Mounts)
• Erro: A aplicação dentro do contêiner não consegue ler ou escrever arquivos em
um diretório montado a partir do Windows ( /mnt/c/... ).
◦ Causa: O usuário que executa o processo dentro do contêiner (definido pela
imagem ou pela flag -u no docker run ) não tem as permissões adequadas
no sistema de arquivos do host (Windows), conforme interpretado pelo WSL.
◦ Soluções:
1. Executar como Usuário Correto: Se a aplicação permitir, execute o
contêiner com um usuário que corresponda ao proprietário dos
arquivos no host. Frequentemente, no WSL, o usuário padrão tem UID
1000 e GID 1000. Tente adicionar -u 1000:1000 ao comando docker
run . Alternativamente, modifique o Dockerfile para criar um usuário
com esse UID/GID e use a instrução USER .
2. Ajustar Permissões no Contêiner (Menos Ideal): Modifique o ponto de
entrada ( ENTRYPOINT ou CMD ) do contêiner para executar comandos
chown ou chmod no diretório montado ao iniciar. Isso pode exigir que
o contêiner inicie como root.
3. Verificar Permissões no Windows: Garanta que o usuário do Windows
tem permissões de leitura/escrita no diretório que está sendo montado.
4. Falhas Durante o Build ( docker build )
• Erro: Falha em comandos como apt-get update , apk add , npm install ,
pip install com erros de rede ou DNS.
◦ Causa: O contêiner de build não consegue acessar a internet ou resolver
nomes de domínio.
◦ Soluções:
1. Verificar Conectividade WSL: Abra um terminal WSL e tente ping
[Link] e ping [Link] . Se falhar, resolva a conectividade de rede
do WSL primeiro.
2. Configurar Proxy Docker: Se você está atrás de um proxy corporativo,
configure-o nas configurações do Docker Desktop (Settings > Resources
> Proxies).
3. Verificar DNS: Garanta que as configurações de DNS do Docker estão
corretas (geralmente herda do host ou WSL). Pode ser necessário
configurar um DNS específico nas configurações do Docker ou do WSL.
• Erro: COPY failed: file not found ou ADD failed: file not found .
◦ Causa: O arquivo ou diretório especificado na instrução COPY ou ADD não
existe no contexto de build enviado ao daemon Docker.
◦ Soluções:
1. Verificar Caminho: Confirme se o caminho de origem na instrução
COPY / ADD está correto relativo ao diretório onde você executa
docker build (o contexto de build).
2. Verificar Contexto: Certifique-se de que o arquivo realmente existe no
diretório de contexto.
3. Verificar .dockerignore : Verifique se o arquivo ou diretório não está
sendo excluído acidentalmente por regras no arquivo .dockerignore .
5. Lentidão com Bind Mounts do Windows ( /mnt/c/... )
• Problema: Operações de leitura/escrita de arquivos em volumes montados a partir
do sistema de arquivos do Windows (ex: /mnt/c/Projetos ) são significativamente
lentas.
◦ Causa: A tradução de chamadas de sistema de arquivos entre o ambiente
Linux do WSL2 e o sistema de arquivos NTFS do Windows tem uma
sobrecarga de desempenho inerente.
◦ Soluções:
1. Mover Projetos para o Filesystem WSL: A solução mais eficaz é clonar
ou mover seus projetos para dentro do sistema de arquivos da sua
distribuição WSL (ex: /home/<seu_usuario_wsl>/projetos/ ). Em
seguida, use bind mounts a partir desse local (ex: -v /home/
<seu_usuario_wsl>/projetos/MeuApp:/app ). Acesse esses arquivos
usando o VS Code com a extensão Remote - WSL ou diretamente pelo
terminal WSL.
2. Usar Volumes Nomeados: Para dados que exigem alto desempenho de
I/O (como bancos de dados), prefira volumes nomeados em vez de bind
mounts do sistema Windows.
6. Erros de Imagem ( image not found , pull access denied )
• Erro: Unable to find image \'nome_imagem:tag\' locally seguido por Error
response from daemon: pull access denied for nome_imagem, repository does not
exist or may require \'docker login\': denied: requested access to the resource is
denied .
◦ Causa: A imagem especificada não foi encontrada localmente e não pôde ser
baixada do registro (geralmente Docker Hub).
◦ Soluções:
1. Verificar Nome/Tag: Confira se há erros de digitação no nome da
imagem ou na tag.
2. Verificar Existência: Certifique-se de que a imagem/tag existe no
registro (procure no Docker Hub ou no registro especificado).
3. Fazer Login (Imagens Privadas): Se a imagem for privada, execute
docker login (ou docker login <url_do_registro> ) antes de tentar o pull
ou run .
7. Passos Gerais de Troubleshooting
Quando encontrar um erro não listado ou as soluções acima não funcionarem:
1. Leia a Mensagem de Erro: A mensagem de erro do Docker geralmente contém
pistas importantes.
2. Verifique o Status do Docker: Olhe o ícone do Docker Desktop na bandeja do
sistema.
3. Consulte os Logs:
◦ Logs do Contêiner: docker logs <id_ou_nome_container>
◦ Logs do Daemon Docker: Docker Desktop > Settings > Troubleshoot > View
daemon logs.
4. Reinicie: Tente reiniciar o contêiner ( docker restart ), o Docker Desktop e o WSL
( wsl --shutdown ).
5. Simplifique: Tente reproduzir o erro com um comando ou Dockerfile mais simples
para isolar o problema.
6. Pesquise: Use a mensagem de erro exata para pesquisar em fóruns do Docker,
Stack Overflow ou GitHub Issues.
7. Limpeza: Remova contêineres, redes e volumes não utilizados com docker system
prune -a (use com cuidado).
Lidar com erros é uma parte essencial do trabalho com Docker. Com paciência e
seguindo estas etapas, a maioria dos problemas pode ser resolvida.
Referências
[7] Microsoft. "Troubleshooting Windows Subsystem for Linux". Microsoft Learn.
Acessado em 02 de junho de 2025. [Link]
troubleshooting