Docker
O Docker empacota código, bibliotecas e pesos de modelos em imagens de contêiner que funcionam da mesma forma em laptops, servidores com GPU, executores de CI e dispositivos de borda.
O Docker é uma plataforma de código aberto para criar, compartilhar e executar aplicações em contêineres: processos isolados que incluem seu próprio sistema de arquivos, com código, bibliotecas e pacotes do sistema, enquanto compartilham o kernel do sistema operacional do host. A dotCloud, empresa que mais tarde mudou seu nome para Docker, Inc., abriu o código em março de 2013, e sua ferramenta de linha de comando, seu formato de imagem em camadas e seu registro público fizeram dos contêineres Linux uma ferramenta cotidiana para desenvolvedores. Em aprendizado de máquina, uma imagem Docker fixa a versão exata do Python, as bibliotecas CUDA, a compilação do PyTorch e os pesos do modelo, para que o modelo se comporte da mesma forma em um laptop, em um servidor com GPU, em um executor de integração contínua e em um dispositivo de borda.
Como o Docker funciona#
Um Dockerfile lista as etapas que criam uma imagem: uma imagem base para começar, comandos que instalam pacotes, arquivos a copiar e o comando a executar na inicialização. Cada instrução RUN, COPY ou ADD adiciona uma camada somente leitura, e a compilação seguinte reutiliza as camadas em cache até que uma instrução ou um de seus arquivos de entrada mude. Assim, as dependências instaladas no início permanecem em cache, enquanto o código da aplicação é recompilado em segundos. Uma imagem é essa pilha de camadas mais os metadados. Um contêiner é uma instância em execução de uma imagem com uma fina camada gravável por cima, que é excluída com o contêiner, a menos que os dados sejam gravados em um volume montado.
O comando docker se comunica com o Docker Engine, um daemon em segundo plano que encaminha cada contêiner ao containerd e ao runtime de baixo nível runc. Eles usam namespaces do Linux para isolar os processos, a rede e o sistema de arquivos de um contêiner, e cgroups para limitar o uso de CPU e memória. As imagens são compartilhadas por meio de registros como o Docker Hub, o GitHub Container Registry, o NVIDIA NGC e o registro próprio de cada provedor de nuvem. Elas seguem o formato de imagem da Open Container Initiative, por isso o Podman, o containerd e o Kubernetes podem executá-las sem alterações.
A Ultralytics publica imagens Docker oficiais para cada destino de hardware, incluindo GPUs CUDA, CPUs, placas ARM64, dispositivos NVIDIA Jetson e GPUs AMD. Cada imagem também recebe uma tag com o número da versão da Ultralytics, para permitir compilações reproduzíveis. A imagem leve latest-python usada abaixo já inclui Python, PyTorch, o pacote ultralytics e os pesos nano do YOLO26, então o Dockerfile de um projeto só precisa adicionar o próprio código:
# Official Ultralytics CPU image with Python, PyTorch, ultralytics, and yolo26n.pt
FROM ultralytics/ultralytics:latest-python
# Install extra dependencies in their own layer, cached until requirements.txt changes
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy the application last, so code edits rebuild only this layer
COPY app.py .
# Command every container runs when it starts
CMD ["python", "app.py"]docker build -t yolo-app . transforma este arquivo e os arquivos ao lado dele em uma imagem, e docker run --rm yolo-app inicia um contêiner a partir dela. Enviar a imagem para um registro permite que qualquer outra máquina obtenha e execute o mesmo ambiente, por exemplo, como uma API de serviço de modelos ou uma tarefa noturna de inferência.
Docker para aprendizado de máquina#
Os contêineres acessam GPUs por meio do NVIDIA Container Toolkit. O driver da NVIDIA permanece no host, e a imagem contém apenas bibliotecas CUDA de espaço de usuário, que precisam ser compatíveis com esse driver. No Linux, o Docker 28.2 e versões posteriores ativam o CDI por padrão, então --device nvidia.com/gpu=all solicita GPUs como dispositivos CDI e mantém o acesso à GPU em contêineres de longa duração, que podem perder esse acesso com a flag antiga --gpus all quando o host recarrega o systemd.
Duas outras configurações são importantes para o treinamento. Os workers do carregador de dados do PyTorch enviam lotes ao processo de treinamento por meio da memória compartilhada em /dev/shm, que o Docker limita a 64 MB por padrão; por isso, os contêineres de treinamento são executados com --ipc=host ou com um valor maior em --shm-size. Os conjuntos de dados e as saídas devem ficar em volumes montados, pois uma execução de treinamento que grava checkpoints dentro do contêiner perde esses arquivos quando o contêiner é removido. Fixar uma tag de versão ou o digest da imagem em vez de latest mantém uma tarefa de treinamento distribuído ou uma implantação de modelo na mesma imagem em todas as máquinas. Tanto servidores de inferência, como o NVIDIA Triton Inference Server, quanto serviços gerenciados, como o Vertex AI, executam modelos como imagens de contêiner.
Docker vs. máquinas virtuais e Kubernetes#
- Máquinas virtuais: Um hipervisor emula o hardware, e cada VM inicializa seu próprio kernel convidado. Isso isola as cargas de trabalho com mais rigor e permite qualquer sistema operacional convidado, mas exige uma imagem completa do sistema operacional por VM e resulta em uma inicialização mais lenta. Como os contêineres compartilham o kernel Linux do host, o Docker Desktop no macOS e no Windows os executa dentro de uma VM Linux leve.
- Docker Compose: Define vários contêineres que são executados juntos em um host, como uma API de inferência, um cache e um coletor de métricas.
- Kubernetes: Agenda contêineres em um cluster, reinicia os que falham e ajusta o número de réplicas conforme o tráfego. O Kubernetes 1.24 removeu o dockershim, seu adaptador integrado para o Docker Engine, então os clusters executam contêineres por meio do containerd ou do CRI-O. As imagens criadas com o Docker continuam sendo executadas ali porque são imagens OCI padrão.










