Objetivo
Criar um laboratório que reúna:
- aplicação web;
- banco PostgreSQL;
- rede;
- volume;
- variáveis de ambiente;
- Docker Compose;
- healthcheck;
- logs;
- troubleshooting.
Arquitetura
Navegador
│
│ :8080
▼
Nginx
│
▼
Rede frontend
Aplicação / serviços
│
▼
Rede backend
│
▼
PostgreSQL
│
▼
Volume db-data
Para o laboratório inicial utilizaremos Nginx e PostgreSQL como serviços independentes para focar na infraestrutura Docker.
Crie:
mkdir -p ~/docker-labs/projeto-final/site
cd ~/docker-labs/projeto-final
Crie site/index.html:
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Projeto Final Docker</title>
</head>
<body>
<h1>Projeto Final Docker</h1>
<p>Nginx executando através do Docker Compose.</p>
</body>
</html>
Crie .env:
POSTGRES_USER=lab
POSTGRES_PASSWORD=troque_esta_senha
POSTGRES_DB=laboratorio
Crie compose.yaml:
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./site:/usr/share/nginx/html:ro
networks:
- frontend
restart: unless-stopped
db:
image: postgres
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- db-data:/var/lib/postgresql/data
networks:
- backend
healthcheck:
test:
[
"CMD-SHELL",
"pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"
]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
db-data:
networks:
frontend:
backend:
Validar o Compose
docker compose config
Subir
docker compose up -d
Estado
docker compose ps
Testar site
curl localhost:8080
Logs
docker compose logs
Logs do banco:
docker compose logs db
Logs em tempo real:
docker compose logs -f
Entrar no banco
docker compose exec db \
psql -U "$POSTGRES_USER" -d "$POSTGRES_DB"
Se as variáveis não estiverem disponíveis no seu shell, use os valores definidos no .env.
Derrubar a aplicação
docker compose down
Os containers e redes do projeto serão removidos.
O volume continuará existindo.
Verifique:
docker volume ls
Suba novamente:
docker compose up -d
Os dados persistem.
Remover inclusive volumes
Atenção
O comando abaixo apaga os volumes do projeto e, portanto, os dados persistentes.
docker compose down -v
Use somente quando você realmente quiser apagar o laboratório.
Desafio final
Monte sozinho um ambiente com:
1 servidor Nginx
1 PostgreSQL
2 redes
1 volume persistente
1 arquivo .env
1 compose.yaml
Requisitos:
- Nginx deve responder em
localhost:8080. - PostgreSQL não precisa publicar a porta 5432 para o host.
- O banco deve utilizar um volume nomeado.
- As credenciais devem ficar fora do
compose.yaml. - Todos os containers devem ser administrados pelo Compose.
- Você deve conseguir identificar erros através de logs.
- Os dados do banco devem sobreviver a
docker compose down.
Checklist de domínio
Fundamentos
- Explico imagem x container.
- Explico container x VM.
- Entendo Docker CLI e daemon.
- Sei o que é registry.
Containers
-
docker run -
docker ps -
docker stop -
docker start -
docker restart -
docker rm -
docker exec -
docker logs -
docker inspect
Imagens
-
docker pull -
docker images -
docker rmi -
docker build -
docker tag - Entendo tags e camadas.
Rede
- Publico portas.
- Crio redes.
- Conecto containers.
- Entendo resolução por nome.
Armazenamento
- Crio volumes.
- Uso bind mounts.
- Sei quando os dados são descartados.
- Sei preservar dados.
Dockerfile
-
FROM -
RUN -
COPY -
WORKDIR -
ENV -
EXPOSE -
USER -
CMD -
ENTRYPOINT
Compose
- Crio
compose.yaml. - Defino services.
- Defino ports.
- Defino volumes.
- Defino networks.
- Uso variáveis.
- Uso healthcheck.
- Administro o ciclo de vida do projeto.
Comandos de referência rápida
# Versão e informações
docker version
docker info
# Containers
docker ps
docker ps -a
docker run IMAGE
docker start CONTAINER
docker stop CONTAINER
docker restart CONTAINER
docker rm CONTAINER
docker exec -it CONTAINER bash
docker logs CONTAINER
docker inspect CONTAINER
# Imagens
docker images
docker pull IMAGE
docker build -t IMAGE:TAG .
docker rmi IMAGE
docker history IMAGE
# Volumes
docker volume ls
docker volume create NOME
docker volume inspect NOME
docker volume rm NOME
# Redes
docker network ls
docker network create NOME
docker network inspect NOME
docker network connect REDE CONTAINER
docker network disconnect REDE CONTAINER
# Recursos
docker stats
docker top CONTAINER
docker system df
# Compose
docker compose config
docker compose up -d
docker compose ps
docker compose logs
docker compose logs -f
docker compose exec SERVICO COMANDO
docker compose restart
docker compose down
Exercícios extras
Exercício 1
Crie um container Alpine e imprima:
Meu primeiro laboratorio
sem entrar interativamente no container.
Exercício 2
Crie um Nginx chamado web-lab publicado na porta 9090.
Exercício 3
Descubra o endereço IP interno do container web-lab.
Exercício 4
Crie uma rede chamada rede-lab.
Exercício 5
Conecte dois containers à mesma rede e teste comunicação por nome.
Exercício 6
Crie um volume chamado dados-lab.
Exercício 7
Grave um arquivo no volume, remova o container e confirme a persistência.
Exercício 8
Crie sua própria imagem Nginx contendo uma página HTML.
Exercício 9
Crie versões 1.0 e 2.0 da sua imagem.
Exercício 10
Transforme seu laboratório de Nginx em um projeto Docker Compose.
Troubleshooting — roteiro de diagnóstico
Quando um container não funcionar, evite sair apagando e recriando tudo.
Siga uma sequência.
1. O container existe?
docker ps -a
2. Qual é o estado?
docker inspect CONTAINER
3. O que os logs dizem?
docker logs CONTAINER
4. A porta foi publicada?
docker port CONTAINER
5. Existe processo ouvindo no host?
ss -lntp
6. A rede está correta?
docker network inspect REDE
7. O volume está montado?
docker inspect CONTAINER
8. A aplicação está rodando dentro do container?
docker top CONTAINER
9. O container está sem memória?
docker stats
Esse método é muito mais útil profissionalmente do que simplesmente memorizar comandos.
Prática recomendada
Repita os laboratórios sem copiar os comandos.
Uma boa sequência é:
- leia a explicação;
- execute o laboratório;
- destrua o ambiente;
- tente recriá-lo de memória;
- provoque um erro;
- diagnostique o erro;
- documente o que aconteceu.
Esse processo transforma comandos memorizados em conhecimento operacional.
Próximos passos após este curso
Depois de dominar este conteúdo, siga para:
- Dockerfile avançado;
- multi-stage builds;
- healthchecks avançados;
- secrets;
- reverse proxy;
- TLS/HTTPS;
- Docker Registry;
- GitHub Container Registry;
- CI/CD;
- backups de volumes;
- monitoramento;
- rootless Docker;
- hardening;
- Kubernetes.
Referências oficiais
- Docker Overview: https://docs.docker.com/get-started/docker-overview/
- Docker Engine: https://docs.docker.com/engine/
- Dockerfile: https://docs.docker.com/reference/dockerfile/
- Build best practices: https://docs.docker.com/build/building/best-practices/
- Volumes: https://docs.docker.com/engine/storage/volumes/
- Networking: https://docs.docker.com/engine/network/
- Docker Compose: https://docs.docker.com/compose/
- Compose Specification: https://docs.docker.com/reference/compose-file/
Resultado esperado
Ao concluir o curso, você não deve apenas saber executar:
docker run
Você deve conseguir olhar para uma aplicação e raciocinar:
Qual imagem vou usar?
│
Qual processo ficará dentro do container?
│
Preciso publicar portas?
│
Existem dados persistentes?
│
Preciso de volume?
│
Quais containers precisam conversar?
│
Quais redes devo criar?
│
Quais configurações devem ficar fora da imagem?
│
Como vou diagnosticar uma falha?
│
Como vou reproduzir tudo usando Compose?
Esse é o ponto em que Docker deixa de ser apenas um conjunto de comandos e passa a ser uma ferramenta de infraestrutura.
