Create a multi-stage build for your C++ application
Prerequisites
- You have a Git client. The examples in this section use a command-line based Git client, but you can use any client.
Overview
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.
Get the sample application
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
Check the Dockerfile
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:
- Build stage: This stage uses the
ubuntu:latest
image to compile the C++ code and create a static binary. - Runtime stage: This stage uses the
scratch
image, which is an empty image, to copy the static binary from the build stage and run it.
Build the Docker image
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
.
Run the Docker container
To run the Docker container, use the following command:
$ docker run hello
You should see the output Hello, World!
in the terminal.
Summary
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.