合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
# Docker部署Go程序 阅读目录 阐述 1 开始 第一种方式 - 在容器上编译并运行 第二种方式 - 先编译再发布到容器 第三种方式 - 多阶镜像构建 总结 阐述 Docker是一种轻量级的容器技术,可以为应用程序的部署提供统一、可移植的运行环境。 1 开始 首先,我们需要一个简单的示例项目,以演示如何将Go项目部署到Docker容器当中。 运行以下命令创建并初始化一个名称为GoTest的项目目录: linux ``` mkdir GoTest cd GoTest go mod init GoTest ``` windows ![](https://img.kancloud.cn/bc/5d/bc5d96ef5bd147b70915e12e880382f1_816x163.png) 接着我们编写一个简单的 web 服务,该服务监听 8080 端口: ``` package main import ( "fmt" "net/http" ) func main() { fmt.Println("服务启动......") http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "hello world") }) http.ListenAndServe(":8080", nil) } ``` linux 示例项目已经创建好了,项目结构如下: $ tree . ``` ├── go.mod ├── go.sum └── main.go ``` 第一种方式 - 在容器上编译并运行 创建好了项目之后,要让项目运行在Docker容器中,我们需要先创建镜像,这里用Dockerfile文件来定制我们的镜像,Dockerfile文件代码如下: ``` # 基础镜像 FROM golang:alpine # 环境变量 ENV GOPROXY https://goproxy.cn,direct # 创建目录 RUN mkdir /app # 将源码复制到app目录 ADD . /app/ # 切换到app目录 WORKDIR /app # 编译源码 RUN go build -o main . # 运行 CMD ["./main"] ``` 在项目直接 docker build 命令构建镜像: ``` docker build -t gotest:1.0 . ``` ![](https://img.kancloud.cn/b4/99/b499dc5b856feae5ab0197923c37b4e0_939x471.png) 构建成功之后,通过 docker images 查看镜像: ``` E:\TEXT\test>docker image ls gotest REPOSITORY TAG IMAGE ID CREATED SIZE gotest 1.0 d5e891a78a66 About a minute ago 329MB E:\TEXT\test>docker image ls gotest:1.0 REPOSITORY TAG IMAGE ID CREATED SIZE gotest 1.0 d5e891a78a66 21 minutes ago 329MB E:\TEXT\test> ``` 使用该镜像启动一个容器: ``` E:\TEXT\test>docker run -p 8080:8080 gotest:1.0 服务启动...... ``` 使用curl命令访问在容器中运行的Web服务: ``` E:\TEXT\test>curl http://localhost:8080/hello hello world E:\TEXT\test> ``` 查看编译的文件,在Windows上是看不到的。 第二种方式 - 先编译再发布到容器 我们使用 docker images 查看镜像时,会发现上述步骤生成的镜像非常大: ``` E:\TEXT\test>docker image ls gotest:1.0 REPOSITORY TAG IMAGE ID CREATED SIZE gotest 1.0 d5e891a78a66 29 minutes ago 329MB E:\TEXT\test> ``` 但如果我们实际编译项目,会发现生成的可以执行文件是非常小的: ``` /app # ls -lh main -rwxr-xr-x 1 root root 6.3M Aug 4 02:23 main /app # ``` 可执行文件非常小,而构建的镜像非常大,这是因为我们是以 golang:alpine 镜像为基础来构建自己的镜像的,golang:alpine 包含Go语言的开发环境,本身就非常大: ``` $ docker image ls golang:alpine REPOSITORY TAG IMAGE ID CREATED SIZE golang alpine 722a834ff95b 1 hours ago 301MB ``` 如果我们不希望构建好的镜像太大了,可以先编译好可执行程序,再构建镜像,此时的Dockerfile文件简化如下: ``` # 以空白镜像为基础 FROM scratch # 将编译好的可执行文件复制到镜像 ADD ./your-app-name-linux / # 运行 CMD ["./your-app-name-linux"] ``` 编译可执行程序: ``` PS E:\TEXT\test> $env:GOOS = "linux" PS E:\TEXT\test> $env:GOARCH = "amd64" PS E:\TEXT\test> go build -o your-app-name-linux PS E:\TEXT\test> ``` linux ``` go build -o main . ``` 构建镜像: ``` E:\TEXT\test>docker build -t gotest:2.0 . [+] Building 0.2s (5/5) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 202B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build context 0.1s => => transferring context: 6.58MB 0.1s => [1/1] ADD ./your-app-name-linux / 0.0s => exporting to image 0.1s => => exporting layers 0.0s => => writing image sha256:376b84364d4ed2bb8acf73c6d43583fbb4f0aa1e4ada411a8b05897998207a40 0.0s => => naming to docker.io/library/gotest:2.0 0.0s E:\TEXT\test> ``` 查看镜像: ``` E:\TEXT\test>docker image ls gotest:2.0 REPOSITORY TAG IMAGE ID CREATED SIZE gotest 2.0 376b84364d4e About a minute ago 6.58MB E:\TEXT\test> ``` 从上面显示的结果可以看到,这种方式构建产生的镜像非常小。 第三种方式 - 多阶镜像构建 我们在上面使用两种方式将Go程序部署到容器中,一种是直接在镜像中编译,这种方式构建的镜像太大了,一种是自己编译后打包到镜像,这种方式比较麻烦且不符合一般部署流程。 而使用Docker的多阶镜像构建可以则将上述两种方式结合,多阶镜像构建,即在一个Dockerfile文件可以声明多个镜像构建语句,且后面阶段的构建可以复制上一阶段的文件: ``` # 第一阶构建 FROM golang:alpine ENV GOPROXY https://goproxy.cn,direct RUN mkdir /app/ ADD . /app/ WORKDIR /app RUN CGO_ENABLED=0 GOOS=linux go build -o main . # 第二阶构建,从空白镜像开始 FROM scratch ## 复制上层构建的文件 COPY --from=0 /app/main / CMD ["./main"] ``` 构建镜像: ``` $ docker build -t GoTest:3.0 ``` 查看镜像: ``` $ docker image ls GoTest:3.0 REPOSITORY TAG IMAGE ID CREATED SIZE gotest 3.0 8d3b724f8968 30 seconds ago 6.13MB ``` 从上面的结果也可以看出,多阶构建产生的镜像也非常小。 总结 直接在镜像中构建Go项目会使产生的镜像过大,而手动编译后再写入镜像则略显繁琐,多阶镜像构建可以很好地解决这两个问题。 原文链接:[链接](https://blog.csdn.net/weiguang102/article/details/132099255)