diff --git a/content/guides/cpp/_index.md b/content/guides/cpp/_index.md index 1bfc404dca5..85f317765e3 100644 --- a/content/guides/cpp/_index.md +++ b/content/guides/cpp/_index.md @@ -12,19 +12,21 @@ aliases: - /guides/language/cpp/ languages: [cpp] params: - time: 10 minutes + time: 20 minutes --- The C++ getting started guide teaches you how to create a containerized C++ application using Docker. In this guide, you'll learn how to: > **Acknowledgment** > -> Docker would like to thank [Pradumna Saraf](https://twitter.com/pradumna_saraf) for his contribution to this guide. +> Docker would like to thank [Pradumna Saraf](https://twitter.com/pradumna_saraf) and [Mohammad-Ali A'rĂ¢bi](https://twitter.com/MohammadAliEN) for their contribution to this guide. -- Containerize and run a C++ application +- Containerize and run a C++ application using a multi-stage Docker build +- Build and run a C++ application using Docker Compose - Set up a local environment to develop a C++ application using containers - Configure a CI/CD pipeline for a containerized C++ application using GitHub Actions - Deploy your containerized application locally to Kubernetes to test and debug your deployment +- Use BuildKit to generate SBOM attestations during the build process After completing the C++ getting started modules, you should be able to containerize your own C++ application based on the examples and instructions provided in this guide. diff --git a/content/guides/cpp/containerize.md b/content/guides/cpp/containerize.md index 03042bc97e2..96c19430b88 100644 --- a/content/guides/cpp/containerize.md +++ b/content/guides/cpp/containerize.md @@ -1,9 +1,9 @@ --- title: Containerize a C++ application -linkTitle: Containerize your app +linkTitle: Build and run a C++ application using Docker Compose weight: 10 keywords: C++, containerize, initialize -description: Learn how to containerize a C++ application. +description: Learn how to use Docker Compose to build and run a C++ application. aliases: - /language/cpp/containerize/ - /guides/language/cpp/containerize/ @@ -15,17 +15,17 @@ aliases: ## Overview -This section walks you through containerizing and running a C++ application. +This section walks you through containerizing and running a C++ application, using Docker Compose. ## Get the sample application -Clone the sample application to use with this guide. Open a terminal, change directory to a directory that you want to work in, and run the following command to clone the repository: +We're using the same sample repository that you used in the previous sections of this guide. If you haven't already cloned the repository, clone it now: ```console $ git clone https://github.com/dockersamples/c-plus-plus-docker.git ``` -You should now have the following contents in your `c-plus-plus-docker` +You should now have the following contents in your `c-plus-plus-docker` (root) directory. ```text diff --git a/content/guides/cpp/multistage.md b/content/guides/cpp/multistage.md new file mode 100644 index 00000000000..0dbd3e35f58 --- /dev/null +++ b/content/guides/cpp/multistage.md @@ -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 +``` + +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. diff --git a/content/guides/cpp/security.md b/content/guides/cpp/security.md new file mode 100644 index 00000000000..733c23c9a82 --- /dev/null +++ b/content/guides/cpp/security.md @@ -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. +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. \ No newline at end of file