-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Add multi-stage builds to the C++ guide #21562
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| --- | ||
| title: Create a multi-stage build for your C++ application | ||
| linkTitle: Containerize your app using a multi-stage build | ||
| weight: 5 | ||
| keywords: C++, containerize, multi-stage | ||
| description: Learn how to create a multi-stage build for a C++ application. | ||
| aliases: | ||
| - /language/cpp/multistage/ | ||
| - /guides/language/cpp/multistage/ | ||
| --- | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - 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. | ||
|
|
||
| ## 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: | ||
|
|
||
| ```bash | ||
| $ git clone https://github.com/dockersamples/c-plus-plus-docker.git | ||
aerabi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ``` | ||
|
|
||
| The example for this section is under the `hello` directory in the repository. Get inside it and take a look at the files: | ||
|
|
||
| ```bash | ||
| $ cd c-plus-plus-docker/hello | ||
| $ ls | ||
| ``` | ||
|
|
||
| You should see the following files: | ||
|
|
||
| ```text | ||
| 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. | ||
|
|
||
| ```Dockerfile | ||
| # 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: | ||
|
|
||
| 1. **Build stage**: This stage uses the `ubuntu:latest` image to compile the C++ code and create a static binary. | ||
| 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. | ||
|
|
||
| ## Build the Docker image | ||
|
|
||
| To build the Docker image, run the following command in the `hello` directory: | ||
|
|
||
| ```bash | ||
| $ 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: | ||
|
|
||
| ```bash | ||
| $ 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: | ||
|
|
||
| ```bash | ||
| $ docker run hello ls | ||
| ``` | ||
|
|
||
| This makes the image very lightweight and secure. | ||
|
Check warning on line 112 in content/guides/cpp/multistage.md
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| --- | ||
| title: Supply-chain security for C++ Docker images | ||
| linkTitle: Supply-chain security | ||
| weight: 60 | ||
| keywords: C++, security, multi-stage | ||
| description: Learn how to extract SBOMs from C++ Docker images. | ||
| aliases: | ||
| - /language/cpp/security/ | ||
| - /guides/language/cpp/security/ | ||
| --- | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - 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. | ||
| - You have a Docker Desktop installed, with containerd enabled for pulling and storing images (it's a checkbox in **Settings** > **General**). Otherwise, if you use Docker Engine: | ||
| - You have the [Docker SBOM CLI plugin](https://github.com/docker/sbom-cli-plugin) installed. To install it on Docker Engine, use the following command: | ||
|
|
||
| ```bash | ||
| $ curl -sSfL https://raw.githubusercontent.com/docker/sbom-cli-plugin/main/install.sh | sh -s -- | ||
| ``` | ||
|
|
||
| - You have the [Docker Scout CLI plugin](https://docs.docker.com/scout/install/) installed. To install it on Docker Engine, use the following command: | ||
|
|
||
| ```bash | ||
| $ curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s -- | ||
| ``` | ||
|
|
||
| - You have [containerd enabled](https://docs.docker.com/engine/storage/containerd/) for Docker Engine. | ||
|
|
||
| ## Overview | ||
|
|
||
| This section walks you through extracting Software Bill of Materials (SBOMs) from a C++ Docker image using the Docker SBOM CLI plugin. SBOMs provide a detailed list of all the components in a software package, including their versions and licenses. You can use SBOMs to track the provenance of your software and ensure that it complies with your organization's security and licensing policies. | ||
|
|
||
| ## Generate an SBOM | ||
|
|
||
| Here we will use the Docker image that we built in the [Create a multi-stage build for your C++ application](/guides/language/cpp/multistage/) guide. If you haven't already built the image, follow the steps in that guide to build the image. | ||
|
Check warning on line 36 in content/guides/cpp/security.md
|
||
| The image is named `hello`. To generate an SBOM for the `hello` image, run the following command: | ||
|
|
||
| ```bash | ||
| $ docker sbom hello | ||
| ``` | ||
|
|
||
| The command will say "No packages discovered". This is because the final image is a scratch image and doesn't have any packages. | ||
| Let's try again with Docker Scout: | ||
|
|
||
| ```bash | ||
| $ docker scout sbom --format=list hello | ||
| ``` | ||
|
|
||
| This command will tell you the same thing. | ||
|
|
||
| ## Generate an SBOM attestation | ||
|
|
||
| The SBOM can be generated during the build process and "attached" to the image. This is called an SBOM attestation. | ||
| To generate an SBOM attestation for the `hello` image, first let's change the Dockerfile: | ||
|
|
||
| ```Dockerfile | ||
| ARG BUILDKIT_SBOM_SCAN_STAGE=true | ||
|
|
||
| FROM ubuntu:latest AS build | ||
|
|
||
| RUN apt-get update && apt-get install -y build-essential | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| COPY hello.cpp . | ||
|
|
||
| RUN g++ -o hello hello.cpp -static | ||
|
|
||
| # -------------------- | ||
| FROM scratch | ||
|
|
||
| COPY --from=build /app/hello /hello | ||
|
|
||
| CMD ["/hello"] | ||
| ``` | ||
|
|
||
| The first line `ARG BUILDKIT_SBOM_SCAN_STAGE=true` enables SBOM scanning in the build stage. | ||
| Now, build the image with the following command: | ||
|
|
||
| ```bash | ||
| $ docker buildx build --sbom=true -t hello:sbom . | ||
| ``` | ||
|
|
||
| This command will build the image and generate an SBOM attestation. You can verify that the SBOM is attached to the image by running the following command: | ||
|
|
||
| ```bash | ||
| $ docker scout sbom --format=list hello:sbom | ||
| ``` | ||
|
|
||
| Note that the normal `docker sbom` command will not load the SBOM attestation. | ||
|
|
||
| ## Summary | ||
|
|
||
| In this section, you learned how to generate SBOM attestation for a C++ Docker image during the build process. | ||
| The normal image scanners will not be able to generate SBOMs from scratch images. | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.