Arquitetura e Componentes Fundamentais
O ecossistema Docker opera através de uma arquitetura cliente-servidor projetada para empacotar aplicações e suas dependências em ambientes isolados. Os componentes estruturais incluem:
- Imagens (Images): Modelos estáticos e imutáveis que contêm o sistema de arquivos, bibliotecas, variáveis de ambiente e configurações necessárias para executar uma aplicação.
- Contêineres (Containers): Instâncias em tempo de execução derivadas de uma imagem. Possuem seu próprio espaço de processos, rede e sistema de arquivos isolado.
- Registries (Repositórios): Servidores de armazenamento para imagens, como o Docker Hub, permitindo operações de pull (download) e push (upload).
- Docker Daemon: O serviço de background responsável por gerenciar objetos Docker, processando requisições da API REST.
- Docker Client: A interface de linha de comando (CLI) que envia instruções ao Daemon.
- Redes e Volumes: Mecanismos para orquestrar a comunicação entre contêineres e persistir dados no host, respectivamente.
Relação entre Imagem e Contêiner
Sob a perspectiva da programação orientada a objetos, a imagem atua como uma classe (definição abstrata), enquanto o contêiner é o objeto instanciado (entidade concreta em memória). O contêiner provê um ambiente Linux enxuto e seguro, onde a aplicação é executada de forma independente.
Operações com Imagens via CLI
A manipulação de imagens é feita através do comando docker image (ou o alias docker images).
Listagem de imagens disponíveis localmente:
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
debian bullseye 8e0598b0d01a 3 weeks ago 124MB
alpine latest a6215f271958 5 weeks ago 7.05MB
Para visualizar registros ocultos ou intermediários:
$ docker image ls -a
Extração exclusiva dos identificadores (útil para scripts de automação):
$ docker image ls -q
8e0598b0d01a
a6215f271958
Exclusão de uma imagem específica:
$ docker image rm -f alpine:latest
Limpeza em massa de todo o cache de imagens:
$ docker rmi -f $(docker image ls -aq)
Ciclo de Vida dos Contêineres
O Docker requer um kernel Linux nativo. Em ambientes Windows ou macOS, uma máquina virtual utilitária (como WSL2 ou Docker Desktop VM) atua como intermediária. A criação de um contêiner exige, obrigatoriamente, uma imagem base.
Download e Inicialização
$ docker pull debian:bullseye
Parâmetros críticos do comando docker run:
--name: Atribui um identificador customizado ao contêiner.-d: Executa o contêiner em modo desanexado (background).-it: Aloca um pseudo-TTY interativo vinculado à entrada padrão.-p [host]:[container]: Realiza o NAT de portas entre a rede do host e a rede isolada do contêiner.
Comportamento de Processos em Background
Ao executar docker run -d debian, o contêiner encerrará instantaneamente. O motor do Docker exige que o processo principal (PID 1) permaneça ativo em primeiro plano. Imagens de sistemas operacionais base (como Debian ou Alpine) não possuem serviços nativos rodando por padrão. Para mantê-las ativas, utiliza-se o modo interativo ou configura-se um entrypoint de longa duração.
Provisionando um Serviço de Banco de Dados
$ docker run -d --name cache-node -p 6380:6379 redis:7.2-alpine
Neste cenário, o processo do redis-server assume o PID 1, mantendo o contêiner ativo.
Monitoraemnto e Inspeção
Visualização do fluxo de saída padrão (stdout):
$ docker logs cache-node
Verificação dos processos em execução dentro do namespace do contêiner:
$ docker top cache-node
Extração de metadados detalhados em formato JSON (redes, volumes, variáveis):
$ docker inspect cache-node
Controle de Estado e Destruição
$ docker stop cache-node
$ docker start cache-node
$ docker rm cache-node
Para forçar a remoção de contêineres ativos:
$ docker rm -f cache-node
Script para purgar todos os contêineres existentes:
$ docker rm -f $(docker ps -aq)
Acesso a Ambientes em Execução
A interação com contêineres já provisionados pode ser realizada de duas formas distintas:
Execução Remota de Comandos (exec)
O comando exec injeta um novo processo no namespace do contêiner. Encerrar esta sessão não afeta o ciclo de vida do serviço principal.
$ docker exec -it cache-node sh
Anexação ao Processo Principal (attach)
O attach conecta o terminal do usuário diretamente ao fluxo de entrada/saída do PID 1. Utilizar o comando exit nesta sessão resultará na interrupção imediata do contêiner.
$ docker attach cache-node
Interação Prática com Redis
$ docker exec -it cache-node redis-cli -p 6379
127.0.0.1:6379> PING
PONG
127.0.0.1:6379> SET session_token "xyz-987"
OK
127.0.0.1:6379> GET session_token
"xyz-987"
Transferência de Dados entre Namespaces
A utilidade docker cp permite a extração ou injeção de arquivos bypassando a necessidade de volumes montados.
# Geração de um arquivo no sistema de arquivos efêmero
$ docker exec cache-node touch /tmp/metrics.log
# Extração para o diretório de trabalho no host
$ docker cp cache-node:/tmp/metrics.log ./local-metrics.log
Portabilidade via Exportação e Importação
É possível serializar o sistema de arquivos de um contêiner para distribuição ou backup.
Serialização do sistema de arquivos atual:
$ docker export cache-node > infra-backup.tar
Reconstrução de uma imagem a partir do arquivo tar (perdendo o histórico de camadas original):
$ cat infra-backup.tar | docker import - custom-registry/redis-base:1.0
Arquitetura de Armazenamento e UnionFS
As imagens Docker são construídas sobre o Union File System (UnionFS), uma tecnologia que permite a sobreposição transparente de múltiplos diretórios. A estrutura de carregamento ocorre em níveis:
- bootfs: A camada mais profunda, contendo o bootloader e o kernel. Esta camada é compartilhada diretamente com o sistema operacional do host, otimizando o consumo de recursos.
- rootfs: Localizada acima do bootfs, contém a estrutura clássica de diretórios Linux (
/etc,/bin,/dev). Representa a distribuição base (ex: Alpine, Debian).
Devido a essa arquitetura em camadas, múltiplos contêineres podem compartilhar a mesma imagem base em memória e em disco. Todas as camadas que compõem a imagem são estritamente de leitura (Read-Only).
No momento da inicialização (docker run), o Docker provisiona uma camada superior de leitura e gravação (Read-Write), conhecida como Container Layer. Qualquer modificação, criação ou exclusão de arquivos durante a execução da aplicação é isolada nesta camada efêmera.
Consolidação de Estado via Commit
Embora a persistência de dados deva ser feita via volumes, é possível capturar o estado da camada de lietura/gravação de um contêiner e transformá-la em uma nova imagem estática.
# Modificação do ambiente instalando um novo pacote
$ docker exec -it meu-app-debian apt-get update
$ docker exec -it meu-app-debian apt-get install -y htop
# Geração de um novo snapshot de imagem
$ docker commit -m="Adicionada ferramenta de monitoramento htop" -a="Equipe SRE" meu-app-debian minha-org/debian-monitorada:v2.1