Docker para iniciantes: guia completo do zero ao primeiro container

Docker para iniciantes: guia completo do zero ao primeiro container

Se você já ouviu a frase “na minha máquina funciona”, sabe exatamente o problema que o Docker resolve. Este guia de Docker para iniciantes foi escrito para quem nunca rodou um container na vida: vamos começar pelos conceitos, instalar a ferramenta, executar os primeiros comandos e terminar criando uma imagem própria de uma aplicação Node.js — tudo com prints de cada etapa.

Ao final, você vai entender a diferença entre imagem e container, saber ler a saída do docker ps, publicar portas, ver logs, e ter um Dockerfile funcional que pode reaproveitar nos seus projetos.

O que é Docker e por que ele existe

Docker é uma plataforma que empacota uma aplicação junto com tudo o que ela precisa para rodar — sistema base, bibliotecas, runtime da linguagem, dependências e configurações — em uma unidade padronizada chamada container. Esse container roda do mesmo jeito no seu notebook, no computador do colega e no servidor de produção.

Antes do Docker, era comum cada ambiente ter uma versão diferente do PHP, do Node.js ou do banco de dados. Um sistema funcionava no computador do desenvolvedor e quebrava no servidor porque faltava uma extensão, porque a versão da biblioteca era outra ou porque uma variável de ambiente não existia. O Docker elimina boa parte dessa loteria: o ambiente passa a ser descrito em código e reproduzido de forma idêntica.

Container não é máquina virtual

Uma confusão comum de quem está começando é achar que container é uma máquina virtual mais leve. A ideia é parecida, mas o funcionamento é diferente:

  • Máquina virtual (VM) emula um computador inteiro, com um sistema operacional completo rodando por cima de um hypervisor. Ela consome gigabytes de disco e leva minutos para iniciar.
  • Container compartilha o kernel do sistema hospedeiro e isola apenas os processos, a rede e o sistema de arquivos da aplicação. Ele ocupa megabytes e sobe em segundos (às vezes em milissegundos).

Na prática, isso significa que você consegue rodar dezenas de containers em um notebook comum, algo impensável com VMs.

Conceitos essenciais: imagem, container, registry e volume

Antes de digitar qualquer comando, vale fixar quatro palavras que vão aparecer o tempo todo:

Conceito O que é Analogia
Imagem Um pacote somente leitura com o sistema base, dependências e o código da aplicação A receita de um bolo
Container Uma instância em execução de uma imagem O bolo pronto, saído do forno
Registry Um repositório de imagens, como o Docker Hub O livro de receitas compartilhado
Volume Um espaço de armazenamento que sobrevive quando o container é removido A geladeira onde você guarda o que sobrou

Uma mesma imagem pode gerar vários containers ao mesmo tempo, assim como uma receita pode gerar vários bolos. E, importante: containers são descartáveis. Qualquer arquivo gravado dentro de um container é perdido quando ele é removido — a não ser que esteja em um volume.

Como instalar o Docker

A instalação muda conforme o sistema operacional. Os caminhos oficiais são:

  • Windows: instale o Docker Desktop. Ele usa o WSL 2 por baixo dos panos, então ative o WSL antes (wsl --install no PowerShell como administrador) e reinicie o computador.
  • macOS: baixe o Docker Desktop para a arquitetura do seu Mac (Apple Silicon ou Intel) e arraste para a pasta Aplicativos.
  • Linux (Ubuntu/Debian): o caminho mais rápido é o script oficial de conveniência.

No Linux, os comandos são:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Permite usar o docker sem sudo (faça logout e login depois)
sudo usermod -aG docker $USER

Verificando se a instalação funcionou

Abra um terminal e rode docker --version. Se aparecer a versão, o cliente está instalado. Para confirmar que o daemon (o serviço que realmente executa os containers) está no ar, use docker info:

Terminal mostrando docker --version e docker info no Docker para iniciantes
Saída do docker –version e do docker info confirmando a instalação

Se o docker info retornar um erro como Cannot connect to the Docker daemon, o serviço não está rodando. No Windows e no Mac, abra o Docker Desktop e aguarde o ícone da baleia ficar estável. No Linux, rode sudo systemctl start docker.

Seu primeiro container: docker run hello-world

O teste clássico de toda instalação é a imagem hello-world. Ela não faz nada de útil além de imprimir uma mensagem — e justamente por isso é perfeita para entender o fluxo:

docker run hello-world
Saída do comando docker run hello-world
O Docker baixou a imagem do Docker Hub, criou o container e exibiu a mensagem

