| Comando | O que faz |
|---|---|
docker run -d -p 8080:80 --name c nginx |
Criar e iniciar container |
docker ps / docker ps -a |
Listar containers rodando / todos |
docker stop / start / restart c |
Parar / iniciar / reiniciar container |
docker rm -f c |
Forçar remoção de container |
docker logs -f c |
Seguir logs em tempo real |
docker exec -it c bash |
Abrir terminal no container |
docker images |
Listar imagens locais |
docker pull nginx:alpine |
Baixar imagem do Docker Hub |
docker build -t app:1.0 . |
Construir imagem do Dockerfile |
docker rmi nginx |
Remover imagem |
docker volume ls / rm / prune |
Listar / remover / limpar volumes |
docker network ls / create / rm |
Gerenciar redes |
docker compose up -d |
Subir todos os serviços |
docker compose down |
Derrubar todos os serviços |
docker compose logs -f app |
Logs de um serviço |
docker compose exec db psql ... |
Executar comando em serviço |
docker system df |
Espaço usado pelo Docker |
docker system prune -a |
Limpeza geral |
Empacotador de aplicação
'Molde' de um container, define a estrutura uma vez e usa quantas vezes quiser facilmente (sem ter que construir) - armazena na sua máquina ou no hub.docker.com
Instância rodando uma imagem, o processo/execução no sistema (pode ter vários processos originários de uma mesma imagem) - não armazena os dados (quando desliga a máquina tudo se perde)
Arquivo que contém as instruções da construção da imagem, substitui a escrita/poluição no cmd
Onde persiste os dados em Docker, armazena os dados fora do container
| Tipo | Quando usar |
|---|---|
| Named Volume (recomendado) | Gerenciado pelo Docker. Fica em /var/lib/docker/volumes/. Melhor para bancos de dados. |
| Bind Mount | Conecta pasta específica do host ao container. Ideal para desenvolvimento (ver mudanças ao vivo). |
| tmpfs Mount | Armazenamento em memória RAM. Temporário, muito rápido. Para dados sensíveis em memória. |
# Criar um volume manualmente
docker volume create dados-postgres
# Listar volumes
docker volume ls
# Inspecionar um volume (ver localização física, etc)
docker volume inspect dados-postgres
# Usar o volume no container
docker run -d \
--name postgres \
-v dados-postgres:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=senha \
postgres:15
# Se remover e recriar o container, os dados persistem!
docker rm -f postgres
docker run -d \
--name postgres \
-v dados-postgres:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=senha \
postgres:15
# Os dados ainda estão lá!
# Remover um volume (CUIDADO: apaga os dados!)
docker volume rm dados-postgres
# Remover volumes não utilizados
docker volume prune
Ferramenta para gerir os containers, substitui o comando 'Docker run', escreve tudo em um arquivo YAML e sobe
Um arquivo Compose tem quatro seções principais: version, services, volumes e networks.
version: '3.8'
# ─── SERVIÇOS ─────────────────────────────────────────────────
services:
# Cada serviço é um container
nome-do-servico:
image: imagem:tag # OU
build: # Construir de um Dockerfile
context: . # Pasta com o Dockerfile
dockerfile: Dockerfile # Nome do arquivo (se não for 'Dockerfile')
container_name: meu-app # Nome fixo do container
ports:
- "HOST:CONTAINER" # Mapeamento de portas
environment: # Variáveis de ambiente
- VARIAVEL=valor
DATABASE_URL: postgres://user:senha@db/meudb
env_file: # Ou carrega de um arquivo .env
- .env
volumes: # Volumes e bind mounts
- dados-nomeados:/var/dados
- ./pasta-local:/app
depends_on: # Ordem de inicialização
db: # Aguarda 'db' ficar 'healthy'
condition: service_healthy
restart: unless-stopped # Política de reinício
networks: # Redes que participa
- minha-rede
healthcheck: # Verificação de saúde
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# ─── VOLUMES NOMEADOS ─────────────────────────────────────────
volumes:
dados-nomeados: # Volume gerenciado pelo Docker
outro-volume:
external: true # Volume criado externamente
# ─── REDES ────────────────────────────────────────────────────
networks:
minha-rede:
driver: bridge
# ─── SUBIR ────────────────────────────────────────────────────
# Subir todos os serviços em background
docker compose up -d
# Subir e reconstruir imagens (quando mudou Dockerfile/código)
docker compose up -d --build
# Subir apenas um serviço específico
docker compose up -d nome-do-servico
# ─── PARAR ────────────────────────────────────────────────────
# Para os containers (mantém volumes e networks)
docker compose stop
# Para e REMOVE containers e networks (volumes permanecem)
docker compose down
# Remove tudo incluindo volumes (CUIDADO: apaga dados!)
docker compose down -v
# ─── MONITORAR ────────────────────────────────────────────────
# Listar containers do projeto
docker compose ps
# Ver logs de todos os serviços
docker compose logs
# Seguir logs em tempo real
docker compose logs -f
# Logs de um serviço específico
docker compose logs -f app
# ─── EXECUTAR COMANDOS ────────────────────────────────────────
# Abrir terminal em um serviço
docker compose exec app bash
# Executar comando pontual
docker compose exec db psql -U usuario -d meudb
# Rodar um serviço one-off (sem iniciar outros)
docker compose run --rm app npm test
# ─── OUTROS ──────────────────────────────────────────────────
# Ver configuração final resolvida (variáveis substituídas)
docker compose config
# Rebuild de um serviço sem parar os outros
docker compose up -d --build app
# Escalar um serviço (criar múltiplas instâncias)
docker compose up -d --scale app=3
Baixa imagem, cria e inicia em um container
| Flag | O que faz |
|---|---|
-d (--detach) |
Roda em background. Sem isso, o terminal fica preso no container. |
-p HOST:CONTAINER |
Mapeia porta. Ex: -p 8080:80 — porta 8080 do seu PC entra na 80 do container. |
--name NOME |
Dá um nome ao container. Facilita referenciar depois. |
-e VAR=VALOR |
Define variável de ambiente dentro do container. Ex: -e POSTGRES_USER=meususuario -e POSTGRES_PASSWORD=minhasenha123
|
-v ORIGEM:DESTINO |
Monta um volume — conecta pasta do host com pasta do container. Ex: -v dados-postgres:/var/lib/postgresql/data
|
--rm |
Remove o container automaticamente quando ele parar. |
-it |
Modo interativo com terminal. Use para entrar no container. |
--network REDE |
Conecta o container a uma rede específica. |
--restart always |
Reinicia o container automaticamente se ele parar ou o host reiniciar. |
No fim do comando escreve a imagem que vai usar
# ─── LISTAR ───────────────────────────────────────────────────
docker ps # Containers em execução
docker ps -a # Todos os containers (incluindo parados)
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' # Formato personalizado/legível
# ─── INICIAR / PARAR ──────────────────────────────────────────
# Parar graciosamente (envia SIGTERM, aguarda 10s, depois SIGKILL)
docker stop meu-nginx
# Parar imediatamente (SIGKILL direto — use apenas se necessário)
docker kill meu-nginx
docker start meu-nginx # Iniciar container parado
docker restart meu-nginx # Reiniciar
# ─── REMOVER ──────────────────────────────────────────────────
docker rm meu-nginx # Remover container parado
docker rm -f meu-nginx # Forçar remoção de container rodando
docker container prune # Remover todos os containers parados de uma vez
# ─── LOGS ────────────────────────────────────────────────────
docker logs meu-nginx # Ver todos os logs
docker logs -f meu-nginx # Seguir logs em tempo real (como tail -f)
docker logs --tail 50 meu-nginx # Ver apenas as últimas 50 linhas
docker logs -t meu-nginx # Logs com timestamp
# ─── ENTRAR NO CONTAINER ──────────────────────────────────────
docker exec -it meu-nginx bash # Abrir terminal bash no container
docker exec -it meu-nginx sh # Se a imagem não tiver bash, tente sh
docker exec meu-nginx ls /var/www/html # Executar um comando pontual sem entrar
# ─── INSPECIONAR ──────────────────────────────────────────────
docker inspect meu-nginx # Informações detalhadas do container (JSON)
docker stats # Ver uso de CPU, memória e rede em tempo real
docker stats meu-nginx # Stats de um container específico
docker images # Listar imagens baixadas localmente
# Baixar imagem sem criar container
docker pull postgres:15
docker pull node:20-alpine
docker rmi nginx # Remover uma imagem
docker image prune # Remover imagens não utilizadas (dangling)
docker image prune -a # Remover TODAS as imagens não utilizadas por nenhum container
docker search postgres # Pesquisar imagem no Docker Hub via terminal
| Instrução | O que faz |
|---|---|
FROM imagem:tag |
Define a imagem base. Sempre a primeira instrução. |
WORKDIR /caminho |
Define o diretório de trabalho dentro do container. |
COPY origem destino |
Copia arquivos do host para o container. |
ADD origem destino |
Como COPY, mas suporta URLs e descompacta tar automaticamente. |
RUN comando |
Executa comando durante o BUILD da imagem (instalar pacotes, etc). |
CMD ["cmd", "arg"] |
Comando padrão ao iniciar o container. Pode ser sobrescrito. |
ENTRYPOINT ["cmd"] |
Ponto de entrada fixo do container. CMD vira argumentos dele. |
ENV VAR=VALOR |
Define variável de ambiente disponível em runtime. |
ARG VAR=VALOR |
Variável disponível APENAS no momento do build. |
EXPOSE porta |
Documenta qual porta o container vai usar (não abre automaticamente). |
VOLUME /caminho |
Declara um ponto de montagem de volume. |
USER usuario |
Define o usuário que roda os próximos comandos (segurança). |
# ─────────────────────────────────────────────────────────────
# ESTÁGIO 1: Instalação de dependências
# ─────────────────────────────────────────────────────────────
FROM node:20-alpine AS dependencies
# Instala dependências nativas se necessário
# (bcrypt, sharp e outros precisam de ferramentas de compilação)
RUN apk add --no-cache python3 make g++
WORKDIR /app
# Copia APENAS os arquivos de dependência primeiro
# Isso aproveita o cache do Docker:
# Se package.json não mudou, essa camada é reutilizada
COPY package.json package-lock.json ./
# Instala dependências de produção
RUN npm ci --only=production
# ─────────────────────────────────────────────────────────────
# ESTÁGIO 2: Imagem final (menor e mais segura)
# ─────────────────────────────────────────────────────────────
FROM node:20-alpine
# Cria usuário não-root para rodar a aplicação (segurança!)
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
# Copia node_modules do estágio anterior
COPY --from=dependencies /app/node_modules ./node_modules
# Copia o código da aplicação
COPY . .
# Altera dono dos arquivos para o usuário criado
RUN chown -R appuser:appgroup /app
# Troca para o usuário não-root
USER appuser
# Documenta a porta (boa prática, não obrigatório)
EXPOSE 3000
# Variáveis de ambiente com valores padrão
ENV NODE_ENV=production
ENV PORT=3000
# Verifica se a aplicação está saudável
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"
# Inicia a aplicação
CMD ["node", "src/server.js"]
docker build -t minha-app:1.0 . # Construir a imagem com a tag 'minha-app:1.0'
# O ponto (.) indica que o Dockerfile está na pasta atual
docker build -f caminho/Dockerfile -t minha-app . # Para usar um Dockerfile em outro lugar
docker history minha-app:1.0 # Ver as camadas e tamanho da imagem construída
# ─── Publicar no Docker Hub ───────────────────────────────────
docker login # Faça login no Docker Hub
docker tag minha-app:1.0 seuusuario/minha-app:1.0 # Taguear a imagem com seu usuário Docker Hub
docker push seuusuario/minha-app:1.0 # Enviar para o Docker Hub
Bind mounts são indispensáveis no desenvolvimento. Eles espelham sua pasta local dentro do container — qualquer alteração no código é refletida imediatamente no container, sem precisar reconstruir a imagem.
# Montar a pasta atual dentro do container
docker run -d \
--name app-dev \
-p 3000:3000 \
-v $(pwd):/app \
-v /app/node_modules \
node:20-alpine \
sh -c 'npm install && npm run dev'
# O que aconteceu:
# -v $(pwd):/app = pasta atual do host mapeada para /app no container
# -v /app/node_modules = volume anônimo para node_modules (não sobrescreve!)
# No Windows PowerShell, use ${PWD} no lugar de $(pwd)
docker run -v ${PWD}:/app ...
meu-projeto/
├── src/
│ └── server.js
├── Dockerfile
├── docker-compose.yml
├── docker-compose.override.yml # Sobrescreve configs para dev
├── .dockerignore
├── .env # Variáveis (não versionar!)
├── .env.example # Template (versionar)
└── package.json
# .env — NÃO commite esse arquivo no git!
# Adicione .env no .gitignore
# Aplicação
NODE_ENV=development
PORT=3000
APP_SECRET=sua-chave-secreta-aqui
# PostgreSQL
POSTGRES_USER=appuser
POSTGRES_PASSWORD=senhasegura123
POSTGRES_DB=meuapp
DATABASE_URL=postgresql://appuser:senhasegura123@db:5432/meuapp
# Redis
REDIS_URL=redis://redis:6379
# .dockerignore — equivalente ao .gitignore para Docker
# Evita copiar arquivos desnecessários para a imagem
node_modules
.git
.gitignore
.env
.env.*
*.log
docker-compose*.yml
README.md
.DS_Store
coverage/
.nyc_output/
dist/ # Ou build/ — será compilado dentro do container
version: '3.8'
services:
# ─── APLICAÇÃO ───────────────────────────────────────────────
app:
build:
context: .
dockerfile: Dockerfile
target: production # Estágio do multi-stage build
ports:
- "${PORT:-3000}:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=${DATABASE_URL}
- REDIS_URL=${REDIS_URL}
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
networks:
- app-net
# ─── BANCO DE DADOS ──────────────────────────────────────────
db:
image: postgres:15-alpine
env_file: .env
volumes:
- postgres-data:/var/lib/postgresql/data
- ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
networks:
- app-net
# ─── CACHE ───────────────────────────────────────────────────
redis:
image: redis:7-alpine
command: redis-server --appendonly yes --maxmemory 256mb
volumes:
- redis-data:/data
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-net
# ─── PROXY REVERSO ───────────────────────────────────────────
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- certbot-data:/etc/letsencrypt
depends_on:
- app
restart: unless-stopped
networks:
- app-net
volumes:
postgres-data:
redis-data:
certbot-data:
networks:
app-net:
driver: bridge
O Docker Compose mescla automaticamente o arquivo override com o principal. Use isso para manter configurações de dev separadas sem modificar o arquivo de produção.
# docker-compose.override.yml
# Este arquivo é mesclado AUTOMATICAMENTE com docker-compose.yml
# Use para configs de desenvolvimento
version: '3.8'
services:
app:
build:
target: development # Usa estágio dev do Dockerfile
volumes:
- .:/app # Bind mount para hot reload
- /app/node_modules # Preserva node_modules do container
environment:
- NODE_ENV=development
command: npm run dev # Sobrescreve CMD do Dockerfile
db:
ports:
- "5432:5432" # Expõe porta para conectar externamente
redis:
ports:
- "6379:6379"