Docker from scratch, Go and Multipart upload

Friday, January 26, 2018 · 2 minutes · 256 words

To reduce docker container size we can built the image from scratch instead of using bloated images, like debian or worse ubuntu.

But to put a golang binary in it you have to take care of some important stuff. We’ll see briefly how to do it. For more details, see Building Minimal Docker Containers For Go Applications

Compile staticaly your go program :

1CGO_ENABLED=GOARCH=amd64 GOOS=linux go build -a -installsuffix cgo -o server

Your Dockerfile looks like this :

1FROM scratch
2ADD static /static
3ADD server /server
4CMD /server

But if you add some upload code in your program, this won’t work. The upload needs the tmp folder for big files that are sent in multipart form.
Below, the code in the os.file_unix Go package :

 1// TempDir returns the default directory to use for temporary files.
 2func TempDir() string {
 3	dir := Getenv("TMPDIR")
 4	if dir == "" {
 5		if runtime.GOOS == "android" {
 6			dir = "/data/local/tmp"
 7		} else {
 8			dir = "/tmp"
 9		}
10	}
11	return dir
12}

So, as we are on linux, dir = “/tmp” is our usual suspect.

But the scratch docker does not contain a tmp folder. This was a hard bug to catch but so easy to fix, just changing the Docker file :

1FROM scratch
2VOLUME /tmp
3ADD static /static
4ADD server /server

Now link the container /tmp to the host tmp :

1docker run -P -v /tmp:/tmp your_image 

That’s it ! Enjoy a fully functionnal minimal docker golang application !

Go Docker