I am looking for a solution to a simple configuration problem to solve; it has been nagging me for quite some time now. :)
I have a golang project on github which gives me a static binary, and uses godeps.
Now I want to ensure that the godep go install ...
command can be run after a git clone and a docker container be built from this newly built binary locally.
As an option, the user should be able to push it to docker hub or a private repo as applicable.
I am thinking of using Makefiles, but that seems too complicated (set the gopath, then godep build, modify the Dockerfile dynamically to point to the place where the binary is located, then a docker build).
Is there an easier way to do it?
So far, when I've been on your situation, I've always come up with a Makefile for doing all the work, which, like you said, has never been simple. Although it's never been simple, I've done it using at least 2 different approaches dependending on the level of dependency you want between the build process and the development environment.
The simplest way is, as you say, just throw in a Makefile the steps you would do by yourself. You can use Dockerfiles ARGuments to parameterize the binary name so you don't have to modify the Dockerfile during the build.
Here you have a quick and dirty (working) Makefile I've just made up for getting you started:
APP_IMAGE=group/example
APP_TAG=1.0
APP_BINARY=example
.PHONY: clean image binary
all: image
clean:
if [ -r $(APP_BINARY) ]; then rm $(APP_BINARY); fi
if [ -n "$$(docker images -q $(APP_IMAGE):$(APP_TAG))" ]; then docker rmi $(APP_IMAGE):$(APP_TAG); fi
image: binary
docker build --build-arg APP_BINARY=$(APP_BINARY) -t $(APP_IMAGE):$(APP_TAG) $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
binary: $(APP_BINARY)
$(APP_BINARY): main.go
go build -o $@ $^
That Makefile expects to be in the same directory as the Dockerfile.
Here is a minimal one (which works):
FROM alpine:3.5
ARG APP_BINARY
ADD ${APP_BINARY} /app
ENTRYPOINT /app
I've tested that having a main.go in the same top-level project directory as both Makefile and Dockerfile, in case you have a main.go nested inside some inside directory ("ROOT/cmd/bla" is commonplace) then you should change the "go build" line to account for that.
Although I've been doing things like that for a while, now that I see (and think about) your question I've come to see that a dedicated tool which knows specifically how to do this could be great to have. Specifically a tool that mimics "go build/get/install" but can build docker images... so where you can run the following command to get a binary:
go install github.com/my/program
You could also run the following command to get a simple docker image:
goi install github.com/my/program
How does that sound? Is there something like that in existence? Should I get started?
Provide a base
image (with GOPATH, godep ... pre configured).
Create Dockerfile based on the base
image, then user only need to alter the COPY path.