O artigo anterior explicou o que são containers e por que eles existem. Este artigo é inteiramente prático: instalar o Docker, entender os primeiros comandos e desenvolver fluência no ciclo de vida de um container — criar, inspecionar, parar, remover.
Ao final deste artigo, rodar um servidor web completo em um container será algo tão natural quanto abrir um arquivo de texto.
Instalando o Docker
No Ubuntu e distribuições baseadas em Debian:
A forma recomendada é usar o repositório oficial do Docker, não o pacote do apt padrão — que frequentemente está desatualizado:
# Remove versões antigas, se existirem
sudo apt remove docker docker-engine docker.io containerd runc
# Instala dependências
sudo apt update
sudo apt install ca-certificates curl gnupg
# Adiciona a chave GPG oficial do Docker
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Adiciona o repositório oficial
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Instala o Docker Engine
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Permitindo rodar Docker sem sudo:
Por padrão, o Docker requer privilégios de root. Para usar sem sudo, adiciona-se o usuário ao grupo docker:
sudo usermod -aG docker $USER
newgrp docker
É necessário fazer logout e login novamente para que a mudança de grupo tenha efeito completo.
Verificando a instalação:
docker version
docker info
O docker version mostra as versões do cliente e do daemon. O docker info exibe informações detalhadas sobre o ambiente — número de containers, imagens, configurações de rede e storage driver.
O Primeiro Container
docker run hello-world
O que acontece nessa sequência quando esse comando é executado:
O Docker verifica se a imagem hello-world existe localmente. Não existe na primeira vez, então ele a baixa do Docker Hub. Em seguida, cria um container a partir dessa imagem, executa o processo definido nela — que imprime uma mensagem explicativa — e encerra o container logo após.
A saída confirma que a instalação está funcionando e o Docker consegue se comunicar com o Docker Hub.
Rodando Containers Interativos
Para explorar um container Ubuntu como se fosse uma máquina Linux completa:
docker run -it ubuntu:22.04 bash
O flag -i mantém o stdin aberto (interativo). O flag -t aloca um pseudo-terminal. Juntos, permitem que se use o container como um terminal interativo.
Dentro do container, é possível executar qualquer comando Linux:
cat /etc/os-release
apt update && apt install -y curl
curl --version
exit
Ao sair com exit, o container para. Ele não é removido automaticamente — apenas para.
O Ciclo de Vida de um Container
# Lista containers em execução
docker ps
# Lista todos os containers, incluindo os parados
docker ps -a
# Inicia um container parado
docker start <container_id ou nome>
# Para um container em execução
docker stop <container_id ou nome>
# Remove um container parado
docker rm <container_id ou nome>
# Para e remove em um único comando
docker rm -f <container_id ou nome>
Os containers podem ser referenciados pelo ID completo, pelos primeiros caracteres do ID (o suficiente para ser único) ou pelo nome. Se nenhum nome for especificado no docker run, o Docker gera um nome aleatório — sempre composto por um adjetivo e o nome de um cientista famoso, como suspicious_turing ou friendly_curie.
Para nomear um container explicitamente:
docker run --name meu-ubuntu -it ubuntu:22.04 bash
Rodando um Servidor Web
Um dos casos de uso mais comuns: rodar um Nginx em um container e acessá-lo pelo navegador.
docker run -d -p 8080:80 --name servidor-web nginx:alpine
Três flags importantes aqui:
-d (detached) — executa o container em segundo plano, liberando o terminal.
-p 8080:80 — mapeia a porta 8080 do host para a porta 80 do container. O formato é sempre porta-do-host:porta-do-container. Qualquer requisição que chegar na porta 8080 da máquina local será redirecionada para a porta 80 dentro do container.
--name servidor-web — nomeia o container para facilitar referências futuras.
Verificando se está funcionando:
curl http://localhost:8080
Ou simplesmente abrindo http://localhost:8080 no navegador. A página de boas-vindas do Nginx confirma que o container está respondendo.
Inspecionando Containers em Execução
# Logs do container — equivalente ao tail do arquivo de log
docker logs servidor-web
# Logs em tempo real
docker logs -f servidor-web
# Estatísticas de uso de recursos em tempo real
docker stats servidor-web
# Informações detalhadas em JSON
docker inspect servidor-web
# Executa um comando dentro de um container em execução
docker exec -it servidor-web sh
O docker exec é extremamente útil para depuração: permite entrar em um container que já está rodando sem interrompê-lo. Isso é diferente do docker run, que cria um novo container — o exec entra no container existente.
Dentro do container Nginx, é possível inspecionar os arquivos de configuração:
cat /etc/nginx/nginx.conf
ls /usr/share/nginx/html
exit
Gerenciando Imagens
# Lista imagens locais
docker images
# Baixa uma imagem sem criar um container
docker pull postgres:16
# Remove uma imagem
docker rmi nginx:alpine
# Remove imagens, containers parados e cache não utilizados
docker system prune
# Remove tudo, incluindo imagens não utilizadas
docker system prune -a
O docker system prune é útil para liberar espaço em disco, especialmente em máquinas de desenvolvimento onde muitas imagens se acumulam. Em servidores de produção, deve ser usado com cautela — imagens que parecem não utilizadas podem ser necessárias para reiniciar containers.
Passando Variáveis de Ambiente
A maioria das imagens oficiais é configurada via variáveis de ambiente. O PostgreSQL, por exemplo:
docker run -d \
--name banco-dados \
-e POSTGRES_USER=devops \
-e POSTGRES_PASSWORD=senha123 \
-e POSTGRES_DB=minha_app \
-p 5432:5432 \
postgres:16
O flag -e define variáveis de ambiente dentro do container. Para verificar que o banco subiu corretamente:
docker logs banco-dados
# Conectando ao banco de dentro do container
docker exec -it banco-dados psql -U devops -d minha_app
Um Fluxo Completo de Trabalho
Reunindo os comandos em um cenário realista — subir um ambiente de desenvolvimento com Nginx e PostgreSQL, inspecionar, e depois limpar tudo:
# Sobe os serviços
docker run -d --name web -p 8080:80 nginx:alpine
docker run -d --name db -e POSTGRES_PASSWORD=senha123 -p 5432:5432 postgres:16
# Verifica o que está rodando
docker ps
# Inspeciona logs
docker logs web
docker logs db
# Testa o Nginx
curl http://localhost:8080
# Para tudo
docker stop web db
# Remove os containers
docker rm web db
# Verifica que não sobrou nada
docker ps -a
O Que Vem a Seguir
Até aqui foram usadas imagens prontas do Docker Hub. No próximo artigo será abordado o Dockerfile — o arquivo que descreve como construir uma imagem customizada para uma aplicação própria. É o passo que transforma o Docker de uma ferramenta de consumo em uma ferramenta de construção.
Referências para Aprofundamento
Documentação oficial
- Install Docker Engine on Ubuntu — docs.docker.com — Guia oficial de instalação do Docker no Ubuntu, sempre atualizado com o método recomendado.
- Docker CLI Reference — docs.docker.com — Referência completa de todos os comandos do Docker CLI, com exemplos e opções.
Prática
- Play with Docker — Ambiente Docker gratuito no navegador. Permite praticar todos os comandos deste artigo sem instalar nada localmente.
- Docker Getting Started Tutorial — docs.docker.com — Tutorial oficial progressivo do Docker. Os primeiros três passos cobrem exatamente o conteúdo deste artigo.
Leitura complementar
- Docker Hub — hub.docker.com — O registro público de imagens. Vale explorar as imagens oficiais do Nginx, PostgreSQL e Ubuntu para entender como são documentadas e quais variáveis de ambiente aceitam.