During the weekend I was doing some research on docker images specifically to be used with Go (Golang) applications. hence, thought of sharing the interesting findings as that might be useful to someone who's exploring the same for their tech project works.
Here, I will be elaborating a few different ways we can build an image for Golang and also highlight some of the security considerations that we need to take into account when picking one.
For this exercise I was using a simple Rest API developed using Go (Golang) using the Gin Framework.
The Gin framework is a popular web framework for Go (Golang) that is designed to be fast, easy to use, and highly efficient.
Here's a brief summary of its key features and characteristics;
Key Features
Performance: Gin is known for its high performance. It is one of the fastest Go web frameworks, providing a minimal overhead compared to other frameworks.
Fast HTTP Router: Gin uses a fast HTTP router and supports routing with methods like GET, POST, PUT, DELETE, etc. It also supports middleware and route grouping.
Middleware Support: Gin provides a way to use middleware to handle tasks such as logging, authentication, and other pre- or post-processing of requests.
JSON Validation: The framework offers built-in support for JSON validation and binding request data to Go structs, making it easier to work with JSON payloads.
Error Handling: Gin has a structured way of handling errors and provides a central error management system, allowing you to handle errors gracefully.
Template Rendering: While Gin is primarily designed for API development, it supports HTML template rendering if needed.
Request Handling: Supports different methods for request handling including form data, JSON payloads, and URL parameters.
Built-in Debugging: Gin provides detailed error messages and debugging information that can be useful during development.
Router: The core component that handles routing of HTTP requests to the appropriate handlers.
Context: A structure that carries the request and response data, and
provides methods to handle them. It's used extensively within handlers.
Engine: The primary instance of the Gin application, which is configured with routes, middleware, and other settings.
Middleware: Functions that execute during the request lifecycle, allowing you to perform tasks like logging, authentication, and more
Enough about Gin Framework :) now let's move into the main topic and talk about the Tests carried out.
In this Test we will be using a Official Standard/Regular Go Base Image
# Official Go Base Image FROM golang:1.21.0 # Create The Application Working Directory WORKDIR /app # Copy and Download Dependencies COPY go.mod go.sum . RUN go mod download # Copy Source and Build The Application COPY . . RUN go build -o main . # Expose The Port EXPOSE 8081 CMD ["./main"]
Image Size
In this Test we will be use the Alpine version of the Go Base Image which is slightly more lightweight
# Official Go Apline Base Image FROM golang:1.21.0-alpine as builder # Create The Application Directory WORKDIR /app # Copy and Download Dependencies COPY go.mod go.sum . RUN go mod download # Copy The Application Source & Build COPY . . RUN go build -o main . # Final Image Creation Stage FROM alpine:3.19 WORKDIR /root/ # Copy The Built Binary COPY --from=builder /app/main . # Expose the port EXPOSE 8081 CMD ["./main"]
Image Size
Here you can see that with a multi-staged build the image sizes are significantly reduced.
In this Test we will be using a Googles Distroless Go Base Image. Distroless images are known for being lightweight and secure containing only the minimal files required. In this these debug shells and unnecessary packages removed. therefore, you sacrifice the flexibility of having a package manager and a shell.
# Build Stage FROM golang:1.21.0 as builder # Set The Application Directory WORKDIR /app # Copy and Download Dependencies COPY go.mod go.sum . RUN go mod download # Copy The Application Source and Build the application COPY . . RUN CGO_ENABLED=0 go build -o main . # Final Image Creation Stage FROM gcr.io/distroless/static-debian12 # Copy the built binary COPY --from=builder /app/main / CMD ["/main"]
Image Size
CGO_ENABLED=0: This is an environment variable setting that disables CGO (C-Go). CGO is a feature of Go that allows Go packages to call C code. Setting CGO_ENABLED=0 ensures that the build does not depend on any C libraries, producing a fully static binary. This is useful for creating lightweight and portable Go binaries that can run on any system without requiring additional dependencies.
Putting it all together, RUN CGO_ENABLED=0 go build -o main . means that Docker will execute a command to build a Go application in the current directory, producing a static binary named main that does not depend on any C libraries.
Image Size
Even though the Distroless images are slightly bigger than the alpine images the security threat/vulnerability consideration might compel to choose Distroless!. Hence think about all these facts and pick the one that matches your requirements
Alpine with Multi-Stage Builds is a good choice if you need more control over the build process, and if compatibility issues with musl libc are not a concern. It provides flexibility and is smaller than many other base images, but still includes more components than Distroless images which can lead to potential security vulnerabilities/threats.
Google Distroless Images are ideal for maximizing security and minimizing the attack surface. They provide a very minimal runtime environment, which can be beneficial for production systems where security is a priority. However, you sacrifice the flexibility of having a package manager and a shell.
Use Alpine if you need flexibility and control over the build environment, and if compatibility issues with musl libc are not a problem.
Use Google Distroless if security and minimizing the attack surface are your top priorities, and you can ensure that your application has all its dependencies bundled properly.
Hope this was interesting and thank you for your time!
The above is the detailed content of Docker Images for Go (Golang) Small, Faster Docker Images and Security. For more information, please follow other related articles on the PHP Chinese website!