本文共 5587 字,大约阅读时间需要 18 分钟。
docker pull scratch
tar cv --files-from /dev/null | docker import - scratch
package mainimport ("fmt""net/http")func helloHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "Hello World from Go in minimal Docker container")}func main() {http.HandleFunc("/", helloHandler)fmt.Println("Started, serving at 8080")err := http.ListenAndServe(":8080", nil)if err != nil { panic("ListenAndServe: " + err.Error())}}
docker run -ti google/golang /bin/bash
go get github.com/adriaandejonge/helloworld
go get
命令和 go build
y欧典想,它允许获取远程代码包并构建远程依赖。你可以通过运行可执行文件来启动服务: $GOPATH/bin/helloworld
FROM scratchADD bin/helloworld /helloworldCMD ["/helloworld"]
docker run -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):$(which docker) -ti google/golang /bin/bash
go get github.com/adriaandejonge/helloworld
-v
参数在Docker容器内创建一个卷,并允许提供从Docker上的文件作为输入。 /var/run/docker.sock
是Unix套接字,允许访问Docker服务器。 $(which docker)
可以为容器提供Docker可执行文件的路径。但是,当在Apple的boot2docker上运行Docker时,使用该命令需要注意,如果Docker可执行文件被安装在不同的路径上相对于安装在boot2docker的虚拟机,这将会导致不匹配错误:它将是boot2docker虚拟服务器内的可执行文件被导入容器内。所以,你可能要替换 $(which docker)
为 /usr/local/bin/docker
。同样,如果你运行在不同的系统, /var/run/docker.sock
有一个不同的位置,你需要相应地调整。 cp $GOPATH/src/github.com/adriaandejonge/helloworld/Dockerfile $GOPATH
docker build -t adejonge/helloworld $GOPATH
Successfully built 6ff3fd5a381d然后您可以运行容器:
docker run -ti --name hellobroken adejonge/helloworld
2014/07/02 17:06:48 no such file or directory那么到底是怎么回事?我们的Scratch容器内已经有静态链接的可执行文件。难道我们犯了什么错误?
ldd $GOPATH/bin/helloworld
linux-vdso.so.1 => (0x00007fff039fe000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f61df30f000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f61def84000) /lib64/ld-linux-x86-64.so.2 (0x00007f61df530000)所以,在我们才可以运行的Hello World Web服务器之前,我们需要告诉Go编译器真正的做静态链接。
CGO_ENABLED=0 go get -a -ldflags '-s' github.com/adriaandejonge/helloworld
CGO_ENABLED
环境变量表示使用cgo编译器,而不是Go编译器。 -a
参数表示要重建所有的依赖。否则,还是以动态链接依赖为结果。 -ldflags -s
一个不错的额外标志,它可以缩减生成的可执行文件约50%的大小,没有cgo编译器你也可以使用该命令,50%是除去了调试信息的结果。 ldd $GOPATH/bin/helloworld
not a dynamic executable然后重新运行用Scratch镜像构建Docker容器那一步:
docker build -t adejonge/helloworld $GOPATH
Successfully built 6ff3fd5a381d接着运行容器:
docker run -ti --name helloworld adejonge/helloworld
Started,serving at 8080目前为止,有许多步骤,会有很多错误的余地。让我们退出google/golang 容器:
<Press Ctrl-C> exit
docker ps -a docker images -a
docker rm -f hello world docker rmi -f adejonge/helloworld
FROM google/golang RUN CGO_ENABLED=0 go get -a -ldflags '-s' github.com/adriaandejonge/helloworld RUN cp /gopath/src/github.com/adriaandejonge/helloworld/Dockerfile /gopath CMD docker build -t adejonge/helloworld gopath
docker build -t adejonge/hellobuild github.com/adriaandejonge/hellobuild
-t
表示镜像的标签名为adejonge/hellobuild和隐式标签名为latest。这些名称会在之后的删除镜像中用到。 docker run -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):$(which docker) -ti --name hellobuild adejonge/hellobuild
--name hellobuild
参数使得在运行后更容易移除容器。事实上,你现在就可以这样做,因为在运行此命令后,你已经创建了adejonge/helloworld的镜像: docker rm -f hellobuild docker rmi -f adejonge/hellobuild
docker run -ti --name helloworld adejonge/helloworld
docker pull adejonge/helloworld
docker images -a
你可以看到大小为3.6MB。当然,如果你能创建一个比我使用 Go 编写的 Web 服务还小的可执行文件,那就可以让它更小。使用 C 语言或者是汇编,你可以这样做到。尽管如此,你不可能使得它比 scratch 镜像还小。 转载地址:http://khuaa.baihongyu.com/