At this day and age Docker has established itself as the de facto tool for containerisation, it is deserved given how well it abstract its complexity away from its users. In the cloud it allows us to run containerised services as if the programming language those services have been written on don't really matter, and in fact it doesn't, provided that the service are exposed on a port.
On this blog post I will my preferred set up to Dockerize Go services.
Binary, Binary, Binary - Steve Balmer
The command go build
generates a binary, and this is a relevant and non-trivial fact that is going to impact how I am going to set up the Dockerfile, but I am going to come back at this later, for now here is the code snippet:
##
## Builder stage
##
FROM golang:1.20 AS builder
ARG VERSION
WORKDIR /usr/app
COPY . ./
ENV CGO_ENABLED=0
RUN go build -buildvcs=false -o bin/service -ldflags="-X main.Version=${VERSION}" ./
##
## Final stage
##
FROM alpine
WORKDIR /usr/app
COPY /usr/app/bin/service ./service
ENTRYPOINT ["./service"]
The Dockerfile above has two stages where the first stage is solely focused on building a binary from the source code:
golang:1.20
and it is aliased as builder
because it's referenced further downVERSION
, which is used to specify the image's and the binary's version during build time/usr/app
C
. Read more here-buildvcs
set to falsebin/service
VERSION
to the variable Version
defined in main.go
After the binary gets built on the state named builder
, Docker jumps into the second stage and does the following:
/usr/app
COPY --from=builder
./service
, just like you would do if you were running it locallyTo build a new Docker image versioned 0.0.1, run the following command:
docker build --build-arg VERSION=0.0.1 -t go-docker-demo:0.0.1 .
And to run the image newly built run the following command:
docker run -p 8080:8080 go-docker-demo:0.0.1
That's the end of this post, and perhaps to I would like to conclude that the fact that Go generates a binary that can be executed without an external runtime helps to build Docker images based in lightweight images such as alpine
, which makes the build faster, and very cheap to host it on an Images Registry provided by a Cloud vendor, which tend to charge by data transferred in and out.
Cheers,<br/> Firmino