Docker: Guia Completo Para Iniciantes em 2026
Fonte: Unsplash
Funciona na sua máquina, não funciona na do colega. Essa frase resume a maior parte da frustração de quem está começando a desenvolver em equipe — e é exatamente o problema que o Docker resolve. Em vez de você tentar descrever como configurar o ambiente, você empacota o ambiente inteiro e manda junto com o código.
Este guia é do zero absoluto: instalar, rodar o primeiro container, entender a diferença entre imagem e container, escrever um Dockerfile, expor porta, guardar dado com volume e subir um projeto inteiro com docker-compose. Sem atalho e sem termo sem explicação.
Instalando na sua máquina
No Windows e no macOS, o caminho mais simples é o Docker Desktop: baixa o instalador do site oficial, instala e abre. No Linux, você instala o motor do Docker pelo gerenciador de pacotes da sua distribuição e adiciona seu usuário ao grupo do Docker, para não precisar de sudo em cada comando.
# Debian / Ubuntu (via repositório oficial do Docker)
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
-o /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# rode SEM sudo (adiciona você ao grupo docker)
sudo usermod -aG docker $USER
newgrp docker
# confira se está de pé
docker version
docker run hello-world
Se a linha hello-world imprimir a mensagem de boas-vindas, está tudo certo: você já baixou uma imagem e executou um container. Já vale como marco zero.
Imagem e container: a diferença que trava todo iniciante
Guarde esta analogia: imagem é a receita, container é o bolo.
- Imagem — pacote somente leitura com sistema base, bibliotecas e seu código. Fica parada no seu disco.
- Container — instância rodando daquela imagem. Você pode criar vários containers da mesma imagem ao mesmo tempo.
- Registro — onde as imagens ficam armazenadas para distribuição. O mais conhecido é o Docker Hub.
Comandos que você vai usar o tempo todo:
docker images # lista imagens locais
docker ps # containers rodando agora
docker ps -a # todos, inclusive os parados
docker stop # para um container
docker rm # remove o container
docker rmi # remove a imagem
docker logs -f # acompanha os logs em tempo real
docker exec -it bash # entra dentro do container
Experimente rodar um terminal interativo num container base e sair depois:
docker run -it ubuntu:22.04 bash
# dentro: apt-get update && cat /etc/os-release
# saia com: exit
Seu primeiro Dockerfile
Na raiz do projeto, crie um arquivo chamado Dockerfile (sem extensão). Abaixo, um exemplo para uma API Python simples:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "app.py"]
O que cada linha faz, na ordem:
- FROM — define a base. Usar a variante
slimmantém a imagem menor. - WORKDIR — pasta de trabalho dentro do container; comandos seguintes rodam ali.
- COPY requirements.txt . — traz só o arquivo de dependências primeiro. Isso é intencional: enquanto seu código muda, a camada de instalação não reexecuta e o build fica rápido.
- RUN pip install — instala as dependências dentro da imagem.
- COPY . . — traz o restante do código.
- EXPOSE — documenta a porta; sozinho, não abre nada para fora.
- CMD — comando padrão executado quando o container sobe.
Build e execução:
docker build -t minha-api .
docker run --name api -p 8000:8000 minha-api
Agora abra http://localhost:8000 no navegador.
Portas: por que dois números?
No -p 8000:8000 existem dois números, e a ordem importa. Formato: -p <host>:<container>.
- Esquerda — porta na sua máquina, a que você digita no navegador.
- Direita — porta dentro do container, onde a aplicação realmente escuta.
Quer chamar outra porta externa? -p 9090:8000 basta: de fora você acessa 9090, por dentro continua 8000. Erro comum de iniciante é exatamente inverter essa ordem e achar que a porta "não funciona".
Volumes: parar de perder dado a cada container novo
Container é descartável. Quando você remove um container, tudo que foi gravado dentro dele junto com ele. Dado de banco, arquivo enviado, log que precisa persistir — tudo isso deve ficar fora do container.
# volume nomeado (recomendado)
docker volume create dados-pg
docker run --name pg -e POSTGRES_SECRET=senha123 \
-v dados-pg:/var/lib/postgresql/data -p 5432:5432 postgres:16
# bind mount: aponta uma pasta da SUA máquina
docker run --name app -v $(pwd)/src:/app/src -p 3000:3000 minha-api
Volume nomeado fica gerenciado pelo próprio Docker. Bind mount é útil em desenvolvimento, porque cada alteração no arquivo aparece no container na hora, sem novo build.
docker-compose: subir o projeto inteiro de uma vez
Aplicação + banco + cache = três containers. Rodar três comandos separados toda vez cansa. O docker-compose.yaml resolve:
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: senha123
POSTGRES_DB: appdb
volumes:
- dados-pg:/var/lib/postgresql/data
ports:
- "5432:5432"
api:
build: .
environment:
DATABASE_URL: postgres://postgres:senha123@db:5432/appdb
ports:
- "8000:8000"
depends_on:
- db
volumes:
dados-pg:
E os comandos que você vai digitar no dia a dia:
docker compose up -d # sobe tudo em segundo plano
docker compose ps # quem está rodando
docker compose logs -f api # logs de um serviço
docker compose down # para e remove os containers
docker compose down -v # idem, apagando também os volumes
Repare num detalhe importante: dentro da rede do compose, o serviço se chama pelo nome do serviço. A API conecta em db:5432, não em localhost:5432 — porque localhost dentro do container é ele mesmo.
Erros de iniciante que dá para evitar já
- Imagem gigante — comece sempre pela variante
slimoualpinee evite instalar pacote que você não usa. - Build lento — copie dependências antes do código-fonte; isso mantém a camada de instalação em cache.
- Credencial no Dockerfile — senha e token entram por variável de ambiente, nunca escrito no repositório. Crie um
.dockerignoree coloque lá.env,.gite__pycache__. - Dado dentro do container — se não estiver em volume, você vai perder.
- Container como servidor de produção improvisado — subir container é rápido; manter com atualização, log e limite de recurso é outra conversa.
Quando essa base estiver no reflexo da mão, você já reduz o discurso de "na minha máquina funciona" a zero — e o próximo passo natural é publicar imagem em registro próprio e subir em algum serviço de orquestração.
E aí, fez sentido?
Conte nos comentários sua experiência com Docker para iniciantes — e se o artigo te ajudou, compartilhe com alguém que precisa ler. 👇