Small docker images for Go applications

Small docker images for Go applications

Docker is a tool to containerise applications, it allows you to have a consistent environment to build and run your application locally or in production helping to mitigate any potential issues that can arise from differences in environments and conform to dev/prod parity.

When building docker images for Go applications, you can use the official golang image as a base image, once you have added your code and depenedencies the final image can be quite large.

As go is a compiled language we can use docker multi-stage builds to keep the final image size down, this is helpful when your cloud provider charges by storage like AWS ECR.

Here is an example dockerfile for a go application:

FROM golang:1.22

WORKDIR /usr/src/app

COPY go.mod go.sum ./
RUN go mod download && go mod verify

COPY . .
RUN go build -v -o /usr/local/bin/app ./cmd/app/main.go

EXPOSE 8080

CMD ["app"]

it’s 1gb in size.

go_base

A multi-stage build allows us to use the go image golang:1.22 to build our application, then another image to run the application.

FROM golang:1.22 as buildStage

WORKDIR /appdir

COPY go.mod go.sum ./
RUN go mod download && go mod verify

COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -v -o /usr/local/bin/myapp ./cmd/app/main.go

FROM alpine:latest

WORKDIR /

COPY --from=buildStage /usr/local/bin/myapp /

EXPOSE 8080

CMD ["/myapp"]

The first FROM statement imports the go image and names it buildStage, we then build the application, the second FROM statement imports the alpine image which is a small linux image at only 5mb, we then copy the built application from the buildStage image to the alpine image using COPY --from=buildStage.

The final image size in this case is on 15mb.

go_small

© 2024 Timney.