如何执行go程序
写一个go的程序:
package main import "fmt" func main() { fmt.Println("hello world") }
在本地的话,我们可以有2种方案执行
go run main.go go build -o main main.go && ./main
直接go run运行或者编译main.go成二进制之后,运行二进制
如何放到docker中运行?
通过以上的案例,我们得出2个方案:
1:编译一个带go环境的容器,直接执行go程序,或者进容器编译即可
2:先编译成二进制,然后把二进制文件放到一个最小的镜像中执行
很明显,第二种方案适合直接运行二进制的场景,可以使用最少的资源去执行,那么如何实现docker自动化执行呢?
我们可以先定义一个带有golang环境的容器,在编译好之后放到最小的镜像去执行
docker手动多阶段构建
定义编译成二进制的dockerfile,命名为Dockerfile.build:
FROM golang WORKDIR /go/src/test ADD . /go/src/test RUN GOOS=linux GOARCH=386 go build -v -o /go/src/test/main
定义运行go的最小镜像dockerfile,命名为dockerfile.run:
FROM alpine:latest RUN apk add -U tzdata RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime WORKDIR /root/ COPY main . CMD \["./main"\]
通过sh命令进行多阶段构建:
#!/bin/sh echo Building cnych/docker-multi-stage-demo:build docker build -t cnych/docker-multi-stage-demo:build . -f Dockerfile.build # 先进行编译 编译golang的镜像 docker create --name extract cnych/docker-multi-stage-demo:build # 创建一个容器,但是不启动,只需要容器里面已经编译好的二进制文件 docker cp extract:/go/src/test/main ./main # 从容器里面拷贝出二进制文件 docker rm -f extract # 删除容器 echo Building cnych/docker-multi-stage-demo:run docker build --no-cache -t cnych/docker-multi-stage-demo:run . -f Dockerfile.run # 编译运行的镜像 rm ./main # 删除二进制文件 docker run -it --name docker-test cnych/docker-multi-stage-demo:run # 运行镜像,这行命令可以忽略,自己手动运行
运行脚本后输出:
docker多阶段构建
在docker的新版本中,直接支持了在dockerfile中多阶段构建:
创建一个新的Dockerfile.new文件:
FROM golang AS build-env ADD . /go/src/test WORKDIR /go/src/test RUN GOOS=linux GOARCH=386 go build -v -o /go/src/test/main FROM alpine RUN apk add -U tzdata RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime COPY --from=build-env /go/src/test/main /usr/local/bin/main CMD \[ "main" \]
我们只需要一个dockerfile文件,即可完成构建命令,并且不需要新的shell命令去删除构建的临时文件,构建和启动命令:
docker build -t cnych/docker-multi-stage-demo:latest -f ./Dockerfile.new ./ docker run -it --name docker-test cnych/docker-multi-stage-demo:latest
即可完成多阶段构建