O Que e um Container
Um container e uma caixa fechada que carrega o seu programa junto com tudo que ele precisa para funcionar: o codigo, as bibliotecas, a versao certa da linguagem, ate o pedacinho do sistema operacional. Voce manda essa caixa para qualquer computador e ela roda exatamente igual. Sem "instalar dependencias", sem "configurar o ambiente", sem surpresa.
🧠 Analogia: A Mala de Viagem Completa
Imagine que voce vai viajar e nao confia em achar nada no destino. Entao voce monta uma mala com TUDO: roupa, escova, travesseiro, ate uma tomada adaptadora. Onde quer que chegue, voce abre a mala e tem exatamente o mesmo conforto de casa. O container e essa mala para o seu programa.
- •A mala: o container (a caixa fechada)
- •O que vai dentro: seu app, as bibliotecas, a versao certa de tudo
- •O destino: qualquer computador com Docker (seu PC, a nuvem, o servidor)
- •O resultado: roda igual em todo lugar, sem "na minha maquina funciona"
💡 Container nao e maquina virtual
Voce pode pensar que e uma maquina virtual (VM), mas e bem mais leve. Uma VM carrega um sistema operacional inteiro do zero (pesa gigas, demora minutos para ligar). O container compartilha o sistema do computador e empacota so o que o seu app precisa. Por isso ele liga em segundos e voce roda dezenas deles no mesmo computador sem travar.
Instalando o Docker
Antes de rodar qualquer container, voce precisa instalar o Docker. No Windows e Mac voce instala o Docker Desktop (um programa com janela). No Linux, voce instala o Docker Engine direto pelo terminal. Vamos por sistema.
Windows
Docker Desktop (precisa do WSL2 ativado)
# 1. Baixe o instalador
docker.com/products/docker-desktop
# 2. Rode o instalador, marque "Use WSL 2"
Docker Desktop Installer.exe
# 3. Reinicie e abra o Docker Desktop
macOS
Docker Desktop (versao Intel ou Apple Silicon)
# Opcao 1: site oficial
Baixe o .dmg, arraste para Aplicativos
# Opcao 2: Homebrew (se tiver)
$ brew install --cask docker
Linux (Ubuntu/Debian)
Docker Engine, instalado pelo script oficial
# Script oficial de instalacao
$ curl -fsSL https://get.docker.com | sh
# Rodar docker sem sudo (relogue depois)
$ sudo usermod -aG docker $USER
👁 Como confirmar que instalou
Abra o terminal e peca a versao. Se aparecer um numero, esta funcionando:
$ docker --version
Docker version 27.3.1, build ce12230
# Checagem mais completa (cliente + servidor):
$ docker info
Server Version: 27.3.1
Containers: 0 Images: 0
Se aparecer a versao, o Docker esta instalado e pronto. Pode pular para o proximo topico e rodar seu primeiro container.
⚠️ Erro Comum
Problema: roda docker info e aparece "Cannot connect to the Docker daemon".
Solucao: o Docker esta instalado, mas o motor (daemon) nao esta ligado. No Windows/Mac, abra o Docker Desktop e espere o icone ficar verde. No Linux, rode sudo systemctl start docker.
docker run: Seu Primeiro Container
O comando docker run e o coracao do Docker. Ele faz tudo de uma vez: baixa a imagem (se nao tiver), cria um container a partir dela e liga. Vamos do "ola mundo" do Docker ate rodar um servidor de verdade.
docker run hello-world - O teste
Esse comando baixa uma imagem minuscula, roda e imprime uma mensagem. E o jeito oficial de confirmar que tudo funciona.
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
Hello from Docker!
This message shows that your installation
appears to be working correctly.
docker run -p - Abrindo a porta
O container e fechado. Para acessar um site dentro dele pelo navegador, voce conecta uma porta sua a uma porta dele com -p porta-sua:porta-do-container.
# Rodar o nginx (servidor web) na porta 8080
$ docker run -p 8080:80 nginx
# -d = roda em segundo plano (detached)
$ docker run -d -p 8080:80 nginx
a1b2c3d4e5f6...
# Agora abra no navegador:
http://localhost:8080
A esquerda do : e a porta do seu computador, a direita e a porta de dentro do container.
docker ps - O que esta rodando
Lista os containers ligados agora. Com -a mostra tambem os que ja pararam.
$ docker ps
CONTAINER ID IMAGE STATUS PORTS
a1b2c3d4e5f6 nginx Up 2 minutes 0.0.0.0:8080->80/tcp
# Parar um container pelo ID
$ docker stop a1b2c3d4e5f6
# Ver todos, inclusive os parados
$ docker ps -a
💡 Dica: nao precisa decorar o ID inteiro
O ID do container e um codigo longo, mas voce so precisa digitar os primeiros caracteres (geralmente 3 ou 4 ja bastam). Em vez de docker stop a1b2c3d4e5f6, basta docker stop a1b2. O Docker entende.
✓ O que FAZER
- ✓Usar
-dpara rodar servidores em segundo plano - ✓Conferir com
docker pso que esta no ar - ✓Parar containers que nao usa mais (libera porta e memoria)
✗ O que NAO fazer
- ✗Inverter a porta (
-p 80:8080quando o app usa 80) - ✗Esquecer containers ligados consumindo recursos
- ✗Usar a mesma porta sua em dois containers ao mesmo tempo
Imagens vs Containers
Essa e a confusao numero 1 de quem comeca. A regra e simples: a imagem e o molde (parada, guardada no disco) e o container e a instancia rodando (viva, em execucao). De uma imagem so voce pode criar quantos containers quiser.
🧠 Analogia: A Receita e o Bolo
A imagem e a receita de bolo num papel: ela so descreve, nao da pra comer. O container e o bolo assado de verdade, pronto na mesa. Com uma receita voce assa quantos bolos quiser, todos iguais. Comeu um, faz outro com a mesma receita.
- •Imagem (receita): arquivo parado no disco, nao consome memoria
- •Container (bolo): processo rodando, consome CPU e memoria
- •1 imagem -> N containers: uma receita, varios bolos
Comandos de IMAGEM
# Listar imagens no disco
$ docker images
REPOSITORY TAG SIZE
nginx latest 187MB
# Baixar uma imagem
$ docker pull node:20
# Apagar uma imagem
$ docker rmi nginx
Comandos de CONTAINER
# Listar containers rodando
$ docker ps
# Parar um container
$ docker stop a1b2
# Apagar um container parado
$ docker rm a1b2
# Ver os logs (saida) dele
$ docker logs a1b2
⚠️ Erro Comum
Problema: tenta docker rmi nginx e aparece "image is being used by running container".
Solucao: nao da pra apagar a receita enquanto tem bolo na mesa. Pare e apague os containers que usam a imagem primeiro (docker stop + docker rm), depois apague a imagem.
images
Listar moldes
pull
Baixar molde
ps
Containers vivos
rm / rmi
Apagar
Dockerfile: A Receita do Container
Ate agora voce usou imagens prontas (nginx, hello-world). Mas e o SEU programa? Para empacotar o seu codigo numa imagem, voce escreve um Dockerfile: um arquivo de texto com a receita, linha por linha, de como montar a imagem.
📝 Um Dockerfile de exemplo (app Node)
# comeca de uma imagem-base com Node ja instalado
FROM node:20
# pasta de trabalho dentro do container
WORKDIR /app
# copia os arquivos do seu projeto para dentro
COPY . .
# roda um comando na hora de montar a imagem
RUN npm install
# comando que executa quando o container liga
CMD ["node", "server.js"]
FROM - de onde partir
Toda receita comeca de uma imagem-base ja pronta (Node, Python, Ubuntu...). Voce nao monta tudo do zero, parte de algo que ja existe.
COPY - levar seu codigo pra dentro
Copia arquivos do seu computador para dentro da imagem. O COPY . . leva a pasta atual inteira para a pasta de trabalho do container.
RUN - executar na montagem
Roda um comando enquanto a imagem esta sendo construida (ex.: instalar dependencias). O resultado fica gravado na imagem.
CMD - o que fazer ao ligar
Define o comando que roda quando o container e iniciado. Diferente do RUN (montagem), o CMD acontece na execucao.
💡 Dica: RUN x CMD
A confusao mais comum: RUN acontece quando voce constroi a imagem (uma vez, e congela no molde). CMD acontece quando voce roda o container (toda vez que liga). Pense: RUN = montagem da mala; CMD = o que voce faz ao chegar no destino.
Build e Push: Do Dockerfile ao Mundo
Voce tem o Dockerfile (a receita). Agora vem o ciclo final: build transforma a receita numa imagem, run liga um container dela, e push envia a imagem para um registry na nuvem, para qualquer servidor poder baixar e rodar.
Build: montar a imagem
O -t da um nome (tag) para a imagem. O ponto no fim e a pasta atual (onde esta o Dockerfile).
$ docker build -t meu-app .
[+] Building 12.3s
=> [1/4] FROM node:20
=> [4/4] RUN npm install
=> naming to docker.io/library/meu-app
Run: testar localmente
Antes de mandar pro mundo, rode a imagem que voce acabou de montar.
$ docker run -p 3000:3000 meu-app
Server rodando na porta 3000
Push: enviar para o registry
O registry e a "nuvem de imagens" (Docker Hub e o mais comum). Voce loga, marca a imagem com seu usuario e envia.
# 1. logar no Docker Hub
$ docker login
# 2. marcar com seu usuario
$ docker tag meu-app seuuser/meu-app:1.0
# 3. enviar para a nuvem
$ docker push seuuser/meu-app:1.0
The push refers to repository [docker.io/seuuser/meu-app]
1.0: pushed
👁 O ciclo completo, do zero ao deploy
# 1. escrever a receita (Dockerfile)
# 2. montar a imagem
$ docker build -t seuuser/meu-app:1.0 .
# 3. enviar para o registry
$ docker push seuuser/meu-app:1.0
# 4. no servidor, baixar e rodar
$ docker run -d -p 80:3000 seuuser/meu-app:1.0
✓ O que FAZER
- ✓Versionar a tag (
:1.0,:1.1) em vez de solatest - ✓Testar com
docker runantes do push - ✓Criar um
.dockerignorepara nao copiar lixo
✗ O que NAO fazer
- ✗Colocar senhas/tokens dentro da imagem
- ✗Dar push de imagem que nunca rodou local
- ✗Empurrar a pasta
node_modulesdentro da imagem
🏆 Parabens!
Voce ja entende o ciclo inteiro do Docker: imagem, container, Dockerfile, build e push. Com isso, seu programa roda igual no seu PC e em qualquer servidor do mundo. No proximo modulo, voce vai aprender a orquestrar varios containers de uma vez com o Docker Compose.
📚 Resumo do Modulo
Proximo Modulo:
4.2 - Docker Compose: orquestrar varios containers (app + banco + cache) com um unico arquivo