Aprende a empacotar, distribuir e executar aplicações em contentores Docker — do desenvolvimento local ao deploy em produção, sempre com o mesmo ambiente.
Conceitos fundamentais antes de começar
Um processo isolado que corre no teu sistema operativo, com o seu próprio sistema de ficheiros, rede e dependências. Leve, rápido e portátil — não é uma máquina virtual.
Processo isoladoUm template imutável e em camadas que define tudo o que um container precisa — sistema de base, dependências, código e configurações. As imagens são partilhadas via registos como o Docker Hub.
Template imutávelFicheiro de texto com instruções para construir uma imagem Docker passo a passo. Define a base, copia ficheiros, instala dependências e configura o comando de arranque.
Receita de construçãoRepositório de imagens Docker. O Docker Hub é o registo público por defeito. Existem também registos privados como o GitHub Container Registry, AWS ECR ou um registo próprio.
Docker Hub · GHCRMecanismo para persistir dados fora do ciclo de vida do container. Os dados num volume sobrevivem a paragens e remoções do container — essencial para bases de dados e ficheiros de utilizador.
Persistência de dadosRede virtual que liga containers entre si. Por defeito, containers no mesmo docker-compose comunicam pelo nome do serviço. Isola comunicações por projecto.
Comunicação entre containersColocar o Docker a funcionar no teu sistema
docker.com/products/docker-desktop — inclui Docker Engine, Docker CLI, Docker Compose e interface gráfica para Windows e macOS. Em Linux, instala o Docker Engine via gestor de pacotes: apt install docker.io ou segue as instruções oficiais em docs.docker.com.
Descarregar, listar, inspecionar e remover imagens
| Comando | O que faz |
|---|---|
| 🔍 Pesquisar e Descarregar | |
| docker search nginx | Pesquisa imagens no Docker Hub pelo nome indicado. |
| docker pull nginx | Descarrega a imagem nginx:latest do Docker Hub sem criar um container. |
| docker pull nginx:1.25 | Descarrega uma versão específica usando a tag. Prefere sempre tags concretas em produção. |
| 📋 Listar e Inspecionar | |
| docker images | Lista todas as imagens descarregadas localmente — nome, tag, ID, tamanho e data. |
| docker image ls | Equivalente moderno de docker images. Usa -a para mostrar imagens intermédias. |
| docker inspect nginx | Devolve metadados completos da imagem em JSON — camadas, variáveis de ambiente, portas expostas. |
| docker history nginx | Mostra as camadas da imagem e os comandos usados para as criar. |
| 🗑️ Remover | |
| docker rmi nginx | Remove uma imagem local. Falha se existirem containers (mesmo parados) a usá-la. |
| docker image prune | Remove todas as imagens sem tags (dangling). Adiciona -a para remover todas as não utilizadas. |
| 🔨 Construir | |
| docker build -t nome:tag . | Constrói uma imagem a partir do Dockerfile na directoria actual. O ponto final é o contexto de build. |
| docker build -f caminho/Dockerfile . | Usa um Dockerfile com um nome ou localização diferente do padrão. |
Escrever Dockerfiles eficientes e seguros
| Instrução | O que faz |
|---|---|
| FROM <imagem> | Define a imagem base. Deve ser a primeira instrução. Usa imagens alpine para reduzir o tamanho. |
| WORKDIR <path> | Define a directoria de trabalho dentro do container. Cria-a se não existir. |
| COPY <src> <dest> | Copia ficheiros do contexto de build para o sistema de ficheiros da imagem. |
| RUN <comando> | Executa um comando durante a construção da imagem. Cada RUN cria uma nova camada — agrupa comandos com &&. |
| ENV <chave>=<valor> | Define variáveis de ambiente persistentes na imagem e nos containers derivados. |
| ARG <nome> | Define variáveis disponíveis apenas durante o build — não ficam na imagem final. |
| EXPOSE <porta> | Documenta as portas que o container irá usar. Não as abre automaticamente no host. |
| VOLUME <path> | Declara um ponto de montagem para volume — garante persistência de dados nesse caminho. |
| USER <utilizador> | Define o utilizador para RUN, CMD e ENTRYPOINT seguintes. Evita correr como root. |
| CMD ["cmd", "arg"] | Comando padrão ao iniciar o container. Pode ser substituído na linha de comandos. |
| ENTRYPOINT ["cmd"] | Ponto de entrada fixo do container — não pode ser substituído facilmente. Combina com CMD para argumentos por defeito. |
.dockerignore na raiz do projecto para excluir node_modules/, .git/, ficheiros .env, logs e outros ficheiros desnecessários do contexto de build. Reduz drasticamente o tamanho da imagem e o tempo de construção.
Criar, iniciar, parar, inspecionar e remover containers
| Comando | O que faz |
|---|---|
| ▶️ Criar e Executar | |
| docker run <imagem> | Cria e inicia um container a partir de uma imagem. Se a imagem não existir localmente, é descarregada. |
| docker run -d <imagem> | Corre em modo detached (background) — o terminal fica livre. |
| docker run -it <imagem> bash | Modo interactivo com terminal — ideal para explorar o interior de um container. |
| docker run -p 8080:80 <imagem> | Mapeia a porta 80 do container para a porta 8080 do host. |
| docker run --name meu-app <imagem> | Atribui um nome ao container para facilitar a sua gestão. |
| docker run -e VAR=valor <imagem> | Define variáveis de ambiente no container. |
| docker run --rm <imagem> | Remove o container automaticamente quando este terminar. |
| 📋 Listar e Monitorizar | |
| docker ps | Lista apenas os containers em execução. |
| docker ps -a | Lista todos os containers — em execução, parados e terminados. |
| docker logs <nome> | Mostra os logs do container. Usa -f para seguir em tempo real. |
| docker stats | Mostra o consumo de CPU, memória, rede e disco de todos os containers activos em tempo real. |
| docker inspect <nome> | Metadados completos do container em JSON — IPs, volumes, variáveis de ambiente, etc. |
| ⏯️ Controlar | |
| docker start <nome> | Inicia um container parado. |
| docker stop <nome> | Para um container graciosamente (envia SIGTERM, aguarda 10s, depois SIGKILL). |
| docker restart <nome> | Para e inicia novamente um container. |
| docker exec -it <nome> bash | Abre um terminal dentro de um container em execução — muito útil para depuração. |
| docker rm <nome> | Remove um container parado. Usa -f para forçar a remoção de um container activo. |
| docker container prune | Remove todos os containers parados de uma vez. |
Persistir dados e conectar containers
| Comando | Descrição |
|---|---|
| docker volume create myvol | Cria um volume gerido pelo Docker. |
| docker volume ls | Lista todos os volumes. |
| docker volume inspect myvol | Detalhes e localização do volume no host. |
| docker volume rm myvol | Remove um volume não utilizado. |
| docker volume prune | Remove todos os volumes sem containers associados. |
| -v myvol:/app/data | Monta o volume myvol em /app/data no container. |
| -v $(pwd):/app | Monta a directoria actual do host (bind mount) — útil em desenvolvimento. |
| Comando | Descrição |
|---|---|
| docker network create mynet | Cria uma rede bridge personalizada. |
| docker network ls | Lista todas as redes Docker. |
| docker network inspect mynet | Detalhes da rede e containers ligados. |
| docker network rm mynet | Remove uma rede. |
| --network mynet | Liga um container a uma rede específica. |
| --network host | Usa a rede do host directamente (sem isolamento). |
| --network none | Container sem acesso à rede. |
Orquestrar múltiplos containers com um único ficheiro YAML
| Comando | O que faz |
|---|---|
| docker compose up | Inicia todos os serviços definidos no docker-compose.yml. Adiciona -d para background. |
| docker compose up --build | Reconstrói as imagens antes de iniciar — necessário após alterações ao Dockerfile. |
| docker compose down | Para e remove todos os containers e redes criados. Adiciona -v para remover também os volumes. |
| docker compose ps | Lista o estado de todos os serviços do projecto. |
| docker compose logs -f | Mostra os logs de todos os serviços em tempo real. Especifica um serviço: docker compose logs api. |
| docker compose exec api sh | Abre um terminal no container do serviço api. |
| docker compose restart api | Reinicia apenas o serviço indicado sem afectar os restantes. |
| docker compose pull | Actualiza todas as imagens dos serviços que usam imagens do registry. |
| docker compose config | Valida e mostra a configuração final do docker-compose.yml. |
Do desenvolvimento local ao deploy em produção
Definir a receita da imagem
Construir a imagem localmente
Correr e validar localmente
Enviar para o registry
Puxar e correr em produção
Define a imagem base, copia o código, instala dependências e configura o comando de arranque. Usa imagens alpine para reduzir o tamanho e multi-stage builds para imagens de produção mais pequenas.
Dockerfile · .dockerignoreExecuta o Dockerfile e cria uma imagem local. Usa tags com versão semântica (1.0.0) e também latest. O Docker aproveita o cache de camadas para builds mais rápidos.
docker build -t minha-app:1.0 .Usa um docker-compose.yml para subir a stack completa (app + base de dados + cache) com um só comando. Valida que todos os serviços comunicam correctamente.
docker compose up --buildAutentica no Docker Hub (ou outro registry), faz tag da imagem com o nome completo do repositório e envia.
docker push utilizador/minha-app:1.0No servidor de produção, faz pull da nova imagem e recria os containers. Usa --pull always para garantir a versão mais recente. Em ambientes orquestrados (Kubernetes, Docker Swarm), o processo de actualização é automático.
Acompanha os logs, monitoriza o consumo de recursos, actualiza imagens regularmente para receber correcções de segurança e remove imagens e volumes não utilizados para libertar espaço.
docker stats · docker logs -f · docker system prunePublicar imagens e manter o sistema limpo
Usa sempre USER no Dockerfile para criar e usar um utilizador sem privilégios. A instrução RUN adduser cria o utilizador dedicado à aplicação.
Nunca incluas passwords ou tokens directamente no Dockerfile. Usa .env (nunca commites), Docker Secrets ou variáveis do CI/CD.
Copia os ficheiros de dependências (package.json) antes do código fonte. Assim, o npm install só corre quando as dependências mudam.
Usa múltiplas fases no Dockerfile para separar o ambiente de build do de produção — a imagem final fica mais pequena e sem ferramentas de desenvolvimento desnecessárias.
Reconstrui as tuas imagens regularmente com bases actualizadas para receber correcções de segurança. Usa o Docker Scout para detectar vulnerabilidades.
Nunca uses :latest em produção — usa sempre versões específicas (:1.2.3) para garantir reproducibilidade e evitar actualizações inesperadas.