Zack Scholl

zack.scholl@gmail.com

Dockerfile for Golang apps

 / #tutorial #golang 

A lightweight Dockerfile for Golang apps.

Docker is a useful container but it is also useful as a way to easily start/restart programs on multiple systems - or a single system. Also, even if the program is a single binary, Docker can be nice because the Docker Hub can be used to automatically build programs which are then pulled for deployment.

I’ve settled on a nice pattern for a very clean image that can be used for self-contained fat Go binaries. The image itself is basically the size of the Go binary.

Say you have a program in github.com/yourname/yourprogram. Go into that directory

$ cd $GOPATH/src/github.com/yourname/yourprogram

and create a file Dockerfile with the following:

 1###################################
 2# 1. Build in a Go-based image   #
 3###################################
 4FROM golang:1.12-alpine as builder
 5RUN apk add --no-cache git # add deps here (like make) if needed
 6WORKDIR /go/yourprogram
 7COPY . .
 8# any pre-requisities to building should be added here
 9# RUN go generate
10RUN go build -v
11
12###################################
13# 2. Copy into a clean image     #
14###################################
15FROM alpine:latest
16COPY --from=builder /go/yourprogram/yourprogram /yourprogram
17VOLUME /data
18# expose port if needed
19EXPOSE 8000
20ENTRYPOINT ["/yourprogram"]
21# any flags here, for example use the data folder
22CMD ["--data-folder","/data"] 

Now, in the same directory as the Dockerfile you can build your image.

$ docker build -t yourprogram .

Now you have an image that uses a data folder. You can then run the image with persistent data using

$ docker run -d -v /path/to/data:/data -p 8001:8000 yourprogram

Now your image will be running and saving data in /path/to/data and be accessible by the local 8001 port.

Its easiset to do this in a Github repo and then attach that to Docker Hub which will automatically build your images. Then you never need to build, after each push to the Github repo you can automatically get the latest image using:

$ docker run -d -v /path/to/data:/data -p 8001:8000 yourname/yourprogram

Now you can utilize things like docker stats and docker ps to check on the status of all your services, and easily stop/start them with docker stop/run.