docker

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > docker > Docker部署Go程序

详解如何在Docker部署Go程序

作者:程序员读书

Docker是一种轻量级的容器技术,可以为应用程序的部署提供统一、可移植的运行环境,下面我们来讲讲如何将Go应用程序部署到Docker的容器吧

开始

首先,我们需要一个简单的示例项目,以演示如何将Go项目部署到Docker容器当中。

运行以下命令创建并初始化一个名称为GoTest的项目目录:

mkdir GoTest
cd GoTest
go mod init GoTest

接着我们编写一个简单的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)
}

此时我们的示例项目已经创建好了,项目结构如下:

$ 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 .

构建成功之后,通过docker images查看镜像:

$ docker image ls GoTest:1.0
REPOSITORY   TAG   IMAGE ID      CREATED         SIZE
gotest       1.0   18e7bd58d94b  20 seconds ago  309MB

使用该镜像启动一个容器:

$ docker run -p 8080:8080 GoTest:1.0

使用curl命令访问在容器中运行的Web服务:

$ curl http://localhost:8080/hello
hello world

先编译再发布到容器

我们使用docker images查看镜像时,会发现上述步骤生成的镜像非常大:

$ docker image ls GoTest:1.0
REPOSITORY     TAG         IMAGE ID       CREATED         SIZE
GoTest         1.0         18e7bd58d94b   20 seconds ago  309MB

但如果我们实际编译项目,会发现生成的可以执行文件是非常小的:

$ ls -lh main
-rwxr-xr-x  1 sun  staff   5.9M  7  6 16:35 main

可执行文件非常小,而构建的镜像非常大,这是因为我们是以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 ./main /
# 运行
CMD ["./main"]

编译可执行程序:

$ go build -o main .

构建镜像:

$ docker build -t GoTest:2.0

查看镜像:

$ docker image ls GoTest:2.0
REPOSITORY       TAG           IMAGE ID         CREATED             SIZE
gotest           2.0           8d3b724f8968     22 seconds ago      6.24MB

从上面显示的结果可以看到,这种方式构建产生的镜像非常小。

多阶镜像构建

我们在上面使用两种方式将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项目会使产生的镜像过大,而手动编译后再写入镜像则略显繁琐,多阶镜像构建可以很好地解决这两个问题。

到此这篇关于详解如何在Docker部署Go程序的文章就介绍到这了,更多相关Docker部署Go程序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文