Pular para o conteúdo
~/buildbase $ 06/11/2026
Sistemas

O que é Docker e por que ele acabou com o ‘na minha máquina funciona’

Contêineres empilhados em um porto ao pôr do sol

Docker é uma ferramenta que coloca dentro de um único pacote o seu código e o ambiente inteiro que ele exige (versão da linguagem, bibliotecas, dependências do sistema, configuração) num pacote chamado imagem. Essa imagem se comporta igual em qualquer computador com Docker instalado, seja o seu, o da equipe ou o de produção, rodando como um container. É por isso que ele acabou com o “na minha máquina funciona”: a máquina passa a ir junto com o código.

$ ls ./neste-artigo
  1. Imagem, container e Dockerfile sem confusão
  2. Etapa 1: instalar e rodar o primeiro container
  3. Etapa 2: subir um serviço pronto sem instalar nada
  4. Etapa 3: escrever o Dockerfile do seu projeto
  5. Etapa 4: construir a imagem e rodar o container
  6. Etapa 5: juntar aplicação e banco com Docker Compose
  7. Docker no dia a dia: três dúvidas de quem acabou de instalar
  8. Um Dockerfile no portfólio diz muito sobre você

O problema que ele resolve é velho. Você usa Python 3.12, o servidor tem 3.9. Seu colega no Windows não consegue instalar a biblioteca de PDF que no seu Linux instalou de primeira. O projeto precisa de PostgreSQL 16 e Redis, e cada pessoa nova no time perde um dia configurando tudo. Com Docker, quem chega roda um comando e tem o ambiente inteiro de pé.

Abaixo está o caminho prático, do primeiro comando até um projeto com banco de dados, apontando onde iniciantes costumam travar em cada etapa.

 

Imagem, container e Dockerfile sem confusão

Três palavras resolvem 90% da confusão inicial:

  • Dockerfile: a receita. Um arquivo de texto com as instruções para montar a imagem.
  • Imagem: o bolo pronto e congelado. Um pacote somente leitura, feito em camadas, gerado a partir do Dockerfile.
  • Container: a fatia servida. Uma instância da imagem em execução. Da mesma imagem você pode rodar dez containers.

E não, container não é uma máquina virtual. A VM emula um computador inteiro com seu próprio sistema operacional, gigabytes de disco e minutos para ligar. O container compartilha o kernel do sistema hospedeiro e isola só os processos, arquivos e rede, e é por isso que liga quase instantaneamente e cabe em poucas dezenas ou centenas de MB. O resumo da arquitetura na documentação do Docker mostra essa arquitetura com o cliente, o daemon e os registros de imagens.

Pátio com contêineres de carga empilhados
A analogia com o contêiner de navio é literal: um formato padrão que qualquer porto sabe carregar, seja qual for a carga. Foto: Sebastian Herrmann / Unsplash

 
 

Etapa 1: instalar e rodar o primeiro container

No Windows e no Mac, instale o Docker Desktop. No Windows, ele usa o WSL 2, então ative-o antes. No Linux, instale o Docker Engine pelo repositório oficial da sua distribuição. Depois, no terminal:

docker run hello-world

Esse comando procura a imagem hello-world no seu computador, não encontra, baixa do Docker Hub, cria um container e o executa. Se aparecer a mensagem de boas-vindas, está tudo certo.

Tropeço comum aqui: no Linux, o erro “permission denied” ao acessar o socket do Docker significa que seu usuário não está no grupo docker. No Windows, a mensagem de que o daemon não está rodando quase sempre é o Docker Desktop fechado ou o WSL 2 desativado.

 

Etapa 2: subir um serviço pronto sem instalar nada

Antes de escrever seu próprio Dockerfile, use imagens oficiais. Precisa de um PostgreSQL para estudar?

docker run --name banco-estudo -e POSTGRES_PASSWORD=senha123 -p 5432:5432 -d postgres:16

Em segundos você tem um PostgreSQL 16 ouvindo na porta 5432, sem instalador e sem bagunçar o sistema. Alguns comandos que você vai usar o tempo todo:

