Building a Go Application With Docker: Optimized Dockerfile

In this article, we will walk through the creation of an optimized Dockerfile for building and running a Go application. This Dockerfile will focus on building only the binary of the Go application, resulting in a smaller and more efficient Docker image.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
## Dockerfile for Building a Go Application

```Dockerfile
# Stage 1: Build the Go Binary
FROM golang:1.17 as builder

# Set the working directory inside the container
WORKDIR /app

# Copy the Go application source code into the container
COPY . .

# Set environment variables
ENV CGO_ENABLED=0

# Fetch dependencies and build the Go binary
RUN go get -d -v ./...
RUN go build -o /tmp/api-server .

# Stage 2: Create a minimal runtime image
FROM scratch

# Copy the binary from the builder stage into the minimal image
COPY --from=builder /tmp/api-server /usr/bin/api-server

# Define the command to run when the container starts
CMD ["api-server", "start"]

In this Dockerfile, we use a multi-stage build to optimize the final Docker image. Here’s a breakdown of what each section does:

  1. Stage 1 (builder):

    • We start from the official Golang image, specifically version 1.17.
    • Set the working directory inside the container to /app.
    • Copy the Go application source code from your local directory into the container.
    • Set the CGO_ENABLED environment variable to 0 to build a statically linked binary.
    • Fetch the project’s dependencies using go get.
    • Build the Go binary and place it in /tmp/api-server.
  2. Stage 2 (minimal runtime image):

    • We use the scratch image as the base image. This image is essentially empty, which makes our final image very small and lightweight.
    • Copy the binary (api-server) from the builder stage into /usr/bin/api-server in the final image.
    • Define the default command to execute when the container starts, which is ["api-server", "start"].

This Dockerfile optimizes the final Docker image size by separating the build environment from the runtime environment. It results in a minimal Docker image that contains only the Go binary and its necessary dependencies, making it efficient and suitable for production deployment.

For more details on using this Dockerfile and building a Go application with Docker, you can refer to the original article.

Remember to replace the COPY . . line in the Dockerfile with the appropriate path to your Go application source code, as specified in your project structure.

0%