Firmino Changani

Shipping a Golang service as a Docker container

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

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:

 1##
 2## Builder stage
 3##
 4FROM golang:1.20 AS builder
 5
 6ARG VERSION
 7
 8WORKDIR /usr/app
 9COPY . ./
10
11ENV CGO_ENABLED=0
12RUN go build -buildvcs=false -o bin/service -ldflags="-X main.Version=${VERSION}" ./
13
14##
15## Final stage
16##
17
18FROM alpine
19WORKDIR /usr/app
20COPY --from=builder /usr/app/bin/service ./service
21
22ENTRYPOINT ["./service"]

Source

The Dockerfile above has two stages where the first stage is solely focused on building a binary from the source code:

After the binary gets built on the state named builder, Docker jumps into the second stage and does the following:

How to build it, and run it

To 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

Conclusion

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, Firmino

#golang #docker

Reply to this post by email ↪