ComandoO que faz
docker psLista containers em execução (-a mostra também os parados)
docker logs banco-estudoMostra a saída do container, primeiro lugar a olhar quando algo falha
docker exec -it banco-estudo bashAbre um terminal dentro do container
docker stop banco-estudoPara o container
docker rm banco-estudoRemove o container parado
docker imagesLista as imagens baixadas

Atenção às portas: o -p 5432:5432 liga a porta da sua máquina (à esquerda) à porta do container (à direita). Se você já tem um PostgreSQL instalado usando a 5432, o comando falha com “port is already allocated”. Troque para -p 5433:5432. E atenção: ao remover o container, os dados vão junto, a menos que você use um volume (etapa 5).

 

Etapa 3: escrever o Dockerfile do seu projeto

Para uma API simples em Python com Flask:

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["flask", "run", "--host=0.0.0.0"]

Linha a linha: parte de uma imagem oficial enxuta de Python, define a pasta de trabalho, copia primeiro só a lista de dependências, instala, depois copia o resto do código e define o comando de início.

Detalhe que muda o tempo de build: a ordem das linhas importa. Cada instrução vira uma camada, e o Docker reaproveita camadas que não mudaram. Copiando o requirements.txt antes do código, a instalação de dependências só se repete quando a lista muda, e não a cada vírgula alterada no código. O guia de boas práticas para Dockerfile detalha essa e outras otimizações. Crie também um arquivo .dockerignore com .git, .env, venv e __pycache__, para não mandar lixo (nem senhas) para dentro da imagem.

 

Etapa 4: construir a imagem e rodar o container

docker build -t minha-api .
docker run -p 5000:5000 minha-api

O ponto no final do build é o contexto, a pasta enviada ao Docker. Abra http://localhost:5000 e a API responde.

O clássico da primeira vez: a aplicação sobe, mas o navegador não conecta. Em 9 de 10 casos, o servidor está ouvindo em 127.0.0.1 dentro do container, que só aceita conexões vindas dele mesmo. Por isso o –host=0.0.0.0 no Flask (e o equivalente em Node, Django ou Rails).

Guindaste sobre pilha de contêineres em um porto
Uma vez construída, a imagem pode ser enviada a um registro e baixada em qualquer servidor. Foto: taro ohtani / Unsplash

 
 

Etapa 5: juntar aplicação e banco com Docker Compose

Projetos reais têm vários serviços. Em vez de vários docker run compridos, descreva tudo num compose.yaml:

services:
  api:
    build: .
    ports:
      - "5000:5000"
    environment:
      DATABASE_URL: postgresql://postgres:senha123@db:5432/postgres
    depends_on:
      - db
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: senha123
    volumes:
      - dados:/var/lib/postgresql/data
volumes:
  dados:

Um docker compose up sobe os dois; docker compose down derruba. Repare que a API acessa o banco pelo nome db, e não por localhost: dentro da rede do Compose, cada serviço é encontrado pelo nome. Esse é o erro número um de quem monta o primeiro Compose. O volume dados garante que o banco sobreviva quando os containers forem recriados.

 

Docker no dia a dia: três dúvidas de quem acabou de instalar

  1. Meu disco encheu, o que aconteceu? Imagens, containers parados e camadas antigas se acumulam. O comando docker system prune remove o que não está em uso; com -a, apaga também imagens sem container, então use com calma.
  2. Alterei o código e nada mudou no container. A imagem é uma foto do momento do build. Rode docker compose up –build ou, em desenvolvimento, monte a pasta do projeto como volume para ver as mudanças na hora.
  3. Posso colocar a senha do banco no Dockerfile? Não. Tudo que entra na imagem fica gravado nas camadas e pode ser lido por quem tiver a imagem. Use variáveis de ambiente, um arquivo .env fora do controle de versão ou o gerenciador de segredos da plataforma.

 

Um Dockerfile no portfólio diz muito sobre você

Coloque um Dockerfile e um compose.yaml no próximo projeto de portfólio e escreva no README que basta rodar docker compose up. Para quem avalia, isso mostra que você pensa em quem vai usar seu código depois. É também o primeiro passo para pipelines de deploy e para Kubernetes, temas que você encontra, junto com container, imagem e volume, no glossário de programação. Se a sua máquina sofre com vários containers abertos, o texto sobre o que não pode faltar num notebook seminovo para programar ajuda a dimensionar memória e disco.