content/guides/cpp/multistage.md
This section walks you through creating a multi-stage Docker build for a C++ application. A multi-stage build is a Docker feature that allows you to use different base images for different stages of the build process, so you can optimize the size of your final image and separate build dependencies from runtime dependencies.
The standard practice for compiled languages like C++ is to have a build stage that compiles the code and a runtime stage that runs the compiled binary, because the build dependencies are not needed at runtime.
Let's use a simple C++ application that prints Hello, World! to the terminal. To do so, clone the sample repository to use with this guide:
$ git clone https://github.com/dockersamples/c-plus-plus-docker.git
The example for this section is under the hello directory in the repository. Get inside it and take a look at the files:
$ cd c-plus-plus-docker/hello
$ ls
You should see the following files:
Dockerfile hello.cpp
Open the Dockerfile in an IDE or text editor. The Dockerfile contains the instructions for building the Docker image.
# Stage 1: Build stage
FROM ubuntu:latest AS build
# Install build-essential for compiling C++ code
RUN apt-get update && apt-get install -y build-essential
# Set the working directory
WORKDIR /app
# Copy the source code into the container
COPY hello.cpp .
# Compile the C++ code statically to ensure it doesn't depend on runtime libraries
RUN g++ -o hello hello.cpp -static
# Stage 2: Runtime stage
FROM scratch
# Copy the static binary from the build stage
COPY --from=build /app/hello /hello
# Command to run the binary
CMD ["/hello"]
The Dockerfile has two stages:
ubuntu:latest image to compile the C++ code and create a static binary.scratch image, which is an empty image, to copy the static binary from the build stage and run it.To build the Docker image, run the following command in the hello directory:
$ docker build -t hello .
The -t flag tags the image with the name hello.
To run the Docker container, use the following command:
$ docker run hello
You should see the output Hello, World! in the terminal.
In this section, you learned how to create a multi-stage build for a C++ application. Multi-stage builds help you optimize the size of your final image and separate build dependencies from runtime dependencies. In this example, the final image only contains the static binary and doesn't include any build dependencies.
As the image has an empty base, the usual OS tools are also absent. So, for example, you can't run a simple ls command in the container:
$ docker run hello ls
This makes the image very lightweight and secure.