Simple Go and Docker pattern

Here is a handy way of building statically linked binaries with golang using docker.

main.go
package main

import (
	log "github.com/sirupsen/logrus"
)

func main() {
	log.Info("Hello World!")
}
Makefile
GO_VERSION="1.15.4"

.PHONY: _example docker

all: example docker

example: main.go
	docker run -v $(PWD):/go/src/github.com/michalschott/example \
		-e GOARCH=${GOARCH} -e GOOS=${GOOS} golang:$(GO_VERSION) \
		make -C /go/src/github.com/michalschott/example _example

_example:
	go get ./...
	go vet ./...
	CGO_ENABLED=0 GOARCH=$(GOARCH) GOOS=$(GOOS) go build -a -installsuffix cgo -ldflags '-s -w' -o example main.go

docker:
	docker build -t example:latest .

Example usage:

  • make - will build binary for amd64 linux and then put it inside container tagged as example:latest
  • GOOS=darwin make example - build binary for MacOS
  • GOARCH=x86 make example - build binary for x84 architecture
Dockerfile

scratch is a special very minimum container.

Depends on your application you might need to add CA certificate file (uncoment lines, you’ll figure this out).

# Uncomment if your app needs to do SSL calls.

#FROM alpine:3.12 as cert

FROM scratch

COPY example /

#COPY --from=cert /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
#COPY ca-certificates.crt /etc/ssl/certs/ca-certificates.crt

CMD ["/example"]