Repare no que aconteceu, porque é o mesmo fluxo de qualquer container:

  1. O Docker procurou a imagem hello-world:latest no seu computador e não encontrou (Unable to find image locally).
  2. Ele então baixou a imagem do Docker Hub, o registry público padrão (Pulling from library/hello-world).
  3. Criou um container a partir dessa imagem e executou o programa dentro dele.
  4. O programa imprimiu a mensagem e terminou — e, quando o processo principal termina, o container para.

Se você rodar o mesmo comando de novo, o passo de download não acontece: a imagem já está em cache local.

Rodando um servidor web de verdade com Nginx

Agora vamos subir algo útil: o servidor web Nginx. Desta vez usaremos três opções novas do docker run:

docker run -d --name meu-nginx -p 8080:80 nginx
  • -d (detached) roda o container em segundo plano e devolve o terminal para você.
  • --name meu-nginx dá um nome amigável ao container. Sem isso, o Docker inventa um nome aleatório.
  • -p 8080:80 publica a porta: tudo o que chegar na porta 8080 do seu computador é encaminhado para a porta 80 do container. O formato é sempre HOST:CONTAINER.

Em seguida, liste os containers em execução com docker ps:

Comando docker run do Nginx seguido de docker ps
O docker ps mostra o container meu-nginx rodando e a porta 8080 publicada

A coluna PORTS confirma o mapeamento 0.0.0.0:8080->80/tcp. Abra o navegador em http://localhost:8080 e você verá a página padrão do Nginx, servida de dentro do container:

Página Welcome to nginx aberta no navegador em localhost:8080
O Nginx rodando dentro do container, acessado pelo navegador

Os comandos do dia a dia

Com um container rodando, estes são os comandos que você mais vai usar:

docker ps                 # lista containers em execução
docker ps -a              # lista todos, inclusive os parados
docker logs meu-nginx     # mostra os logs do container
docker logs -f meu-nginx  # acompanha os logs em tempo real
docker exec -it meu-nginx sh   # abre um terminal dentro do container
docker stop meu-nginx     # para o container
docker start meu-nginx    # inicia de novo
docker rm meu-nginx       # remove (precisa estar parado)
docker images             # lista as imagens baixadas
docker rmi nginx          # remove uma imagem

O docker exec -it merece atenção: ele permite “entrar” no container para investigar arquivos, testar comandos e depurar problemas. O -i mantém a entrada interativa e o -t aloca um terminal.

Criando sua própria imagem com Dockerfile

Usar imagens prontas é ótimo, mas o poder do Docker aparece quando você empacota a sua aplicação. Para isso existe o Dockerfile: um arquivo de texto com as instruções para montar a imagem, passo a passo.

Vamos usar como exemplo a API de tarefas que construímos no tutorial Minha primeira API em Node.js com Express. Na raiz do projeto, crie um arquivo chamado exatamente Dockerfile (sem extensão):

Dockerfile de uma aplicação Node.js aberto no editor
Um Dockerfile comentado para uma API Node.js

Cada instrução gera uma camada da imagem:

  • FROM define a imagem base. Aqui usamos node:22-alpine, uma versão enxuta do Node.js baseada em Alpine Linux.
  • WORKDIR cria e entra na pasta /app dentro da imagem.
  • COPY package*.json ./ copia apenas os arquivos de dependências. Fazemos isso antes de copiar o resto do código por um motivo de performance: se só o código mudar, o Docker reaproveita a camada do npm ci do cache e o build fica muito mais rápido.
  • RUN executa um comando durante o build — no caso, instala as dependências de produção.
  • EXPOSE documenta a porta usada pela aplicação (ele não publica a porta sozinho; quem faz isso é o -p).
  • CMD define o comando executado quando o container inicia.

Crie também um arquivo .dockerignore para evitar copiar lixo para dentro da imagem:

node_modules
npm-debug.log
.git
.env

Ignorar o .env é especialmente importante: tokens e senhas não devem ficar gravados dentro de uma imagem. Falamos disso em detalhes no tutorial sobre variáveis de ambiente e arquivo .env.

Construindo a imagem com docker build

Na mesma pasta do Dockerfile, rode:

docker build -t minha-api:1.0 .

O -t dá nome e versão (tag) à imagem, e o ponto final indica que o contexto do build é a pasta atual.

Saída do docker build criando a imagem minha-api
O docker build executa cada instrução do Dockerfile e gera a imagem minha-api:1.0

Executando a imagem que você criou

Agora é só rodar a imagem como qualquer outra:

