Guia Completo de Docker: Do Básico ao Avançado
Aprenda Docker do básico ao avançado com um guia detalhado, cobrindo conceitos, configuração, orquestração e melhores práticas.
Introdução
O Docker transformou a maneira como desenvolvedores e equipes de TI criam, testam e implantam aplicações. Ao permitir que aplicações sejam empacotadas com todas as suas dependências em containers, Docker simplifica o desenvolvimento e garante que as aplicações rodem de maneira consistente em diferentes ambientes, seja no desenvolvimento local, no teste ou na produção.
Neste guia completo, você aprenderá desde os conceitos fundamentais de containerização até funcionalidades avançadas do Docker. Vamos abordar desde a instalação e configuração inicial até técnicas de orquestração com Docker Compose, uso de redes, volumes para persistência de dados, otimização e segurança de containers. Com um passo a passo detalhado, este tutorial oferece tudo o que você precisa para dominar o uso do Docker em projetos de qualquer escala, incluindo integração com CI/CD para automação e deploy contínuo.
Prepare-se para explorar o poder do Docker e elevar suas habilidades em DevOps, criando ambientes isolados, seguros e escaláveis para suas aplicações!
Sumário
- Introdução ao Docker e Conceitos de Containerização
- Instalação e Configuração do Docker
- Trabalhando com Imagens no Docker
- Criando e Gerenciando Containers
- Introdução ao Dockerfile: Construindo Imagens Personalizadas
- Gerenciamento de Volumes no Docker
- Rede e Comunicação entre Containers
- Docker Compose: Orquestrando Múltiplos Containers
- Trabalhando com Registries e Docker Hub
- Otimização e Melhores Práticas com Containers
- Monitoramento e Log de Containers
- Salvando e Carregando Imagens e Containers
- Troubleshooting e Solução de Problemas Comuns no Docker
- Casos de Uso Avançados e Integração com CI/CD
1. Introdução ao Docker e Conceitos de Containerização
Objetivo
Apresentar o Docker, suas principais funcionalidades e a importância da containerização. Compreender os conceitos de imagens, containers, registries e orquestração é essencial para o uso adequado do Docker.
O que é o Docker?
Docker é uma plataforma de código aberto que facilita a criação, o gerenciamento e a execução de containers. Containers são ambientes isolados que contêm aplicações e todas as suas dependências, o que facilita a portabilidade e a consistência entre diferentes ambientes (desenvolvimento, teste e produção).
Containers vs. Máquinas Virtuais (VMs)
Característica | Containers | Máquinas Virtuais (VMs) |
---|---|---|
Isolamento | Processos e namespaces | Sistemas operacionais inteiros |
Uso de recursos | Leve (compartilha o kernel) | Pesado (cada VM tem seu próprio SO) |
Início/Desligamento | Rápido (segundos) | Lento (minutos) |
Portabilidade | Alta | Limitada, depende do hypervisor |
Armazenamento | Volumes e redes do Docker | Discos virtuais |
Containers compartilham o kernel do sistema operacional do host, o que os torna mais leves e rápidos em comparação com VMs, que exigem um sistema operacional completo para cada instância.
Principais Conceitos do Docker
-
Imagens: São modelos somente-leitura usados para criar containers. Cada imagem contém todos os elementos necessários para a aplicação (sistema de arquivos, bibliotecas, dependências).
-
Containers: São instâncias de uma imagem em execução. Um container é a unidade básica em que as aplicações e seus ambientes operacionais executam de forma isolada.
-
Registries: São repositórios para armazenar e compartilhar imagens Docker. O Docker Hub é o registry padrão, mas também é possível configurar registries privados para compartilhar imagens de maneira controlada.
-
Orquestração: Refere-se à prática de gerenciar múltiplos containers que compõem uma aplicação. Ferramentas como Docker Compose e Kubernetes ajudam na orquestração de containers para aplicações mais complexas e escaláveis.
Vantagens da Containerização com Docker
-
Consistência entre ambientes: Containers oferecem consistência, pois a aplicação e suas dependências estão dentro de um único ambiente que pode ser replicado em qualquer máquina.
-
Eficiência de recursos: Por compartilharem o kernel do sistema operacional, containers utilizam menos recursos que VMs.
-
Escalabilidade: Containers podem ser escalados rapidamente, ideal para sistemas distribuídos e de microserviços.
-
Desenvolvimento acelerado: Docker permite a criação de ambientes prontos para desenvolvimento rapidamente, eliminando problemas de configuração de ambiente.
Fluxo de Trabalho Básico com Docker
- Buscar e criar imagens: A partir do Docker Hub ou outras fontes, utilizando
docker pull
. - Criar containers: Executando
docker run
para iniciar um container baseado em uma imagem. - Gerenciar containers: Parando, reiniciando e removendo containers conforme necessário.
- Persistência e redes: Usando volumes para persistência de dados e redes para comunicação entre containers.
Exemplo Prático de Uso do Docker
Para ilustrar o fluxo básico de trabalho com Docker, vejamos um exemplo simples:
- Buscar uma Imagem:
1
docker pull nginx
Este comando baixa a imagem do servidor web NGINX do Docker Hub.
- Criar e Executar um Container:
1
docker run -d -p 8080:80 nginx
Aqui, o Docker cria um container baseado na imagem NGINX, em modo detached (
-d
), e mapeia a porta 80 do container para a porta 8080 no host. - Listar Containers em Execução:
1
docker ps
Este comando exibe todos os containers que estão em execução. Veremos o container NGINX com suas configurações de porta e status.
- Parar e Remover o Container:
1 2
docker stop <container_id> docker rm <container_id>
Usando o ID do container, podemos pará-lo e removê-lo. Isso libera recursos no sistema.
2. Instalação e Configuração do Docker
Objetivo
Guiar o usuário no processo de instalação e configuração inicial do Docker. Ao final desta seção, você será capaz de verificar a instalação do Docker e ajustar permissões para gerenciar containers.
Pré-Requisitos
- Acesso a um sistema com Debian 11 ou Oracle Linux 8.
- Acesso root ou permissões de superusuário (sudo) para instalação.
Passo a Passo para Instalar o Docker no Debian 11
- Atualize o Sistema:
1 2
sudo apt update sudo apt upgrade -y
- Instale Dependências Necessárias:
Instale pacotes que permitirão o uso do repositório HTTPS.
1
sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
- Adicione a Chave GPG do Docker:
1
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
- Adicione o Repositório Docker:
1
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- Instale o Docker:
Atualize a lista de pacotes e instale o Docker.
1 2
sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io -y
- Verifique a Instalação:
Após a instalação, confirme se o Docker está funcionando:
1 2
docker --version docker info
O comando
docker --version
exibirá a versão instalada, enquantodocker info
mostrará detalhes do ambiente Docker.
Instalação do Docker no Oracle Linux 8
- Atualize o Sistema:
1
sudo dnf update -y
- Adicione o Repositório Docker:
Adicione o repositório oficial do Docker para Oracle Linux.
1
sudo dnf config-manager --add-repo=https://download.docker.com/linux/oracle/docker-ce.repo
- Instale o Docker:
1
sudo dnf install docker-ce docker-ce-cli containerd.io -y
- Inicie e Ative o Serviço Docker:
1 2
sudo systemctl start docker sudo systemctl enable docker
- Verifique a Instalação:
Assim como no Debian, use:
1 2
docker --version docker info
Configuração Inicial e Permissões para Usuário
Após a instalação, configure permissões para que um usuário comum possa executar comandos Docker sem precisar do sudo
toda vez.
- Crie o Grupo Docker (caso não exista):
1
sudo groupadd docker
- Adicione seu Usuário ao Grupo Docker:
1
sudo usermod -aG docker $USER
Observação: Substitua
$USER
pelo nome do usuário, se estiver configurando para outro usuário. - Aplique as Alterações de Grupo:
Você precisará fazer logoff e logon novamente para que as permissões sejam aplicadas. Alternativamente, pode executar:
1
newgrp docker
- Teste a Permissão:
Execute um comando Docker sem
sudo
para verificar:1
docker run hello-world
Esse comando baixa e executa a imagem
hello-world
, exibindo uma mensagem de sucesso se o Docker estiver corretamente configurado.
Resolução de Problemas Comuns na Instalação
- Erro: Docker Daemon não está rodando:
- Verifique o status do Docker:
1
sudo systemctl status docker
- Inicie o Docker se necessário:
1
sudo systemctl start docker
- Verifique o status do Docker:
- Erro de Permissão:
Se houver erro de permissão ao executar comandos Docker sem
sudo
, verifique se o usuário foi adicionado ao grupodocker
corretamente e se o login foi reiniciado.
3. Trabalhando com Imagens no Docker
Objetivo
Ensinar como localizar, baixar e gerenciar imagens Docker para construir containers. Este é um passo fundamental, pois as imagens formam a base dos containers.
Principais Comandos para Gerenciamento de Imagens
Comando | Descrição |
---|---|
docker pull <imagem> |
Baixa uma imagem do Docker Hub ou de um registry especificado. |
docker images |
Lista todas as imagens baixadas e disponíveis localmente. |
docker rmi <imagem> |
Remove uma imagem especificada do sistema. |
docker build |
Constrói uma imagem a partir de um Dockerfile. |
docker tag |
Marca uma imagem para facilitar a identificação e uso. |
1. Baixando Imagens com docker pull
O comando docker pull
permite buscar e baixar imagens do Docker Hub ou de um registry especificado. Vamos utilizar o Docker Hub para buscar uma imagem popular, como o nginx
.
1
docker pull nginx
Este comando busca a última versão da imagem nginx
. Você também pode especificar uma versão específica da imagem (conhecida como “tag”):
1
docker pull nginx:1.21
Nota: Cada versão ou tag representa uma versão específica da aplicação ou do sistema, facilitando o uso de versões estáveis ou personalizadas.
2. Listando Imagens Disponíveis com docker images
Para ver as imagens baixadas e disponíveis no seu ambiente local, use o comando docker images
:
1
docker images
Este comando exibe uma lista com as colunas principais, incluindo:
- REPOSITORY: O nome da imagem.
- TAG: A tag ou versão da imagem.
- IMAGE ID: Identificador único da imagem.
- CREATED: Tempo decorrido desde a criação.
- SIZE: Tamanho da imagem.
Exemplo:
1
2
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 4cdc5dd7eaad 2 weeks ago 133MB
3. Diferença entre Imagens Oficiais e Personalizadas
Imagens Oficiais
Imagens oficiais são mantidas pela comunidade ou por equipes responsáveis diretamente no Docker Hub (ex.: nginx
, mysql
). Elas são confiáveis e verificadas pelo Docker, geralmente identificadas com o ícone de “verificado”.
Imagens Personalizadas
Imagens personalizadas são versões de imagens feitas sob medida para atender a necessidades específicas. Podem ser criadas a partir de um Dockerfile ou modificações locais em uma imagem padrão.
4. Excluindo Imagens com docker rmi
Para liberar espaço no sistema, é possível remover imagens que não são mais necessárias. O comando docker rmi <imagem>
permite remover uma imagem especificada.
1
docker rmi nginx
Caso a imagem esteja em uso por algum container, será necessário interromper o container antes de excluí-la.
Dica: Use
docker rmi $(docker images -q -f "dangling=true")
para remover imagens “dangling” (ou seja, imagens intermediárias sem tag), economizando espaço.
5. Criando Imagens Personalizadas com Dockerfile
Um Dockerfile permite criar uma imagem personalizada definindo todas as etapas para montar o ambiente e instalar dependências.
Exemplo Básico de Dockerfile
- Crie um arquivo chamado
Dockerfile
:1 2 3 4 5 6 7 8 9 10 11 12 13 14
# Usando uma imagem base FROM ubuntu:latest # Instalando pacotes necessários RUN apt-get update && apt-get install -y python3 # Definindo o diretório de trabalho WORKDIR /app # Copiando arquivos para o container COPY . /app # Comando para iniciar o container CMD ["python3", "app.py"]
- Construa a Imagem:
1
docker build -t minha-imagem-python .
Neste exemplo, estamos usando a imagem base
ubuntu
, instalando o Python e copiando arquivos locais para o diretório/app
dentro do container. -
Listando a Nova Imagem: Após a construção, verifique se a imagem está disponível:
1
docker images
6. Tagging e Versionamento de Imagens com docker tag
O comando docker tag
permite atribuir tags específicas para imagens, facilitando o versionamento e o compartilhamento em registries.
1
docker tag minha-imagem-python minha-conta/minha-imagem-python:v1
Essa tag facilita o gerenciamento de versões ao identificar cada versão ou modificação realizada.
4. Criando e Gerenciando Containers
Objetivo
Demonstrar como criar, executar e gerenciar containers no Docker. Containers são a base para executar aplicações isoladamente, e dominar o gerenciamento de containers é essencial para o uso do Docker.
Principais Comandos para Containers
Comando | Descrição |
---|---|
docker run |
Cria e inicia um container com base em uma imagem. |
docker ps |
Lista containers em execução. |
docker ps -a |
Lista todos os containers (executando e parados). |
docker stop <container_id> |
Para a execução de um container. |
docker start <container_id> |
Inicia um container previamente parado. |
docker restart <container_id> |
Reinicia um container. |
docker rm <container_id> |
Remove um container parado. |
docker exec -it <container_id> |
Acessa um container em execução no modo interativo. |
1. Criando e Executando Containers com docker run
O comando docker run
é o mais básico e importante para iniciar um container a partir de uma imagem. Ele aceita várias opções que permitem configurar o container de forma personalizada.
Exemplo 1: Executar um Container NGINX em Modo Background
1
docker run -d -p 8080:80 nginx
- -d: Inicia o container em modo detached (background).
- -p 8080:80: Mapeia a porta 80 do container para a porta 8080 no host, permitindo acesso à aplicação.
Após executar este comando, o servidor NGINX estará disponível no endereço http://localhost:8080
.
Exemplo 2: Executar um Container em Modo Interativo
Para executar um container em modo interativo, permitindo acesso ao terminal do container, use a opção -it
:
1
docker run -it ubuntu /bin/bash
- -it: Executa em modo interativo com acesso ao terminal do container.
- ubuntu: A imagem a ser usada.
- /bin/bash: Comando inicial a ser executado (abre um shell Bash).
Este comando abre um shell no container Ubuntu, permitindo executar comandos diretamente dentro do ambiente do container.
Opções Úteis no Comando docker run
Opção | Descrição |
---|---|
-d |
Executa o container em segundo plano. |
-p host:container |
Mapeia uma porta do host para uma porta do container, permitindo acesso externo. |
-v host_path:container_path |
Monta um volume, ligando diretórios do host com o container. |
-e VAR=value |
Define variáveis de ambiente dentro do container. |
--name <nome> |
Atribui um nome ao container, facilitando o gerenciamento. |
2. Listando Containers com docker ps
O comando docker ps
mostra todos os containers em execução. Para listar todos os containers, inclusive os parados, use -a
:
1
2
docker ps # Lista apenas containers em execução
docker ps -a # Lista todos os containers (executando e parados)
Exemplo de Saída:
1
2
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d9eafacde07 nginx "nginx -g …" 5 minutes ago Up 5 minutes 0.0.0.0:8080->80/tcp amazing_morse
3. Parando, Reiniciando e Removendo Containers
Parar um Container com docker stop
Para interromper um container em execução, utilize o comando docker stop
seguido do ID ou nome do container.
1
docker stop amazing_morse
Reiniciar um Container com docker restart
Para reiniciar um container (útil para aplicar alterações de configuração):
1
docker restart amazing_morse
Remover um Container com docker rm
Se o container foi interrompido e você deseja removê-lo, use o comando docker rm
:
1
docker rm amazing_morse
Dica: Para remover múltiplos containers de uma vez, use
docker rm $(docker ps -aq)
.
4. Acessando um Container em Execução com docker exec
O comando docker exec
é utilizado para executar comandos dentro de um container em execução. Ele é especialmente útil para acessar o terminal ou rodar scripts diretamente no ambiente isolado do container.
Exemplo: Acessar o Terminal do Container NGINX
1
docker exec -it amazing_morse /bin/bash
Este comando abre um shell interativo no container amazing_morse
. Você pode então executar comandos diretamente dentro do container.
5. Introdução ao Dockerfile: Construindo Imagens Personalizadas
Objetivo
Explicar o uso do Dockerfile para criar imagens personalizadas, permitindo que você defina os pacotes, dependências e configurações iniciais de um container. Ao final, você será capaz de construir uma imagem Docker sob medida.
O que é um Dockerfile?
Um Dockerfile é um arquivo de texto que contém uma série de instruções para construir uma imagem Docker. Cada instrução no Dockerfile define uma etapa para criar o ambiente de um container, como instalar pacotes, copiar arquivos ou configurar variáveis de ambiente.
Principais Instruções do Dockerfile
Instrução | Descrição |
---|---|
FROM |
Define a imagem base a partir da qual o container será criado. |
RUN |
Executa comandos no container durante o processo de criação da imagem. |
COPY |
Copia arquivos ou diretórios do host para o sistema de arquivos do container. |
WORKDIR |
Define o diretório de trabalho dentro do container, onde os comandos serão executados. |
CMD |
Especifica o comando que será executado quando o container for iniciado. |
EXPOSE |
Expõe uma porta do container para comunicação com o mundo externo. |
ENV |
Define variáveis de ambiente que estarão disponíveis dentro do container. |
Criando um Dockerfile Básico
Vamos criar um Dockerfile simples para uma aplicação Python.
- Crie um Diretório de Trabalho:
1 2
mkdir meu_app_docker cd meu_app_docker
-
Crie o Arquivo Dockerfile: No diretório
meu_app_docker
, crie um arquivo chamadoDockerfile
com o seguinte conteúdo:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# Use uma imagem base do Python FROM python:3.9 # Defina o diretório de trabalho WORKDIR /app # Copie o arquivo de requisitos COPY requirements.txt /app # Instale as dependências RUN pip install -r requirements.txt # Copie o código da aplicação COPY . /app # Exponha a porta em que a aplicação vai rodar EXPOSE 5000 # Comando para iniciar a aplicação CMD ["python", "app.py"]
-
Adicione os Arquivos Necessários: No mesmo diretório, crie dois arquivos:
requirements.txt
: Contém as dependências do Python, comoFlask
(exemplo):1
flask
app.py
: Um simples servidor Flask:1 2 3 4 5 6 7 8 9
from flask import Flask app = Flask(__name__) @app.route('/') def home(): return "Hello, Docker!" if __name__ == "__main__": app.run(host="0.0.0.0", port=5000)
Construindo a Imagem com docker build
Agora que temos nosso Dockerfile e arquivos da aplicação, vamos construir a imagem.
-
Construa a Imagem: No terminal, execute o comando abaixo para criar uma imagem a partir do Dockerfile:
1
docker build -t minha-imagem-python .
- -t: Atribui um nome/tag à imagem (
minha-imagem-python
). - .: Indica o diretório atual como contexto para a construção da imagem.
- -t: Atribui um nome/tag à imagem (
-
Verifique a Imagem: Após a construção, verifique se a imagem foi criada com sucesso:
1
docker images
Você verá a imagem
minha-imagem-python
listada entre as imagens disponíveis.
Executando o Container a Partir da Imagem Criada
Agora vamos executar um container com base na nova imagem.
1
docker run -d -p 5000:5000 minha-imagem-python
- -d: Inicia o container em modo detached (background).
- -p 5000:5000: Mapeia a porta 5000 do container para a porta 5000 do host.
Acesse http://localhost:5000
no navegador para ver o servidor Flask em execução, que deverá exibir a mensagem “Hello, Docker!”.
Boas Práticas para Dockerfiles
-
Use Imagens Base Específicas: Prefira imagens com versão específica (
python:3.9
em vez depython:latest
) para garantir consistência. - Reduza o Número de Instruções
RUN
: Sempre que possível, combine instruçõesRUN
para reduzir o número de camadas na imagem. Exemplo:1 2 3
RUN apt-get update && \ apt-get install -y pacote1 pacote2 && \ apt-get clean
-
Use
.dockerignore
: Crie um arquivo.dockerignore
para evitar copiar arquivos desnecessários para a imagem, como arquivos temporários ou de configuração do sistema. - Minimize o Tamanho da Imagem: Remova pacotes desnecessários, use imagens mínimas (como
alpine
quando possível) e limpe caches ao final das instruçõesRUN
.
6. Gerenciamento de Volumes no Docker
Objetivo
Ensinar como usar volumes para persistir dados em containers. Volumes são o método recomendado para armazenar dados que precisam sobreviver ao ciclo de vida dos containers.
Por Que Usar Volumes?
Containers são efêmeros por natureza; ao serem removidos, todos os dados internos também são apagados. Volumes permitem que dados sejam mantidos de forma independente do ciclo de vida do container, sendo ideais para aplicações que geram ou manipulam dados, como bancos de dados e sistemas de logs.
Tipos de Armazenamento no Docker
- Volumes: São armazenados em diretórios gerenciados pelo Docker no host e são independentes do sistema de arquivos do container.
- Bind Mounts: Mapeiam um diretório específico do host para o container. São mais dependentes da estrutura do sistema de arquivos do host.
- tmpfs Mounts: Armazenam dados na memória do sistema, sendo úteis para dados temporários.
Nota: Volumes são preferidos em produção, pois são mais seguros, flexíveis e permitem que o Docker gerencie o armazenamento.
Principais Comandos para Gerenciamento de Volumes
Comando | Descrição |
---|---|
docker volume create <nome> |
Cria um novo volume com o nome especificado. |
docker volume ls |
Lista todos os volumes disponíveis. |
docker volume inspect <nome> |
Exibe informações detalhadas sobre um volume. |
docker volume rm <nome> |
Remove um volume não utilizado. |
1. Criando e Listando Volumes
Criar um Volume
Para criar um volume no Docker, use o comando docker volume create
:
1
docker volume create meu_volume
Esse comando cria um volume chamado meu_volume
, que pode ser usado em qualquer container.
Listar Volumes
Para verificar os volumes existentes, use:
1
docker volume ls
Exemplo de Saída:
1
2
DRIVER VOLUME NAME
local meu_volume
2. Montando Volumes em Containers
Para montar um volume em um container, utilize a opção -v
(ou --mount
) no comando docker run
. Vamos fazer isso com um exemplo:
Exemplo: Usando Volumes para Armazenamento Persistente
1
docker run -d -p 8080:80 -v meu_volume:/usr/share/nginx/html nginx
Neste exemplo:
- -v meu_volume:/usr/share/nginx/html: Monta o volume
meu_volume
no diretório/usr/share/nginx/html
dentro do container. Tudo que for salvo neste diretório será mantido mesmo se o container for removido.
3. Bind Mounts: Ligando um Diretório do Host a um Container
Além de volumes, você pode usar bind mounts para ligar diretórios específicos do sistema host ao container. Essa abordagem é útil em ambiente de desenvolvimento, quando é necessário acessar o código local diretamente no container.
1
docker run -d -p 8080:80 -v $(pwd)/site:/usr/share/nginx/html nginx
Neste exemplo:
$(pwd)/site
refere-se ao diretóriosite
no host (no local atual)./usr/share/nginx/html
é o diretório dentro do container.
Nota: Como o bind mount depende da estrutura do host, ele pode ser menos seguro para uso em produção do que volumes.
4. Inspecionando Volumes
Para ver detalhes sobre um volume específico, incluindo o caminho onde ele é armazenado no host, use:
1
docker volume inspect meu_volume
Exemplo de Saída:
1
2
3
4
5
6
7
8
9
10
11
[
{
"CreatedAt": "2023-11-06T12:34:56Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/meu_volume/_data",
"Name": "meu_volume",
"Options": {},
"Scope": "local"
}
]
O campo Mountpoint
mostra onde os dados do volume estão armazenados no host.
5. Excluindo Volumes
Volumes ocupam espaço no sistema, então, é útil remover volumes não utilizados para liberar espaço.
Remover um Volume Específico
1
docker volume rm meu_volume
Remover Volumes “Dangling” (Não Utilizados)
Para excluir volumes que não estão em uso por nenhum container:
1
docker volume prune
Isso remove todos os volumes não utilizados, ajudando a manter o sistema limpo.
7. Rede e Comunicação entre Containers
Objetivo
Demonstrar como criar e gerenciar redes para containers Docker, possibilitando que eles se comuniquem de forma isolada e segura. As redes permitem interconectar containers de uma mesma aplicação e garantir que não interfiram em outras redes do sistema.
Conceitos de Redes no Docker
O Docker oferece vários tipos de redes, cada uma com características específicas:
-
Bridge (Ponte): Rede padrão usada para containers no modo standalone. Ideal para containers que precisam se comunicar apenas dentro do mesmo host.
-
Host: Permite que o container compartilhe a mesma interface de rede do host. É útil quando você deseja máxima performance de rede ou precisa de integração direta com o host.
-
None: Não configura nenhuma rede para o container, deixando-o isolado sem interface de rede. Útil para segurança em processos que não requerem comunicação externa.
-
Overlay: Usado em configurações de orquestração (como Docker Swarm ou Kubernetes) para conectar containers em diferentes hosts. Não será abordado neste tutorial básico, pois requer configuração de cluster.
Principais Comandos para Gerenciamento de Redes
Comando | Descrição |
---|---|
docker network create <nome> |
Cria uma nova rede Docker. |
docker network ls |
Lista todas as redes disponíveis. |
docker network inspect <nome> |
Exibe detalhes de uma rede específica. |
docker network connect <nome> |
Conecta um container a uma rede existente. |
docker network disconnect <nome> |
Desconecta um container de uma rede. |
docker network rm <nome> |
Remove uma rede que não esteja sendo usada por containers ativos. |
1. Listando Redes Existentes
Por padrão, o Docker cria algumas redes básicas. Use docker network ls
para visualizá-las:
1
docker network ls
Exemplo de Saída:
1
2
3
4
NETWORK ID NAME DRIVER SCOPE
b12345678901 bridge bridge local
c23456789012 host host local
d34567890123 none null local
- bridge: Rede padrão de ponte para containers isolados.
- host: Rede que compartilha a interface de rede do host.
- none: Rede sem interface, isolando completamente o container.
2. Criando uma Rede Personalizada
Para facilitar a comunicação entre containers, crie uma rede personalizada. Isso é útil para separar grupos de containers e organizar aplicações em microserviços.
1
docker network create minha_rede
Após a criação, a rede minha_rede
estará disponível para conectar containers.
3. Conectando Containers a uma Rede
Ao iniciar um container, você pode conectá-lo diretamente a uma rede específica usando o parâmetro --network
. Vamos ver um exemplo de como conectar dois containers (um servidor web e um banco de dados) para que eles possam se comunicar.
Exemplo: Criando um Container MySQL e um Container NGINX
- Inicie o Container do MySQL na Rede Personalizada:
1
docker run -d --name mysql_container --network minha_rede -e MYSQL_ROOT_PASSWORD=senha mysql:5.7
Neste exemplo:
- –network minha_rede: Conecta o container à rede
minha_rede
. - MYSQL_ROOT_PASSWORD: Define a senha do usuário
root
no MySQL.
- –network minha_rede: Conecta o container à rede
- Inicie o Container NGINX na Mesma Rede:
1
docker run -d --name nginx_container --network minha_rede -p 8080:80 nginx
Neste caso, os containers
nginx_container
emysql_container
estão na mesma rede (minha_rede
) e, portanto, podem se comunicar usando seus nomes de container como endereço de rede.
4. Comunicação entre Containers na Mesma Rede
Quando containers estão na mesma rede, eles podem se comunicar usando os nomes dos containers como hostname. No exemplo acima:
- O container NGINX pode acessar o MySQL através de
mysql_container:3306
(3306 é a porta padrão do MySQL). - O nome
mysql_container
será resolvido automaticamente na rede Docker.
Para testar a conexão entre containers, você pode acessar o container NGINX e tentar um comando de conexão:
1
docker exec -it nginx_container ping mysql_container
Este comando verifica se o nginx_container
consegue se comunicar com o mysql_container
pela rede minha_rede
.
5. Inspecionando uma Rede
Para obter detalhes sobre uma rede, incluindo quais containers estão conectados, use:
1
docker network inspect minha_rede
Isso exibe informações como ID da rede, drivers, containers conectados e configurações de IP.
6. Desconectando e Removendo Redes
- Desconectar um Container de uma Rede:
1
docker network disconnect minha_rede nginx_container
- Remover uma Rede:
1
docker network rm minha_rede
Nota: Só é possível remover uma rede que não esteja sendo utilizada por nenhum container ativo.
8. Docker Compose: Orquestrando Múltiplos Containers
Objetivo
Apresentar o Docker Compose para gerenciar e orquestrar aplicações multi-containers. Com o Docker Compose, você poderá configurar a aplicação, definir redes e volumes, e gerenciar múltiplos containers de forma simplificada.
Instalando o Docker Compose
- Verificar se o Docker Compose já está instalado:
1
docker-compose --version
Caso o Docker Compose esteja instalado, este comando exibirá a versão atual.
-
Instalação no Linux: Se o Docker Compose não estiver instalado, baixe-o com o comando:
1
sudo curl -L "https://github.com/docker/compose/releases/download/$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- Conceder Permissão de Execução:
1
sudo chmod +x /usr/local/bin/docker-compose
- Verificar a Instalação:
1
docker-compose --version
Estrutura do Arquivo docker-compose.yml
O Docker Compose usa um arquivo docker-compose.yml
para definir serviços, redes e volumes necessários para a aplicação. Vamos examinar a estrutura básica desse arquivo e como ele é usado para criar e conectar containers.
Exemplo de Arquivo docker-compose.yml
Suponha que queremos configurar uma aplicação com dois serviços: um servidor web NGINX e um banco de dados MySQL. O arquivo docker-compose.yml
terá a seguinte estrutura:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
version: '3.8'
services:
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: senha
MYSQL_DATABASE: exemplo_db
volumes:
- db_data:/var/lib/mysql
networks:
- app_network
web:
image: nginx
ports:
- "8080:80"
depends_on:
- db
networks:
- app_network
volumes:
db_data:
networks:
app_network:
Explicação do Arquivo
-
version: Define a versão do Compose YAML. A versão
3.8
é comum para funcionalidades avançadas. - services:
- db: Define o serviço do banco de dados MySQL.
- image: Especifica a imagem Docker (neste caso,
mysql:5.7
). - environment: Variáveis de ambiente para configuração do MySQL (senha e nome do banco).
- volumes: Monta o volume
db_data
para persistência de dados no diretório do MySQL (/var/lib/mysql
). - networks: Conecta o serviço
db
à redeapp_network
.
- image: Especifica a imagem Docker (neste caso,
- web: Define o serviço NGINX para servir conteúdo web.
- ports: Mapeia a porta 8080 no host para a porta 80 no container.
- depends_on: Garante que o serviço
db
seja iniciado antes deweb
. - networks: Conecta o serviço
web
à redeapp_network
.
- db: Define o serviço do banco de dados MySQL.
- volumes:
- db_data: Define um volume Docker para persistência de dados do banco.
- networks:
- app_network: Define uma rede para permitir comunicação entre os serviços
web
edb
.
- app_network: Define uma rede para permitir comunicação entre os serviços
Comandos Básicos do Docker Compose
Comando | Descrição |
---|---|
docker-compose up |
Cria e inicia todos os serviços definidos no docker-compose.yml . |
docker-compose down |
Interrompe e remove os containers, redes e volumes criados pelo Compose. |
docker-compose ps |
Lista os containers que estão sendo gerenciados pelo Compose. |
docker-compose logs |
Exibe logs dos serviços em execução. |
docker-compose exec <service> |
Executa comandos em um container gerenciado pelo Compose. |
1. Iniciando a Aplicação com docker-compose up
Execute o comando abaixo no diretório onde está o arquivo docker-compose.yml
:
1
docker-compose up -d
- -d: Executa em modo detached (background).
Este comando inicia os serviços db
e web
e cria a rede e volume definidos no arquivo Compose. Após a execução, você pode acessar o servidor NGINX em http://localhost:8080
.
2. Visualizando os Containers em Execução
Para listar os containers em execução pelo Compose, use:
1
docker-compose ps
Exemplo de Saída:
1
2
3
4
Name Command State Ports
---------------------------------------------------------------------------
myapp_db_1 docker-entrypoint.sh mysqld Up 3306/tcp
myapp_web_1 nginx -g 'daemon off;' Up 0.0.0.0:8080->80/tcp
3. Exibindo Logs dos Containers
Para ver os logs dos containers em execução (útil para depuração), use:
1
docker-compose logs -f
4. Executando Comandos em Containers com docker-compose exec
Para acessar o terminal de um container, por exemplo, o container do MySQL, use:
1
docker-compose exec db /bin/bash
Esse comando abre um terminal dentro do container db
, permitindo que você execute comandos diretamente no ambiente do banco de dados.
5. Parando e Removendo Containers com docker-compose down
Para encerrar a aplicação e remover os containers, redes e volumes criados pelo Docker Compose:
1
docker-compose down
Nota: Para manter os volumes, use
docker-compose down --volumes
apenas quando precisar excluir os dados.
9. Trabalhando com Registries e Docker Hub
Objetivo
Aprender a usar o Docker Hub e registries privados para armazenar e compartilhar imagens Docker, com práticas de autenticação e segurança.
O que é um Registry?
Um registry é um serviço para armazenar e distribuir imagens Docker. Existem registries públicos, como o Docker Hub, e registries privados, que são úteis para ambientes corporativos onde o controle de acesso é necessário.
Docker Hub
O Docker Hub é o registry público padrão, que permite armazenar, compartilhar e acessar imagens de forma aberta ou privada. Com o Docker Hub, você pode:
- Armazenar suas imagens em repositórios públicos ou privados.
- Controlar versões de imagens.
- Compartilhar imagens com outras pessoas ou equipes.
Principais Comandos para Gerenciamento de Imagens em Registries
Comando | Descrição |
---|---|
docker login |
Faz login no Docker Hub ou em outro registry especificado. |
docker logout |
Faz logout do Docker Hub ou de um registry. |
docker pull <imagem> |
Baixa uma imagem de um registry (público ou privado). |
docker push <imagem> |
Envia uma imagem para um registry (Docker Hub ou privado). |
docker tag <imagem> <novo_nome> |
Marca uma imagem para organização e envio ao registry. |
1. Configurando o Docker Hub
Passo 1: Criar uma Conta no Docker Hub
Se você ainda não possui uma conta, acesse Docker Hub e crie uma conta. É gratuita e fornece acesso a repositórios públicos e uma opção limitada para repositórios privados.
Passo 2: Fazer Login no Docker Hub
No terminal, faça login no Docker Hub:
1
docker login
Você será solicitado a inserir seu username e password. Após o login, o Docker pode acessar e enviar imagens diretamente para sua conta do Docker Hub.
2. Publicando Imagens no Docker Hub
Para compartilhar uma imagem, você precisa enviá-la ao Docker Hub. Vamos usar um exemplo prático para fazer isso.
Exemplo: Enviando uma Imagem para o Docker Hub
-
Nomear a Imagem com seu Nome de Usuário Antes de enviar, renomeie a imagem no formato
<username>/<nome_imagem>:<tag>
. Usedocker tag
para isso:1
docker tag minha-imagem:latest seu_usuario_dockerhub/minha-imagem:latest
-
Enviar a Imagem com
docker push
Agora você pode enviar a imagem para o Docker Hub:1
docker push seu_usuario_dockerhub/minha-imagem:latest
Após o upload, a imagem estará disponível no Docker Hub em
https://hub.docker.com/r/seu_usuario_dockerhub/minha-imagem
.
3. Baixando Imagens de Registries Públicos e Privados
Para baixar uma imagem, use o comando docker pull
com o nome da imagem e a tag, caso necessário.
1
docker pull nginx:latest
Se a imagem for de um registry privado, você precisará fazer login nesse registry primeiro com docker login <url_do_registry>
.
4. Criando e Configurando um Registry Privado
Se sua equipe ou empresa preferir não usar o Docker Hub, é possível configurar um registry privado localmente ou em um servidor próprio. O Docker fornece uma imagem oficial para isso.
Passo 1: Iniciar um Registry Privado com Docker
Execute o seguinte comando para iniciar um registry local:
1
docker run -d -p 5000:5000 --name meu_registry registry:2
- registry:2 é a imagem oficial do Docker para configurar registries privados.
- A porta 5000 é o padrão, mas pode ser alterada se necessário.
Passo 2: Enviar Imagens para o Registry Privado
-
Marcar a Imagem para o Registry Local Renomeie a imagem no formato
<host>:<porta>/<nome_imagem>
:1
docker tag minha-imagem localhost:5000/minha-imagem
-
Enviar a Imagem para o Registry Privado Use o comando
docker push
para enviar a imagem:1
docker push localhost:5000/minha-imagem
Passo 3: Baixar Imagens do Registry Privado
Para baixar a imagem de volta do registry privado, use docker pull
:
1
docker pull localhost:5000/minha-imagem
Nota: Em ambientes de produção, o registry privado deve ser configurado com HTTPS para garantir a segurança dos dados transmitidos. Também é recomendável usar autenticação para controlar o acesso.
5. Práticas de Segurança para Imagens e Registries
-
Usar HTTPS: Sempre configure o registry privado com HTTPS para proteger as imagens e os dados de configuração.
-
Autenticação e Controle de Acesso: Em registries privados, configure autenticação para limitar o acesso a usuários autorizados.
-
Manter Imagens Atualizadas: Periodicamente, verifique e atualize imagens para aplicar correções de segurança.
-
Escanear Imagens: O Docker Hub e outros registries privados suportam escaneamento de imagens para vulnerabilidades de segurança. Utilize essa funcionalidade para garantir que suas imagens estejam seguras.
10. Otimização e Melhores Práticas com Containers
Objetivo
Explorar práticas recomendadas para otimização e segurança ao trabalhar com Docker. Isso inclui maneiras de reduzir o tamanho das imagens, controlar o uso de recursos, e dicas para tornar o ambiente de containers mais seguro.
1. Otimização do Tamanho das Imagens Docker
Imagens menores são mais rápidas de transferir, menos custosas para armazenar e mais eficientes em termos de uso de recursos. Algumas práticas recomendadas incluem:
-
Escolher Imagens Base Leves: Sempre que possível, use imagens mínimas como
alpine
, que têm um tamanho reduzido (por exemplo,python:alpine
em vez depython:latest
). -
Combinar Instruções
RUN
: Para reduzir a quantidade de camadas e o tamanho final da imagem, combine múltiplos comandosRUN
em uma única instrução. Por exemplo:1 2 3
RUN apt-get update && \ apt-get install -y pacote1 pacote2 && \ rm -rf /var/lib/apt/lists/*
-
Remover Arquivos Desnecessários: Limpe caches e remova pacotes desnecessários após a instalação, como no exemplo acima. Isso garante que não restem dados que ocupem espaço sem necessidade.
-
Utilizar Multistage Builds: Divida a construção de imagens em estágios quando precisar compilar código ou instalar dependências grandes. A imagem final incluirá apenas os arquivos e pacotes essenciais para a execução.
Exemplo de Multistage Build:
1 2 3 4 5 6 7 8
FROM golang:1.18 as builder WORKDIR /app COPY . . RUN go build -o myapp FROM alpine COPY --from=builder /app/myapp /myapp CMD ["/myapp"]
Neste exemplo, o código é compilado em uma imagem
golang
, mas a imagem final usaalpine
, resultando em um tamanho muito menor.
2. Limitação de Recursos (CPU e Memória)
Docker permite controlar o uso de recursos de CPU e memória, evitando que um container consuma recursos excessivos do sistema, o que é especialmente útil em ambientes multi-tenant.
-
Limitar CPU: Para definir um limite de CPU, use
--cpus
. Por exemplo, para limitar um container a usar no máximo 1.5 CPU:1
docker run --cpus="1.5" minha-imagem
-
Limitar Memória: Para limitar a memória disponível para um container, use
--memory
. Por exemplo, para limitar a 512 MB:1
docker run --memory="512m" minha-imagem
Essas restrições ajudam a evitar que um container monopolize recursos, garantindo uma performance equilibrada entre múltiplos containers.
3. Dicas de Segurança para Containers Docker
A segurança é um aspecto fundamental no uso de containers, especialmente quando eles estão em produção. Aqui estão algumas práticas para aumentar a segurança dos containers:
-
Use Imagens Oficiais e Verificadas: Sempre que possível, utilize imagens oficiais ou de fontes confiáveis, que passam por validações e atualizações de segurança constantes.
-
Escanear Imagens para Vulnerabilidades: Muitas ferramentas, como o Docker Hub e o Snyk, oferecem escaneamento de vulnerabilidades. Use esses escaneamentos regularmente para identificar e corrigir problemas de segurança em suas imagens.
-
Evitar Rodar Containers com Privilégios Elevados: Evite usar o
--privileged
e, sempre que possível, configure o usuário com menos permissões dentro do container usando a instruçãoUSER
no Dockerfile:1 2
RUN adduser -D appuser USER appuser
-
Configurar Variáveis de Ambiente Sensíveis com Cuidado: Evite armazenar informações sensíveis diretamente no Dockerfile. Prefira armazenar variáveis sensíveis em arquivos seguros ou definir variáveis de ambiente no momento da execução:
1
docker run -e DB_PASSWORD=$(cat /secrets/db_password) minha-imagem
-
Isolar Containers com Redes Customizadas: Evite usar a rede
host
, a menos que seja absolutamente necessário, e crie redes Docker customizadas para isolar os containers.
4. Limpeza de Imagens e Containers Não Utilizados
Com o tempo, o sistema acumula containers, imagens, volumes e redes que não são mais necessários. Docker oferece comandos para limpar automaticamente esses recursos, liberando espaço e mantendo o ambiente organizado:
-
Remover Containers Parados:
1
docker container prune
-
Remover Imagens Sem Tag (Dangling):
1
docker image prune
-
Remover Volumes Não Utilizados:
1
docker volume prune
-
Remover Todos os Recursos Não Utilizados:
1
docker system prune
Esses comandos ajudam a evitar o desperdício de recursos e manter o ambiente Docker limpo.
5. Monitoramento e Logging de Containers
Para garantir que os containers estão funcionando corretamente, é importante monitorar o uso de recursos e capturar logs.
-
Monitorar Uso de Recursos com
docker stats
:1
docker stats
Esse comando exibe o uso de CPU, memória, e rede dos containers em tempo real, o que é útil para detectar problemas de performance.
-
Capturar Logs de Containers:
1
docker logs <container_id>
Esse comando exibe os logs do container especificado, permitindo identificar erros e verificar a saída da aplicação.
Dica Avançada: Ferramentas como Prometheus e Grafana podem ser integradas ao Docker para monitoramento avançado de métricas e logs.
11. Monitoramento e Log de Containers
Objetivo
Ensinar como monitorar o uso de recursos dos containers e acessar seus logs. Além disso, abordaremos a integração com ferramentas externas, como Prometheus e Grafana, para monitoramento avançado.
1. Monitorando Containers com Docker
Docker oferece alguns comandos nativos para monitorar o desempenho e a atividade dos containers.
Verificar o Status dos Containers com docker ps
O comando docker ps
exibe o status dos containers em execução, incluindo o nome, ID, uptime e portas expostas. Para ver todos os containers, inclusive os parados, use -a
.
1
docker ps
Monitorar o Uso de Recursos com docker stats
O comando docker stats
exibe informações em tempo real sobre o uso de CPU, memória, I/O de rede e I/O de disco para cada container em execução.
1
docker stats
Exemplo de Saída:
1
2
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
1a2b3c4d5e6f web_app 2.13% 50.18MiB / 500MiB 10.04% 800kB / 1MB 0B / 0B 8
Isso permite identificar containers que consomem muitos recursos e ajuda a detectar gargalos.
2. Capturando Logs de Containers com Docker
Os logs dos containers são fundamentais para entender o comportamento da aplicação e diagnosticar erros.
Visualizar Logs com docker logs
Para visualizar os logs de um container específico, use:
1
docker logs <container_id>
- -f: Segue os logs em tempo real, similar ao
tail -f
. - –tail: Exibe apenas as últimas linhas dos logs.
1
docker logs -f --tail 100 <container_id>
Este comando é útil para acompanhar a saída da aplicação em tempo real e verificar qualquer erro que ocorra durante a execução.
3. Monitoramento Avançado com Ferramentas Externas
Em ambientes de produção, é recomendável usar ferramentas de monitoramento dedicadas para acompanhar métricas e logs de containers. Vamos ver como integrar o Docker com duas ferramentas populares: Prometheus e Grafana.
Configuração do Prometheus para Monitoramento de Containers
-
Iniciar o Container do Prometheus
Crie um arquivo de configuração
prometheus.yml
para o Prometheus e inclua o seguinte conteúdo básico:1 2 3 4 5 6 7
global: scrape_interval: 5s scrape_configs: - job_name: 'docker' static_configs: - targets: ['host.docker.internal:9323']
Esse arquivo define um job para monitorar o Docker a cada 5 segundos.
-
Executar o Exporter do Docker para Prometheus
O Docker não expõe diretamente suas métricas para o Prometheus. É necessário usar o Docker Exporter (como o
prom/node-exporter
ouprom/dockerd-exporter
):1
docker run -d -p 9323:9323 --name node-exporter prom/node-exporter
-
Iniciar o Container do Prometheus
Execute o Prometheus apontando para o arquivo de configuração criado:
1
docker run -d -p 9090:9090 -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml --name prometheus prom/prometheus
Após a configuração, você pode acessar o Prometheus em
http://localhost:9090
para verificar as métricas dos containers.
Integração com Grafana para Visualização de Métricas
-
Iniciar o Container do Grafana
Grafana é uma plataforma de visualização de dados que se integra facilmente com Prometheus. Para iniciar o Grafana, execute:
1
docker run -d -p 3000:3000 --name grafana grafana/grafana
-
Configurar o Grafana para Usar o Prometheus como Fonte de Dados
- Acesse o Grafana em
http://localhost:3000
(usuário padrão:admin
, senha:admin
). - Adicione o Prometheus como fonte de dados (
Settings
->Data Sources
->Add data source
). - Use
http://host.docker.internal:9090
como a URL do Prometheus.
- Acesse o Grafana em
-
Criar Dashboards para Monitorar Containers
Após configurar a fonte de dados, você pode importar dashboards prontos para monitorar Docker. O Grafana tem templates prontos para visualizar o uso de CPU, memória, disco e rede dos containers.
4. Ferramentas para Logging Centralizado
Além das métricas, centralizar e organizar logs é fundamental para análise e troubleshooting. Ferramentas populares para gerenciamento de logs incluem ELK Stack (Elasticsearch, Logstash, e Kibana) e Graylog.
Configuração Básica com ELK Stack
-
Instalar e Configurar o Logstash
O Logstash coleta e processa logs dos containers. Configure-o para receber logs do Docker e enviá-los para o Elasticsearch.
-
Armazenamento de Logs no Elasticsearch
O Elasticsearch armazena e indexa logs, permitindo consultas rápidas.
-
Visualização de Logs com Kibana
Kibana permite visualizar e explorar logs. Com a integração com o Elasticsearch, você pode criar gráficos e filtros para analisar logs dos containers em tempo real.
Dica: Para facilitar, você pode rodar o ELK Stack com Docker Compose, que permite iniciar todos os serviços com um único comando.
12. Salvando e Carregando Imagens e Containers
Objetivo
Demonstrar como exportar e importar imagens e containers para backup, migração e compartilhamento de ambientes. Esses métodos ajudam a criar snapshots e mover aplicativos Docker entre máquinas ou ambientes.
1. Salvando e Carregando Imagens
As imagens Docker podem ser salvas em um arquivo para backup ou transferência, e posteriormente carregadas em qualquer ambiente Docker compatível.
Salvando uma Imagem com docker save
O comando docker save
permite exportar uma imagem para um arquivo .tar
. Isso é útil para compartilhar a imagem sem usar um registry ou para backup.
1
docker save -o minha_imagem_backup.tar minha-imagem:latest
- -o: Especifica o arquivo de saída (neste caso,
minha_imagem_backup.tar
). - minha-imagem:latest: Nome e tag da imagem a ser exportada.
Esse comando cria o arquivo minha_imagem_backup.tar
, que contém todos os dados da imagem. Esse arquivo pode ser movido para outra máquina ou mantido como um backup.
Carregando uma Imagem com docker load
Para restaurar ou carregar uma imagem salva com docker save
, use o comando docker load
:
1
docker load -i minha_imagem_backup.tar
- -i: Especifica o arquivo de entrada (neste caso,
minha_imagem_backup.tar
).
Após o comando, a imagem estará disponível localmente e poderá ser listada com docker images
.
2. Exportando e Importando Containers
Além de imagens, você pode exportar o sistema de arquivos de um container em execução para compartilhá-lo com outra máquina ou usá-lo como base para novos containers.
Exportando um Container com docker export
O comando docker export
cria um arquivo .tar
com o sistema de arquivos completo de um container específico, mas sem as camadas de imagem e histórico de construção.
1
docker export -o meu_container_backup.tar <container_id>
- -o: Define o arquivo de saída (
meu_container_backup.tar
). - **
**: ID ou nome do container que será exportado.
Esse arquivo contém o sistema de arquivos do container, mas não inclui informações sobre a imagem ou o histórico.
Importando um Container com docker import
Para carregar o sistema de arquivos exportado em uma nova imagem, use o comando docker import
:
1
docker import meu_container_backup.tar minha-nova-imagem
Esse comando cria uma nova imagem chamada minha-nova-imagem
a partir do arquivo meu_container_backup.tar
. Essa imagem pode ser usada para iniciar novos containers com docker run
.
3. Exemplo Completo: Migrando um Container Entre Máquinas
Suponha que você queira mover um container específico de uma máquina para outra. Abaixo está o processo passo a passo:
- Exportar o Container na Máquina de Origem:
1
docker export -o meu_container_backup.tar <container_id>
-
Transferir o Arquivo para a Máquina de Destino: Você pode transferir o arquivo usando
scp
,rsync
, ou até mesmo por armazenamento externo. - Importar o Container na Máquina de Destino:
Na máquina de destino, importe o arquivo como uma nova imagem:
1
docker import meu_container_backup.tar nova-imagem
- Iniciar um Novo Container a Partir da Imagem:
Agora que a imagem foi carregada, inicie um container usando-a:
1
docker run -d --name novo_container nova-imagem
Este processo cria um container idêntico ao original, permitindo a continuidade do serviço em outra máquina.
4. Backups de Volumes Docker
Além de imagens e containers, os volumes Docker que armazenam dados persistentes também podem ser exportados e importados.
Backup de um Volume com tar
Suponha que temos um volume chamado meu_volume
. Podemos fazer um backup de seu conteúdo com tar
:
1
docker run --rm -v meu_volume:/volume -v $(pwd):/backup alpine tar -czf /backup/meu_volume_backup.tar.gz -C /volume .
Esse comando cria um arquivo .tar.gz
do volume meu_volume
, armazenado no diretório atual.
Restaurar um Volume de Backup
Para restaurar o volume a partir do backup, use:
1
docker run --rm -v meu_volume:/volume -v $(pwd):/backup alpine tar -xzf /backup/meu_volume_backup.tar.gz -C /volume
Esse comando extrai o conteúdo do arquivo de backup para o volume, restaurando os dados.
5. Salvando e Carregando Todos os Recursos com docker-compose
Se você trabalha com várias imagens e containers, como em um ambiente Docker Compose, o processo de exportação e importação pode ser facilitado com scripts e comandos de backup para todos os recursos.
Exemplo de Script Básico para Exportação:
Este script faz backup das imagens e dos volumes de uma configuração Docker Compose:
1
2
3
4
5
6
7
8
9
# Salva todas as imagens
docker-compose images | awk '{print $2}' | tail -n +2 | while read image; do
docker save -o "${image}.tar" "${image}"
done
# Salva os volumes
docker volume ls | awk '{print $2}' | tail -n +2 | while read volume; do
docker run --rm -v ${volume}:/volume -v $(pwd):/backup alpine tar -czf "/backup/${volume}.tar.gz" -C /volume .
done
13. Troubleshooting e Solução de Problemas Comuns no Docker
Objetivo
Identificar e resolver problemas comuns ao trabalhar com Docker. Aprender a diagnosticar problemas de rede, permissões e execução de containers é essencial para manter o ambiente Docker em bom funcionamento.
1. Ferramentas para Diagnóstico e Solução de Problemas
Docker fornece alguns comandos e opções úteis para inspecionar containers e identificar a causa de problemas.
Comando | Descrição |
---|---|
docker inspect <container> |
Exibe detalhes completos do container, incluindo rede e variáveis de ambiente. |
docker logs <container> |
Exibe os logs de execução do container. |
docker exec -it <container> /bin/bash |
Permite acessar o terminal do container para investigação. |
docker events |
Monitora eventos em tempo real do Docker, útil para ver logs do daemon. |
2. Verificando Problemas de Rede
Problema Comum: Containers não Conseguem se Comunicar
Quando containers em uma mesma rede não conseguem se comunicar, verifique:
-
Conexão na Mesma Rede: Confirme que os containers estão conectados à mesma rede. Use o comando:
1
docker network inspect <nome_da_rede>
-
Firewall ou Políticas de Segurança: Verifique se há regras de firewall bloqueando a comunicação entre containers. Isso pode acontecer em redes bridge customizadas.
-
Testando a Conexão Entre Containers: Use o comando
ping
entre containers para testar a conectividade.1
docker exec -it <container1> ping <container2>
Se a comunicação não for possível, recrie a rede e reconecte os containers.
Problema Comum: Conexão Externa ao Container
Se você não consegue acessar o container externamente (por exemplo, o NGINX rodando em localhost:8080
), verifique:
-
Portas Mapeadas Corretamente: Confirme se as portas foram mapeadas corretamente usando
docker ps
. Por exemplo, para mapear a porta 80 do container para a porta 8080 do host:1
docker run -d -p 8080:80 nginx
-
Firewall do Host: Certifique-se de que o firewall do sistema não está bloqueando a porta. No Linux, verifique com
sudo ufw status
.
3. Problemas de Permissão
Erro Comum: Permission Denied
ao Executar Docker Sem sudo
Se você não consegue executar o Docker sem sudo
, provavelmente o usuário não está no grupo Docker. Para resolver:
-
Adicione o usuário ao grupo Docker:
1
sudo usermod -aG docker $USER
-
Reinicie a sessão para aplicar as alterações:
1
newgrp docker
Erro Comum: Permission Denied
ao Acessar Arquivos em Containers
Isso geralmente ocorre ao usar bind mounts com permissões diferentes entre o host e o container. Tente:
-
Definir Permissões Corretas no Host: Altere as permissões do diretório no host para o usuário que o container usa:
1
sudo chown -R 1000:1000 /caminho/para/diretorio
-
Executar o Container com Permissões Adequadas: Use a opção
--user
nodocker run
para especificar o usuário.
4. Problemas de Execução de Containers
Erro Comum: Container Exited with Code 1
Esse erro indica que o container parou devido a um erro na aplicação ou na configuração. Para resolver:
-
Verifique os Logs do Container: O comando
docker logs <container>
fornece informações sobre o que causou a saída. -
Rever o Comando de Inicialização: Verifique o comando
CMD
ouENTRYPOINT
no Dockerfile ou Compose e certifique-se de que está correto.
Erro Comum: Container Reiniciando Constantemente
Esse problema pode ocorrer se o container estiver configurado para reiniciar automaticamente, mas o comando principal falha repetidamente. Para investigar:
- Verifique os Logs do Container:
1
docker logs <container>
- Desative o Restart Automático Temporariamente:
1
docker update --restart=no <container>
-
Inicie Manualmente para Debug: Execute o container em modo interativo para verificar a execução do comando principal.
1
docker run -it <imagem> /bin/bash
5. Problemas ao Construir Imagens
Erro Comum: No Space Left on Device
Esse erro ocorre quando não há espaço suficiente para o Docker criar novas camadas de imagem. Para resolver:
-
Limpar Containers, Imagens e Volumes Não Utilizados:
1
docker system prune -a
Esse comando remove todas as imagens, containers, volumes e redes não utilizados, liberando espaço.
Erro Comum: Cannot Find Package
ao Instalar Dependências
Esse erro é comum ao construir imagens com pacotes específicos que requerem atualização. Verifique:
-
Atualização de Pacotes no Dockerfile:
1
RUN apt-get update && apt-get install -y <pacote>
Certifique-se de incluir apt-get update
para garantir que a lista de pacotes está atualizada antes de instalar.
6. Ferramentas para Solução de Problemas Avançados
Além dos comandos nativos, algumas ferramentas ajudam a solucionar problemas complexos:
-
Dive: Analisa camadas de uma imagem Docker, permitindo identificar grandes arquivos e camadas desnecessárias.
1
dive <imagem>
-
ctop: Exibe métricas de uso de recursos em containers, similar ao comando
top
do Linux, mas focado em containers. -
Sysdig: Ferramenta de análise e monitoramento que permite inspecionar containers, detectar falhas e verificar logs em detalhes.
14. Casos de Uso Avançados e Integração com CI/CD
Objetivo
Apresentar práticas avançadas para o uso de Docker em pipelines de CI/CD. Isso inclui a automação de builds, testes e deploys de containers, integrando Docker com plataformas de CI/CD como GitLab CI, Jenkins e GitHub Actions.
1. Docker em Pipelines de CI/CD
O uso do Docker em CI/CD oferece diversas vantagens, como isolamento de ambiente e consistência entre diferentes etapas do pipeline. Em geral, um pipeline com Docker tem as seguintes etapas:
- Build: Compila a aplicação e cria a imagem Docker.
- Test: Executa testes dentro de containers.
- Push: Envia a imagem para um registry (Docker Hub ou privado).
- Deploy: Implanta a imagem em um ambiente de produção ou staging.
2. Configuração Básica de Docker no GitLab CI
O GitLab CI é uma das ferramentas de CI/CD que possui integração nativa com Docker. Abaixo está um exemplo de configuração de pipeline CI/CD para uma aplicação que usa Docker no GitLab.
Criando o Arquivo .gitlab-ci.yml
Esse arquivo define o pipeline e as etapas do CI/CD no GitLab.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
stages:
- build
- test
- push
# Variáveis (substitua "meu_usuario" e "minha_imagem" conforme necessário)
variables:
DOCKER_REGISTRY: "registry.gitlab.com"
DOCKER_IMAGE: "$DOCKER_REGISTRY/meu_usuario/minha_imagem"
build:
stage: build
image: docker:latest
services:
- docker:dind
script:
- docker build -t $DOCKER_IMAGE:latest .
test:
stage: test
image: docker:latest
services:
- docker:dind
script:
- docker run --rm $DOCKER_IMAGE:latest pytest
push:
stage: push
image: docker:latest
services:
- docker:dind
script:
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $DOCKER_REGISTRY
- docker push $DOCKER_IMAGE:latest
Explicação das Etapas
- build: A etapa
build
cria a imagem Docker da aplicação usando o Dockerfile. - test: A etapa
test
executa os testes. No exemplo, estamos rodando opytest
, mas você pode ajustar para qualquer ferramenta de testes. - push: Envia a imagem Docker para o Docker registry, tornando-a disponível para deploy.
Nota: As variáveis
$CI_REGISTRY_USER
e$CI_REGISTRY_PASSWORD
são configuradas no GitLab CI para autenticação automática.
3. Configuração de Docker no Jenkins
O Jenkins é uma ferramenta de CI/CD amplamente utilizada e suporta o uso de Docker para pipelines de construção e deploy.
Configurando um Pipeline Declarativo no Jenkins
Para configurar um pipeline Docker no Jenkins, você pode usar o arquivo Jenkinsfile
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
pipeline {
agent any
environment {
DOCKER_IMAGE = 'meu_usuario/minha_imagem:latest'
}
stages {
stage('Build') {
steps {
script {
docker.build("$DOCKER_IMAGE")
}
}
}
stage('Test') {
steps {
script {
docker.image("$DOCKER_IMAGE").inside {
sh 'pytest'
}
}
}
}
stage('Push') {
steps {
withCredentials([usernamePassword(credentialsId: 'docker-hub-credentials', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
sh "echo $PASSWORD | docker login -u $USERNAME --password-stdin"
sh "docker push $DOCKER_IMAGE"
}
}
}
}
}
Explicação das Etapas
- Build: Compila a imagem Docker usando o Dockerfile.
- Test: Executa os testes dentro do container.
- Push: Envia a imagem Docker para o Docker Hub ou um registry privado, autenticando-se com credenciais armazenadas no Jenkins.
4. Usando Docker com GitHub Actions
GitHub Actions é uma alternativa popular para pipelines CI/CD, integrada ao GitHub. Ela permite automatizar o build e o deploy de projetos diretamente a partir do repositório.
Criando um Workflow no GitHub Actions
Para configurar um workflow, crie um arquivo YAML em .github/workflows/docker-ci.yml
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
name: Docker CI/CD
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: $
password: $
- name: Build and Push Docker image
uses: docker/build-push-action@v2
with:
push: true
tags: meu_usuario/minha_imagem:latest
Explicação das Etapas
- Checkout Code: Acessa o código do repositório.
- Set up Docker Buildx: Prepara o ambiente Docker.
- Login to Docker Hub: Autentica no Docker Hub usando variáveis secretas do GitHub (
DOCKER_USERNAME
eDOCKER_PASSWORD
). - Build and Push Docker image: Compila e envia a imagem para o Docker Hub.
Dica: No GitHub, você pode configurar variáveis secretas nas configurações do repositório.
5. Práticas Avançadas para Docker em CI/CD
-
Usar Multistage Builds: Em pipelines, as builds multi-estágio ajudam a reduzir o tempo de construção e o tamanho das imagens, especialmente em ambientes de CI/CD onde a velocidade é essencial.
-
Testar e Validar a Imagem Docker: Inclua etapas de validação para garantir que a imagem criada está funcionando corretamente antes do deploy. Isso pode incluir testes de unidade, integração e até varredura de segurança.
-
Automatizar Deploy em Kubernetes: Em ambientes de produção que usam Kubernetes, configure uma etapa de deploy ao final do pipeline, aplicando o YAML de configuração do Kubernetes para atualizar a aplicação automaticamente.
-
Usar Tags para Controle de Versionamento: Adote uma convenção de tags para diferenciar versões, como
:latest
,:staging
, ou versões específicas (:v1.0.0
). Isso facilita a organização e o rollback em caso de problemas.
Conclusão
Neste tutorial, percorremos uma jornada completa pelo universo Docker, explorando desde os conceitos iniciais até as práticas avançadas para ambientes de produção. Agora, você está capacitado para criar, gerenciar e otimizar containers, redes e volumes, além de integrar Docker em pipelines de CI/CD. Esse conhecimento permitirá que você entregue aplicações com maior consistência, segurança e eficiência.
O Docker é uma ferramenta poderosa que continua a evoluir, oferecendo cada vez mais recursos para equipes de desenvolvimento e operações. A prática constante e a exploração de novos recursos serão fundamentais para aproveitar ao máximo seu potencial. Esperamos que este guia seja uma base sólida para o seu trabalho com Docker e que o inspire a continuar aprimorando suas habilidades em DevOps e automação.
Seja no desenvolvimento local ou em ambientes complexos de produção, o Docker oferece a flexibilidade e a escalabilidade necessárias para os desafios modernos de software. Aproveite este conhecimento e boas práticas para levar seus projetos ao próximo nível!