Docker e C++: conteinerização avançada de aplicações

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Docker e C++: conteinerização de aplicações em nível avançado



A conteinerização de aplicações C++ com Docker não é apenas transferir código para um ambiente isolado. Em nível avançado, é a arte de equilibrar o tamanho da imagem, a velocidade de construção, a segurança e a compatibilidade com bibliotecas do sistema. Neste artigo, abordaremos técnicas que ajudarão você a criar imagens Docker eficientes, leves e sustentáveis para projetos C++.



Presumimos que você já conhece os fundamentos do Docker (comandos docker build, docker run) e a sintaxe básica do Dockerfile. Agora vamos para tarefas reais: construção em múltiplos estágios, trabalho com dependências do sistema, depuração dentro do contêiner e integração com CI/CD.



1. Construção em múltiplos estágios: separando compilação e execução



O principal problema do C++ no Docker é o tamanho da imagem. Um conjunto completo de ferramentas (g++, cmake, make, pacotes dev) pode pesar 1–2 GB. A solução é a construção em múltiplos estágios (multi-stage build).



Vamos considerar um exemplo clássico: uma aplicação C++ usando a biblioteca libcurl.



# Primeiro estágio: construçãoFROM ubuntu:22.04 AS builder

RUN apt-get update && apt-get install -y \ build-essential \ cmake \ libcurl4-openssl-dev \ && rm -rf /var/lib/apt/lists/*

WORKDIR /appCOPY . .

RUN cmake -B build -DCMAKE_BUILD_TYPE=Release \ && cmake --build build --parallel $(nproc)

# Segundo estágio: imagem executávelFROM ubuntu:22.04-slim

RUN apt-get update && apt-get install -y \ libcurl4 \ && rm -rf /var/lib/apt/lists/*

COPY --from=builder /app/build/myapp /usr/local/bin/myapp

CMD ["myapp"]


Pontos-chave:

  • No primeiro estágio (builder), instalamos todas as ferramentas e dependências para a construção.
  • No segundo estágio — apenas dependências de runtime (libcurl4 em vez de libcurl4-openssl-dev).
  • A imagem final contém apenas o binário compilado e as bibliotecas necessárias.
  • Usamos --parallel $(nproc) para acelerar a construção.


O tamanho da imagem diminui de ~1.2 GB para ~80 MB. Isso é crítico para implantação e download de imagens em CI/CD.



2. Otimização de cache e camadas do Docker



Cada instrução no Dockerfile cria uma camada. A ordem incorreta das instruções faz com que, com a menor alteração no código, todo o cache seja invalidado.



Regra: primeiro copie o que muda raramente (CMakeLists.txt, dependências), depois o código.



FROM ubuntu:22.04 AS builder

WORKDIR /app

# 1. Dependências do sistema (mudam raramente)RUN apt-get update && apt-get install -y \ build-essential cmake libboost-all-dev \ && rm -rf /var/lib/apt/lists/*

# 2. Arquivos de configuração da construção (mudam com pouca frequência)COPY CMakeLists.txt .

# 3. Código fonte (muda constantemente)COPY src/ ./src/

# 4. ConstruçãoRUN cmake -B build && cmake --build build


Dicas adicionais:

  • Use .dockerignore para excluir build/, .git/, *.o.
  • Agrupe RUN apt-get install em um único comando — isso reduz o número de camadas.
  • Para projetos C++ com muitos arquivos de cabeçalho, considere usar ccache dentro do contêiner.


3. Trabalho com bibliotecas do sistema e vinculação estática



Às vezes, bibliotecas dinâmicas no contêiner estão ausentes ou são incompatíveis. Uma abordagem avançada é a vinculação estática ou o uso do Alpine Linux.



Opção A: Construção estática (g++)

FROM alpine:3.18 AS builder

RUN apk add --no-cache g++ gcc musl-dev make cmake

WORKDIR /appCOPY . .

# Vinculação estáticaRUN g++ -static -O2 -o myapp main.cpp -lpthread

FROM scratchCO

Blogs

Book Recommendations