Skip to main content

Creating standalone Golang apps in Docker + fixing "exec user process caused: no such file or directory"

Solution for "exec user process caused: no such file or directory"

If you are trying to build a minimalist scratch Docker container for a Golang app you may encounter the following rather infuriating error:

standard_init_linux.go:228: exec user process caused: no such file or directory

The solution is to prepend the flag CGO_ENABLED=0 to the build line as follows:

CGO_ENABLED=0 go build -o yourappname *.go

This flag tells Go to build a statically-linked binary, which doesn't have any external dependencies. That's exactly what you need in a scratch (empty) container.

Building a standalone Docker image of your Golang app

Most tutorials about dockerising Golang apps tell you to use the Golang image as the base so that you can compile it. Don't do that! Why would you want hundreds of megabytes of unnecessary cruft in your image, when you could just have a small standalone binary?

Build the binary on your development machine and copy it directly into a scratch image like this:

# Build a binary of your app.
CGO_ENABLED=0 go build -o yourappname *.go

# Make a tar archive of the binary and any other files it needs.
tar -cf yourappname.tar ./*

# Build a Docker image directly from the tar file.
docker import -c "ENTRYPOINT [\"/yourappname\"]" - yourappname < yourappname.tar

Automate build and Docker image creation with a makefile

But it's probably most convenient to automate the whole build and image creation process with a makefile. The command 'make container' will build the whole thing.

.DEFAULT_GOAL := build

fmt:
	go fmt ./...
lint: fmt
	golint ./...
vet: fmt
	go vet ./...
	shadow ./...
build: vet
	CGO_ENABLED=0 go build -o yourappname *.go
tar: build
	tar -cf yourappname.tar ./*
container: tar
	docker import -c "ENTRYPOINT [\"/yourappname\"]" - yourappname < yourappname.tar

Copyright, all rights reserved.