From 2f5d48eac77fb3189f6adc88cb4db89d5783ca6e Mon Sep 17 00:00:00 2001 From: Sagar Utekar Date: Sun, 30 Nov 2025 19:06:42 +0530 Subject: [PATCH 1/2] docs: Update golang guide to include Docker Hardened Images --- content/guides/golang/build-images.md | 135 +++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 3 deletions(-) diff --git a/content/guides/golang/build-images.md b/content/guides/golang/build-images.md index 68696baf2bc7..34fcbb3e3bcc 100644 --- a/content/guides/golang/build-images.md +++ b/content/guides/golang/build-images.md @@ -99,6 +99,38 @@ func IntMin(a, b int) int { To build a container image with Docker, a `Dockerfile` with build instructions is required. +Before creating a Dockerfile, you need to choose a base image. You can either use the [Go Docker Official Image](https://hub.docker.com/_/golang) or a Docker Hardened Image (DHI) from the [Hardened Image catalog](https://hub.docker.com/hardened-images/catalog). + +Choosing DHI offers the advantage of a production-ready image that is lightweight and secure. For more information, see [Docker Hardened Images](https://docs.docker.com/dhi/). + +{{< tabs >}} +{{< tab name="Using Docker Hardened Images" >}} +Docker Hardened Images (DHIs) are available for Go on [Docker Hub](https://hub.docker.com/hardened-images/catalog/dhi/golang). Unlike using the Docker Official Image, you must first mirror the Go image into your organization and then use it as your base image. Follow the instructions in the [DHI quickstart](/dhi/get-started/) to create a mirrored repository for Go. + +Mirrored repositories must start with `dhi-`, for example: `FROM /dhi-golang:`. In the following Dockerfile, the `FROM` instruction uses `/dhi-golang:1.19` as the base image. + +Begin your `Dockerfile` with the (optional) parser directive line that instructs BuildKit to +interpret your file according to the grammar rules for the specified version of the syntax. + +You then tell Docker what base image you would like to use for your application: + +```dockerfile +# syntax=docker/dockerfile:1 + +FROM /dhi-golang:1.19 +``` + +Docker images can be inherited from other images. Therefore, instead of creating +your own base image from scratch, you can use the DHI Go image that already +has all necessary tools and libraries to compile and run a Go application. + +{{< /tab >}} +{{< tab name="Using the official image" >}} + +Using the Docker Official Image is straightforward. In the following Dockerfile, you'll notice that the `FROM` instruction uses `golang:1.19` as the base image. + +This is the official image for Go. This image is [available on the Docker Hub](https://hub.docker.com/_/golang). + Begin your `Dockerfile` with the (optional) parser directive line that instructs BuildKit to interpret your file according to the grammar rules for the specified version of the syntax. @@ -114,6 +146,9 @@ Docker images can be inherited from other images. Therefore, instead of creating your own base image from scratch, you can use the official Go image that already has all necessary tools and libraries to compile and run a Go application. +{{< /tab >}} +{{< /tabs >}} + > [!NOTE] > > If you are curious about creating your own base images, you can check out the following section of this guide: [creating base images](/manuals/build/building/base-images.md#create-a-base-image). @@ -209,6 +244,42 @@ CMD ["/docker-gs-ping"] Here's the complete `Dockerfile`: +{{< tabs >}} +{{< tab name="Using Docker Hardened Images" >}} + +```dockerfile +# syntax=docker/dockerfile:1 + +FROM /dhi-golang:1.19 + +# Set destination for COPY +WORKDIR /app + +# Download Go modules +COPY go.mod go.sum ./ +RUN go mod download + +# Copy the source code. Note the slash at the end, as explained in +# https://docs.docker.com/reference/dockerfile/#copy +COPY *.go ./ + +# Build +RUN CGO_ENABLED=0 GOOS=linux go build -o /docker-gs-ping + +# Optional: +# To bind to a TCP port, runtime parameters must be supplied to the docker command. +# But we can document in the Dockerfile what ports +# the application is going to listen on by default. +# https://docs.docker.com/reference/dockerfile/#expose +EXPOSE 8080 + +# Run +CMD ["/docker-gs-ping"] +``` + +{{< /tab >}} +{{< tab name="Using the official image" >}} + ```dockerfile # syntax=docker/dockerfile:1 @@ -239,6 +310,9 @@ EXPOSE 8080 CMD ["/docker-gs-ping"] ``` +{{< /tab >}} +{{< /tabs >}} + The `Dockerfile` may also contain comments. They always begin with a `#` symbol, and must be at the beginning of a line. Comments are there for your convenience to allow documenting your `Dockerfile`. @@ -415,14 +489,53 @@ These two issues can be solved by using [multi-stage builds](/manuals/build/buil In a nutshell, a multi-stage build can carry over the artifacts from one build stage into another, and every build stage can be instantiated from a different base image. -Thus, in the following example, you are going to use a full-scale official Go -image to build your application. Then you'll copy the application binary into +Thus, in the following example, you are going to use a full-scale Go +image (either DHI or official) to build your application. Then you'll copy the application binary into another image whose base is very lean and doesn't include the Go toolchain or other optional components. The `Dockerfile.multistage` in the sample application's repository has the following content: +{{< tabs >}} +{{< tab name="Using Docker Hardened Images" >}} + +```dockerfile +# syntax=docker/dockerfile:1 + +# Build the application from source +FROM /dhi-golang:1.19 AS build-stage + +WORKDIR /app + +COPY go.mod go.sum ./ +RUN go mod download + +COPY *.go ./ + +RUN CGO_ENABLED=0 GOOS=linux go build -o /docker-gs-ping + +# Run the tests in the container +FROM build-stage AS run-test-stage +RUN go test -v ./... + +# Deploy the application binary into a lean image +FROM gcr.io/distroless/base-debian11 AS build-release-stage + +WORKDIR / + +COPY --from=build-stage /docker-gs-ping /docker-gs-ping + +EXPOSE 8080 + +USER nonroot:nonroot + +ENTRYPOINT ["/docker-gs-ping"] +``` + +{{< /tab >}} +{{< tab name="Using the official image" >}} + ```dockerfile # syntax=docker/dockerfile:1 @@ -456,6 +569,9 @@ USER nonroot:nonroot ENTRYPOINT ["/docker-gs-ping"] ``` +{{< /tab >}} +{{< /tabs >}} + Since you have two Dockerfiles now, you have to tell Docker what Dockerfile you'd like to use to build the image. Tag the new image with `multistage`. This tag (like any other, apart from `latest`) has no special meaning for Docker, @@ -481,9 +597,22 @@ base image that you have used in the second stage of the build is very barebones There's much more to multi-stage builds, including the possibility of multi-architecture builds, so feel free to check out [multi-stage builds](/manuals/build/building/multi-stage.md). This is, however, not essential for your progress here. +## Summary + +In this section, you learned how you can build a container image for your Go +application using Docker. + +Related information: + +- [Dockerfile reference](/reference/dockerfile.md) +- [.dockerignore file](/reference/dockerfile.md#dockerignore-file) +- [Docker Compose overview](/manuals/compose/_index.md) +- [Compose file reference](/reference/compose-file/_index.md) +- [Docker Hardened Images](/dhi/) + ## Next steps In this module, you met your example application and built and container image for it. -In the next module, you’ll take a look at how to run your image as a container. +In the next module, you'll take a look at how to run your image as a container. From 726080c18b242e1ee43335de2a19e06b5219afe5 Mon Sep 17 00:00:00 2001 From: Sagar Utekar Date: Sun, 30 Nov 2025 19:28:14 +0530 Subject: [PATCH 2/2] docs: Update golang guide to include Docker Hardened Images --- content/guides/golang/build-images.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/content/guides/golang/build-images.md b/content/guides/golang/build-images.md index 34fcbb3e3bcc..484b14cb08ae 100644 --- a/content/guides/golang/build-images.md +++ b/content/guides/golang/build-images.md @@ -107,7 +107,7 @@ Choosing DHI offers the advantage of a production-ready image that is lightweigh {{< tab name="Using Docker Hardened Images" >}} Docker Hardened Images (DHIs) are available for Go on [Docker Hub](https://hub.docker.com/hardened-images/catalog/dhi/golang). Unlike using the Docker Official Image, you must first mirror the Go image into your organization and then use it as your base image. Follow the instructions in the [DHI quickstart](/dhi/get-started/) to create a mirrored repository for Go. -Mirrored repositories must start with `dhi-`, for example: `FROM /dhi-golang:`. In the following Dockerfile, the `FROM` instruction uses `/dhi-golang:1.19` as the base image. +Mirrored repositories must start with `dhi-`, for example: `FROM /dhi-golang:`. In the following Dockerfile, the `FROM` instruction uses `/dhi-golang:1.25` as the base image. Begin your `Dockerfile` with the (optional) parser directive line that instructs BuildKit to interpret your file according to the grammar rules for the specified version of the syntax. @@ -117,7 +117,7 @@ You then tell Docker what base image you would like to use for your application: ```dockerfile # syntax=docker/dockerfile:1 -FROM /dhi-golang:1.19 +FROM /dhi-golang:1.25 ``` Docker images can be inherited from other images. Therefore, instead of creating @@ -127,7 +127,7 @@ has all necessary tools and libraries to compile and run a Go application. {{< /tab >}} {{< tab name="Using the official image" >}} -Using the Docker Official Image is straightforward. In the following Dockerfile, you'll notice that the `FROM` instruction uses `golang:1.19` as the base image. +Using the Docker Official Image is straightforward. In the following Dockerfile, you'll notice that the `FROM` instruction uses `golang:1.25` as the base image. This is the official image for Go. This image is [available on the Docker Hub](https://hub.docker.com/_/golang). @@ -139,7 +139,7 @@ You then tell Docker what base image you would like to use for your application: ```dockerfile # syntax=docker/dockerfile:1 -FROM golang:1.19 +FROM golang:1.25 ``` Docker images can be inherited from other images. Therefore, instead of creating @@ -206,7 +206,7 @@ directory inside the image. RUN go mod download ``` -At this point, you have a Go toolchain version 1.19.x and all your Go +At this point, you have a Go toolchain version 1.25.x and all your Go dependencies installed inside the image. The next thing you need to do is to copy your source code into the image. You’ll @@ -250,7 +250,7 @@ Here's the complete `Dockerfile`: ```dockerfile # syntax=docker/dockerfile:1 -FROM /dhi-golang:1.19 +FROM /dhi-golang:1.25 # Set destination for COPY WORKDIR /app @@ -283,7 +283,7 @@ CMD ["/docker-gs-ping"] ```dockerfile # syntax=docker/dockerfile:1 -FROM golang:1.19 +FROM golang:1.25 # Set destination for COPY WORKDIR /app @@ -326,7 +326,7 @@ that you may have used: # syntax=docker/dockerfile:1 # A sample microservice in Go packaged into a container image. -FROM golang:1.19 +FROM golang:1.25 # ... ``` @@ -361,8 +361,8 @@ The following is just an example of what these messages may look like. => CACHED docker-image://docker.io/docker/dockerfile:1@sha256:39b85bbfa7536a5feceb7372a0817649ecb2724562a38360f4d6a7782a409b14 0.0s => [internal] load build definition from Dockerfile 0.0s => [internal] load .dockerignore 0.0s - => [internal] load metadata for docker.io/library/golang:1.19 0.7s - => [1/6] FROM docker.io/library/golang:1.19@sha256:5d947843dde82ba1df5ac1b2ebb70b203d106f0423bf5183df3dc96f6bc5a705 0.0s + => [internal] load metadata for docker.io/library/golang:1.25 0.7s + => [1/6] FROM docker.io/library/golang:1.25@sha256:5d947843dde82ba1df5ac1b2ebb70b203d106f0423bf5183df3dc96f6bc5a705 0.0s => [internal] load build context 0.0s => => transferring context: 6.08kB 0.0s => CACHED [2/6] WORKDIR /app 0.0s @@ -504,7 +504,7 @@ following content: # syntax=docker/dockerfile:1 # Build the application from source -FROM /dhi-golang:1.19 AS build-stage +FROM /dhi-golang:1.25 AS build-stage WORKDIR /app @@ -540,7 +540,7 @@ ENTRYPOINT ["/docker-gs-ping"] # syntax=docker/dockerfile:1 # Build the application from source -FROM golang:1.19 AS build-stage +FROM golang:1.25 AS build-stage WORKDIR /app