Container da API rodando, respondendo ao curl e exibindo logs
A API responde dentro do container; docker logs mostra a saída da aplicação

Pronto: sua aplicação está empacotada. Qualquer pessoa com Docker instalado consegue rodá-la com um único comando, sem instalar Node.js, sem npm install e sem se preocupar com a versão do sistema.

Volumes: como não perder dados

Lembra que containers são descartáveis? Se você rodar um banco de dados em um container e removê-lo, os dados vão junto. A solução são os volumes:

# Volume nomeado, gerenciado pelo Docker
docker volume create dados-mysql
docker run -d --name banco -v dados-mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=segredo mysql:8.4

# Bind mount: espelha uma pasta do seu computador dentro do container
docker run -d -p 8080:80 -v "$(pwd)/site:/usr/share/nginx/html" nginx

O volume nomeado é ideal para bancos de dados. O bind mount é ótimo em desenvolvimento: você edita os arquivos no seu editor e o container enxerga as mudanças na hora.

Erros comuns de quem está começando com Docker

“port is already allocated” — outra aplicação (ou outro container) já está usando a porta do host. Troque o lado esquerdo do -p, por exemplo -p 8081:80, ou pare o processo que ocupa a porta.

“Conflict. The container name is already in use” — já existe um container com esse nome, mesmo que parado. Remova com docker rm nome ou escolha outro nome.

“permission denied while trying to connect to the Docker daemon socket” — no Linux, seu usuário não está no grupo docker. Rode sudo usermod -aG docker $USER e faça logout/login.

O container para logo depois de iniciar — o processo principal terminou ou deu erro. Veja o motivo com docker logs nome-do-container. Um container só fica vivo enquanto o processo definido no CMD estiver rodando.

Disco cheio de imagens antigas — com o tempo, imagens e containers parados se acumulam. O comando docker system prune remove o que não está em uso (leia o aviso com atenção antes de confirmar).

Boas práticas desde o primeiro dia

  • Fixe versões das imagens base. Prefira node:22-alpine a node:latest. O latest muda sem aviso e pode quebrar seu build.
  • Uma responsabilidade por container. API em um container, banco em outro. Para orquestrar vários, use o Docker Compose — veja o tutorial Docker Compose com PHP e MySQL.
  • Nunca coloque segredos na imagem. Passe tokens por variáveis de ambiente em tempo de execução (-e ou --env-file).
  • Use .dockerignore para manter a imagem pequena e sem arquivos sensíveis.
  • Ordene o Dockerfile pensando em cache: o que muda pouco (dependências) vem antes do que muda muito (código).

Perguntas frequentes sobre Docker para iniciantes

Docker é gratuito?

O Docker Engine (usado em servidores Linux) é open source e gratuito. O Docker Desktop é gratuito para uso pessoal, educacional, projetos open source e empresas pequenas; organizações maiores precisam de uma assinatura. Consulte os termos atuais no site oficial.

Preciso saber Linux para usar Docker?

Não para começar, mas ajuda muito. A maioria das imagens é baseada em Linux, então comandos como ls, cd, cat e noções de permissões de arquivo aparecem com frequência ao depurar containers.

Qual a diferença entre docker run e docker start?

O docker run cria um container novo a partir de uma imagem e o inicia. O docker start apenas reinicia um container que já existe e está parado.

Docker substitui o Kubernetes?

Não. Docker cria e executa containers; Kubernetes orquestra muitos containers em vários servidores, com escalonamento automático e alta disponibilidade. Se quiser se aprofundar, leia nosso artigo sobre arquitetura de microserviços com Docker e Kubernetes.

Onde encontro imagens prontas?

No Docker Hub. Dê preferência às imagens marcadas como Docker Official Image ou Verified Publisher, que têm manutenção e atualizações de segurança.

Conclusão e próximos passos

Neste tutorial de Docker para iniciantes você aprendeu os conceitos de imagem, container, registry e volume; instalou o Docker; rodou o hello-world e o Nginx; e criou sua primeira imagem com Dockerfile. Isso já é suficiente para padronizar o ambiente dos seus projetos e acabar com o “na minha máquina funciona”.

O próximo passo natural é subir mais de um serviço ao mesmo tempo — uma aplicação PHP conversando com um banco MySQL, por exemplo. É exatamente isso que fazemos no tutorial Docker Compose com PHP e MySQL. E, se você quer usar containers para consumir APIs brasileiras como CEP, CNPJ, SMS e WhatsApp, conheça a APIBrasil.

Loading

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *