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

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: nível avançado

\n\n

A conteinerização de aplicações C++ com Docker não é apenas transferir um binário para um ambiente isolado. Em nível avançado, é necessário considerar as particularidades da compilação, gerenciamento de dependências, otimização do tamanho da imagem e depuração. Neste artigo, abordaremos as melhores práticas para criar imagens Docker eficientes para projetos C++, utilizando compilação em múltiplos estágios, vinculação estática e dinâmica, além de ferramentas modernas como CMake e vcpkg.

\n\n

1. Compilação em múltiplos estágios (Multi-stage build)

\n

O problema clássico das imagens Docker para C++ é o tamanho enorme devido à inclusão do compilador, arquivos de cabeçalho e bibliotecas na imagem final. A compilação em múltiplos estágios resolve esse problema: o primeiro estágio (build stage) contém todas as ferramentas para compilação, enquanto o segundo (runtime stage) contém apenas o conjunto mínimo de dependências de tempo de execução.

\n\n
# Primeiro estágio: compilação\nFROM gcc:13 AS builder\nWORKDIR /app\nCOPY . .\nRUN apt-get update && apt-get install -y cmake libboost-all-dev && \\\n    cmake -B build -DCMAKE_BUILD_TYPE=Release && \\\n    cmake --build build --parallel $(nproc)\n\n# Segundo estágio: tempo de execução\nFROM alpine:3.19\nRUN apk add --no-cache libstdc++ libgcc\nCOPY --from=builder /app/build/my_app /usr/local/bin/my_app\nCMD ["my_app"]
\n\n

Essa abordagem reduz a imagem final de 1,5 GB (imagem com GCC) para aproximadamente 30 MB. Para executar uma aplicação C++ no Alpine, apenas libstdc++ e libgcc são suficientes.

\n\n

2. Gerenciamento de dependências: vcpkg e Conan

\n

Para projetos C++ modernos com dezenas de bibliotecas, a instalação manual de dependências via apt-get torna-se incontrolável. A melhor solução é usar gerenciadores de pacotes, como vcpkg ou Conan, diretamente no Dockerfile.

\n\n
FROM ubuntu:22.04 AS builder\nRUN apt-get update && apt-get install -y curl git cmake build-essential\nRUN git clone https://github.com/Microsoft/vcpkg.git /opt/vcpkg && \\\n    /opt/vcpkg/bootstrap-vcpkg.sh && \\\n    /opt/vcpkg/vcpkg install fmt spdlog nlohmann-json\n\nWORKDIR /app\nCOPY . .\nRUN cmake -B build -DCMAKE_TOOLCHAIN_FILE=/opt/vcpkg/scripts/buildsystems/vcpkg.cmake && \\\n    cmake --build build
\n\n

Importante: para evitar recompilar o vcpkg e as bibliotecas a cada alteração no código-fonte, copie vcpkg.json e CMakeLists.txt antes de copiar os demais arquivos. O Docker armazena em cache as camadas, e as dependências serão reinstaladas apenas quando o manifesto for alterado.

\n\n

3. Otimização da imagem: vinculação estática e Alpine

\n

Para reduzir ao máximo o tamanho da imagem, pode-se usar vinculação estática. Isso é especialmente relevante para microsserviços e utilitários de linha de comando. No entanto, lembre-se: a vinculação estática pode aumentar o binário, mas elimina a necessidade de incluir bibliotecas dinâmicas no contêiner.

\n\n
# CMakeLists.txt\nset(CMAKE_EXE_LINKER_FLAGS "-static -static-libgcc -static-libstdc++")\ntarget_link_libraries(my_app PRIVATE fmt::fmt spdlog::spdlog)
\n\n

A imagem final pode ser construída sobre scratch (imagem vazia):

\n\n
FROM scratch\nCOPY --from=builder /app/build/my_app /\nENTRYPOINT ["/my_app"]
\n\n

Essa imagem pesa apenas alguns megabytes. No entanto, observe que a vinculação estática nem sempre é possível (por exemplo, ao usar OpenSSL ou CUDA) e, nesses casos, é melhor usar Alpine com bibliotecas dinâmicas.

\n\n

4. Depuração de aplicações C++ no contêiner

\n

A depuração em Docker é uma dificuldade adicional. Métodos avançados incluem:

\n
    \n
  • Uso de imagens de depuração: compile uma imagem separada com símbolos de depuração e gdbserver. Conecte-se a ela a partir da IDE (VS Code, CLion) por meio de depuração remota.
  • \n
  • Core dumps: permita a gravação de arquivos core no contêiner e analise-os após uma falha:
  • \n
\n\n
# Dockerfile para                

Blogs

Book Recommendations