构建、部署和推送 Golang 静态二进制文件的 Docker 镜像。

huangapple go评论99阅读模式
英文:

Build, deploy, push docker images for golang static binaries

问题

我正在寻找解决一个简单配置问题的解决方案;这个问题已经困扰我很长时间了。 构建、部署和推送 Golang 静态二进制文件的 Docker 镜像。

我在GitHub上有一个使用godeps的golang项目,它给我提供了一个静态二进制文件。

现在我想确保在git clone之后可以运行godep go install ...命令,并且可以从这个新构建的二进制文件本地构建一个docker容器。

作为一个选项,用户应该能够将其推送到适用的Docker Hub或私有仓库。

我考虑使用Makefile,但那似乎太复杂了(设置gopath,然后godep build,动态修改Dockerfile以指向二进制文件所在的位置,然后进行docker构建)。

有没有更简单的方法来做到这一点?

英文:

I am looking for a solution to a simple configuration problem to solve; it has been nagging me for quite some time now. 构建、部署和推送 Golang 静态二进制文件的 Docker 镜像。

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?

答案1

得分: 1

到目前为止,当我遇到你的情况时,我总是会为所有的工作编写一个Makefile,就像你说的那样,这从来都不是简单的。虽然从来都不简单,但我至少使用了两种不同的方法,这取决于构建过程和开发环境之间的依赖程度。

最简单的方法就是,就像你说的那样,在Makefile中添加你自己会做的步骤。你可以使用Dockerfile的ARG参数来参数化二进制文件的名称,这样在构建过程中就不需要修改Dockerfile。

这里是一个我刚刚编写的快速而简单的Makefile示例,可以帮助你入门:

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 $@ $^

这个Makefile期望与Dockerfile位于同一个目录中。

这是一个最简单的(可行的)Makefile示例:

FROM alpine:3.5
ARG APP_BINARY
ADD ${APP_BINARY} /app
ENTRYPOINT /app

我已经测试过,在与Makefile和Dockerfile位于同一顶级项目目录的main.go中,如果你的main.go嵌套在某个内部目录中("ROOT/cmd/bla"是常见的情况),那么你应该修改"go build"行来适应这种情况。

虽然我已经这样做了一段时间,但现在我看到(并思考)你的问题后,我发现一个专门知道如何做这件事的工具可能非常好。具体来说,一个模拟"go build/get/install"但可以构建Docker镜像的工具...所以你可以运行以下命令来获取一个二进制文件:

go install github.com/my/program

你也可以运行以下命令来获取一个简单的Docker镜像:

goi install github.com/my/program

听起来怎么样?是否已经存在这样的工具?我应该开始做吗?

英文:

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?

答案2

得分: 0

提供一个已经配置了GOPATH、godep等的base镜像。

基于base镜像创建Dockerfile,然后用户只需要修改COPY路径即可。

英文:

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.

huangapple
  • 本文由 发表于 2017年1月18日 22:49:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/41722442.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定