使用Docker容器化C++应用程序:完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为何要将C++应用容器化?



C++开发历来与"在我机器上能运行"的难题相伴。不同版本的编译器、库和系统依赖项让部署变得棘手。Docker解决了这一问题:您可以将应用程序及其整个环境打包到一个轻量级容器中,该容器在任何系统上都能以相同方式运行。



本文将带您完整走一遍C++应用容器化的流程——从简单的Dockerfile到多阶段构建及镜像体积优化。



1. 基础篇:C++应用的Dockerfile



让我们从最简单的例子开始。假设我们有一个输出"Hello, Docker!"的C++程序。



源代码 (hello.cpp)



#include <iostream>

int main() { std::cout << "Hello, Docker!" << std::endl; return 0;}


第一个Dockerfile



# 使用GCC镜像FROM gcc:13.2

# 设置工作目录WORKDIR /app

# 复制源代码COPY hello.cpp .

# 编译RUN g++ -o hello hello.cpp

# 运行CMD ["./hello"]


让我们构建并运行它:



docker build -t cpp-hello .docker run cpp-hello


这种方法的缺点是镜像体积约为1.2 GB,因为包含了完整的GCC工具链。这对生产环境是不可接受的。



2. 多阶段构建



最佳实践是将构建阶段和执行阶段分离。在第一阶段,我们使用完整的工具链编译应用程序;在第二阶段,我们仅将编译好的二进制文件复制到一个干净的最小镜像中。



优化后的Dockerfile



# 第一阶段:构建FROM gcc:13.2 AS builder

WORKDIR /app

COPY hello.cpp .

RUN g++ -static -o hello hello.cpp

# 第二阶段:运行FROM alpine:3.19

WORKDIR /app

# 复制静态编译的二进制文件COPY --from=builder /app/hello .

CMD ["./hello"]


关键点在于-static标志。它将所有依赖项都包含在二进制文件中,使其能够在没有额外库的纯净Alpine系统上运行。镜像体积从1.2 GB减少到了约6 MB!



3. 实战项目:CMake + 依赖项



让我们考虑一个更复杂的案例:一个使用Boost库并通过CMake构建的应用程序。



项目结构



myapp/├── CMakeLists.txt├── src/│   └── main.cpp└── Dockerfile


CMakeLists.txt



cmake_minimum_required(VERSION 3.20)project(MyApp LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Boost REQUIRED COMPONENTS system)

add_executable(myapp src/main.cpp)target_link_libraries(myapp Boost::system)


main.cpp



#include <iostream>#include <boost/asio.hpp>

int main() { boost::asio::io_context io; std::cout << "Boost.Asio works in the container!" << std::endl; return 0;}


带依赖项的Dockerfile



# 第一阶段:构建FROM ubuntu:22.04 AS builder

# 安装构建依赖项RUN apt-get update && apt-get install -y \ build-essential \ cmake \ libboost-system-dev \ && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# 复制源代码COPY CMakeLists.txt .COPY src/ src/

# 构建RUN mkdir build && cd build && \ cmake .. -DCMAKE_BUILD_TYPE=Release && \ make -j$(nproc)

# 第二阶段:运行FROM ubuntu:22.04

# 仅安装运行时依赖项RUN apt-get update && apt-get install -y \ libboost-system1.74.0 \ && rm -rf /var/lib/apt/lists/*

WORKDIR /app

COPY --from=builder /app/build/myapp .

CMD ["./myapp"]


注意:在第二阶段,我们仅安装Boost的运行时版本(libboost-system1.74.0)。

博客

书籍推荐