详解如何在Docker部署Go程序

 更新时间:2023年08月01日 10:56:01   作者:程序员读书  
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程序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Docker 配置容器固定IP的方法

    Docker 配置容器固定IP的方法

    这篇文章主要介绍了Docker 配置容器固定IP,下面使用docker自带的network实现固定ip分配,并且重启不会消失,通过绑定步骤给大家介绍的非常详细,需要的朋友参考下吧
    2022-04-04
  • Docker安装Redis最新图文教程(非常全)

    Docker安装Redis最新图文教程(非常全)

    Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value的NoSQL数据库,这篇文章主要给大家介绍了关于Docker安装Redis的相关资料,需要的朋友可以参考下
    2023-11-11
  • Docker利用DockerFile创建部署NVIDIA+PyTorch容器的详细过程

    Docker利用DockerFile创建部署NVIDIA+PyTorch容器的详细过程

    这篇文章主要介绍了Docker利用DockerFile创建部署NVIDIA+PyTorch容器的详细过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • Mac为docker和kubectl添加自动补全命令的方法

    Mac为docker和kubectl添加自动补全命令的方法

    很多朋友不太明白如何为docker和kubectl添加自动补全命令,本文通过一些示例给大家介绍kubectl基础概念及语法知识,需要的朋友参考下吧
    2021-06-06
  • 聊聊kubernetes1.20用containerd替换docker(shim)的问题

    聊聊kubernetes1.20用containerd替换docker(shim)的问题

    这篇文章主要介绍了kubernetes1.20用containerd替换docker(shim),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • 解决docker安装后运行hello-world报错的问题

    解决docker安装后运行hello-world报错的问题

    这篇文章主要介绍了解决docker安装后运行hello-world报错的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • docker-compose安装RabbitMQ及插件操作步骤

    docker-compose安装RabbitMQ及插件操作步骤

    这篇文章主要为大家介绍了docker-compose安装RabbitMQ及插件操作步骤详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • Docker安装RabbitMQ AMQP协议及重要角色

    Docker安装RabbitMQ AMQP协议及重要角色

    这篇文章主要为大家介绍了Docker安装RabbitMQ AMQP协议和主要角色详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • 使用Distroless提高容器安全

    使用Distroless提高容器安全

    这篇文章主要为大家介绍了使用Distroless提高容器安全,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • docker使用registry搭建本地镜像仓库实例详解

    docker使用registry搭建本地镜像仓库实例详解

    这篇文章主要介绍了docker使用registry搭建本地镜像仓库实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09

最新评论