|
| 1 | +--- |
| 2 | +title: Create a multi-stage build for your C++ application |
| 3 | +linkTitle: Containerize your app using a multi-stage build |
| 4 | +weight: 5 |
| 5 | +keywords: C++, containerize, multi-stage |
| 6 | +description: Learn how to create a multi-stage build for a C++ application. |
| 7 | +aliases: |
| 8 | +- /language/cpp/multistage/ |
| 9 | +- /guides/language/cpp/multistage/ |
| 10 | +--- |
| 11 | + |
| 12 | +## Prerequisites |
| 13 | + |
| 14 | +- You have a [Git client](https://git-scm.com/downloads). The examples in this section use a command-line based Git client, but you can use any client. |
| 15 | + |
| 16 | +## Overview |
| 17 | + |
| 18 | +This section walks you through creating a multi-stage Docker build for a C++ application. |
| 19 | +A multi-stage build is a Docker feature that allows you to use different base images for different stages of the build process, |
| 20 | +so you can optimize the size of your final image and separate build dependencies from runtime dependencies. |
| 21 | + |
| 22 | +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, |
| 23 | +because the build dependencies are not needed at runtime. |
| 24 | + |
| 25 | +## Get the sample application |
| 26 | + |
| 27 | +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: |
| 28 | + |
| 29 | +```bash |
| 30 | +$ git clone https://github.com/dockersamples/c-plus-plus-docker.git |
| 31 | +``` |
| 32 | + |
| 33 | +The example for this section is under the `hello` directory in the repository. Get inside it and take a look at the files: |
| 34 | + |
| 35 | +```bash |
| 36 | +$ cd c-plus-plus-docker/hello |
| 37 | +$ ls |
| 38 | +``` |
| 39 | + |
| 40 | +You should see the following files: |
| 41 | + |
| 42 | +```text |
| 43 | +Dockerfile hello.cpp |
| 44 | +``` |
| 45 | + |
| 46 | +## Check the Dockerfile |
| 47 | + |
| 48 | +Open the `Dockerfile` in an IDE or text editor. The `Dockerfile` contains the instructions for building the Docker image. |
| 49 | + |
| 50 | +```Dockerfile |
| 51 | +# Stage 1: Build stage |
| 52 | +FROM ubuntu:latest AS build |
| 53 | + |
| 54 | +# Install build-essential for compiling C++ code |
| 55 | +RUN apt-get update && apt-get install -y build-essential |
| 56 | + |
| 57 | +# Set the working directory |
| 58 | +WORKDIR /app |
| 59 | + |
| 60 | +# Copy the source code into the container |
| 61 | +COPY hello.cpp . |
| 62 | + |
| 63 | +# Compile the C++ code statically to ensure it doesn't depend on runtime libraries |
| 64 | +RUN g++ -o hello hello.cpp -static |
| 65 | + |
| 66 | +# Stage 2: Runtime stage |
| 67 | +FROM scratch |
| 68 | + |
| 69 | +# Copy the static binary from the build stage |
| 70 | +COPY --from=build /app/hello /hello |
| 71 | + |
| 72 | +# Command to run the binary |
| 73 | +CMD ["/hello"] |
| 74 | +``` |
| 75 | + |
| 76 | +The `Dockerfile` has two stages: |
| 77 | + |
| 78 | +1. **Build stage**: This stage uses the `ubuntu:latest` image to compile the C++ code and create a static binary. |
| 79 | +2. **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. |
| 80 | + |
| 81 | +## Build the Docker image |
| 82 | + |
| 83 | +To build the Docker image, run the following command in the `hello` directory: |
| 84 | + |
| 85 | +```bash |
| 86 | +$ docker build -t hello . |
| 87 | +``` |
| 88 | + |
| 89 | +The `-t` flag tags the image with the name `hello`. |
| 90 | + |
| 91 | +## Run the Docker container |
| 92 | + |
| 93 | +To run the Docker container, use the following command: |
| 94 | + |
| 95 | +```bash |
| 96 | +$ docker run hello |
| 97 | +``` |
| 98 | + |
| 99 | +You should see the output `Hello, World!` in the terminal. |
| 100 | + |
| 101 | +## Summary |
| 102 | + |
| 103 | +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. |
| 104 | +In this example, the final image only contains the static binary and doesn't include any build dependencies. |
| 105 | + |
| 106 | +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: |
| 107 | + |
| 108 | +```bash |
| 109 | +$ docker run hello ls |
| 110 | +``` |
| 111 | + |
| 112 | +This makes the image very lightweight and secure. |
0 commit comments