多阶段构建Golang程序Docker镜像

栏目: IT技术 · 发布时间: 3年前

内容简介:Docker是基于Linux容器技术(LXC),使用Go语言实现的开源项目,诞生于2013年,遵循Apache2.0协议。Docker自开源后,受到广泛的关注和讨论。使用Docker,开发人员可以使用镜像来快速构建一套标准的开发环境,开发完后,测试和运维人员可以直接使用完全相同的环境来部署代码,实现了生产环境的无缝运行。Docker容器的运行不需要额外的虚拟化管理程序支持,它是内核级的虚拟化 ,可以实现更高的性能,同时对资源的额外需求很低。

Docker简介

Docker是基于 Linux 容器技术(LXC),使用 Go 语言实现的开源项目,诞生于2013年,遵循Apache2.0协议。Docker自开源后,受到广泛的关注和讨论。

Docker在开发和运维中的优势

  • 更快的交付和部署

使用Docker,开发人员可以使用镜像来快速构建一套标准的开发环境,开发完后,测试和运维人员可以直接使用完全相同的环境来部署代码,实现了生产环境的无缝运行。

  • 更高效的资源利用

Docker容器的运行不需要额外的虚拟化管理程序支持,它是内核级的虚拟化 ,可以实现更高的性能,同时对资源的额外需求很低。

  • 更轻松的迁移和扩展

Docker容器几乎可以在任意的平台上运行,支持主流的操作系统发行版本。这种兼容性让用户可以在不同平台之间轻松地迁移应用。

  • 更简单的更新管理

使用Dockerfile,只需要修改一点点配置,就可以替代以往大量的更新工作。并且所有的修改都以增量的方式被分布和更新,从而实现自动化且高效的容器管理。

首先需要知道以下几个概念

  • Docker镜像

Docker镜像类似于虚拟机镜像,可以将它理解为一个只读的模板。镜像是创建 Docker 容器的基础。通过版本管理和增量的文件系统,Docker提供了一套十分简单的机制和创建和更新现有的镜像,用户可以直接从网上下载一个已经做好的应用镜像,并直接使用。

  • Docker容器

Docker容器类似于一个轻量级的沙箱,Docker利用容器来运行和隔离应用。容器是从镜像创建的应用运行实例。可以将其启动、开始、停止、删除,而这些容器都是彼此相互隔离的,互不可见的。

可以把容器看做一个简易版的Linux系统环境(包括root用户权限、进程空间、用户空间和网络空间)以及运行在其中的应用程序打包而成的盒子。

  • Docker仓库

Docker仓库类似于代码仓库,它是Docker集中存放镜像文件的场所。它的设计理念与Git类似。Docker镜像库分公开仓库和私有仓库。最大的公开仓库是官方提供的Docker Hub。当然,如果不想公开镜像,可以搭建自己的私有仓库。

  • Dockerfile

一般介绍完以上三个概念就结束了,但我在这里要介绍下Dockerfile,因为镜像的好坏很大程度取决于Dockerfile。Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile来快速创建自定义的镜像。

多阶段构建Golang应用Docker镜像

一般Golang的Dockerfile文件会像这样:

# Go语言环境基础镜像
FROM golang:latest

# 将源码拷贝到镜像中
COPY server.go /go/release/

# 指定工作目录
WORKDIR /go/release

# 编译镜像时,运行 go build 编译生成 app 可执行的二进制文件
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOARM=6 go build -ldflags '-w -s' -o app server.go

# 指定容器运行时入口程序 app
ENTRYPOINT ["/go/release/app"]

这种方式构建的Docker镜像体积非常大,构建时间长,占用磁盘空间,部署速度慢。

本篇将使用 多阶段构建(multi-stage builds) 的方式来减少生成的Docker镜像的体积。

多阶段构建 的过程中,我们在Dockerfile使用多个 FROM 指令,每个 FROM 指令使用不同的基础镜像构成了不同阶段。你可以选择从上一个阶段的产物(一般指生成的文件)复制到下一个阶段,从而确保不会把不需要的东西带到下一阶段。这种方法可以有效减小Docker镜像的大小。 参考官网

开源项目---gin+vue前后端分离项目 为例,介绍Golang应用如何使用 多阶段构建 Docker镜像。

项目结构图 多阶段构建Golang程序Docker镜像

直接上 Dockerfile

# 构建:使用golang:1.13版本
FROM golang:1.13 as build

# 容器环境变量添加,会覆盖默认的变量值
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.cn,direct

# 设置工作区
WORKDIR /go/release

# 把全部文件添加到/go/release目录
ADD . .

# 编译:把cmd/main.go编译成可执行的二进制文件,命名为app
RUN GOOS=linux CGO_ENABLED=0 GOARCH=amd64 go build -ldflags="-s -w" -installsuffix cgo -o app cmd/main.go

# 运行:使用scratch作为基础镜像
FROM scratch as prod

# 在build阶段复制时区到
COPY --from=build /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# 在build阶段复制可执行的go二进制文件app
COPY --from=build /go/release/app /
# 在build阶段复制配置文件
COPY --from=build /go/release/config ./config

# 启动服务
CMD ["/app"]

Dockerfile各指令详细介绍:https://docs.docker.com/engine/reference/builder/#usage

构建阶段,以golang:1.13为基础镜像,把项目编译成Linux x64位系统可执行的二进制文件(命名为app)。运行阶段,把必要的配置文件和app复制到scratch镜像中运行。最后的镜像只包括运行阶段的文件,所以体积很小,只有10多M。

  • golang编译知识
GOOS=linux CGO_ENABLED=0 GOARCH=amd64 go build -ldflags="-s -w" -installsuffix cgo -o app cmd/main.go

GOOS :目标系统为 linux

CGO_ENABLED :默认为 1 ,启用 C语言 版本的GO编译器,通过设置成 0 禁用它

GOARCH :32位系统为 386 ,64位系统为 amd64

-ldflags :用于传递每个go工具链接调用的参数。

-s
-w

-installsuffix :在软件包安装的目录中增加后缀标识,用于区分默认版本

-o :指定编译后的可执行文件名称

cmd/main.gomain 函数所在路径

scratch镜像

scratch是一个空镜像,只能用于构建其他镜像,比如你要运行一个包含所有依赖的二进制文件,如Golang程序,可以直接使用scratch作为基础镜像。scratch本身是不占空间的,所以使用它构建的镜像大小几乎和二进制文件本身一样大,从而让Golang应用的Docker镜像体积非常小。 参考:https://mp.weixin.qq.com/s/S1Ib08SpQbf1SCbCutUoqQ

制作Golang程序Docker镜像

这里直接使用Linux服务器制作Docker镜像,也可以使用Docker for windows在windows上制作Docker镜像。

  • 前提:Linux服务器安装 DockerGolang

(1)拉取项目 go get -x github.com/bingjian-zhu/gin-vue-admin/cmd

(2)修改配置文件 进入项目中 config/config.yml ,修改 database 配置,改成自己的 MySQL 数据库。 run-mode 运行模式改成 release

多阶段构建Golang程序Docker镜像

(3)生成Docker镜像

镜像名字为 zhubingjian/gin-vue-admin ,版本 1.0 ,不要漏了最后面的 .

docker build -t zhubingjian/gin-vue-admin:1.0 .

其中 zhubingjian 是我 Docker Hub 的账号,想要把镜像上传到自己的 Docker Hub 上,镜像名称需要以 Docker Hub账号 + / 开头。已经生成的镜像可以通过 tag 修改名称。

运行指令: docker images

可以看到我们生成的Docker镜像只有14.3M,非常小。名称为 none 的镜像是多阶段生成过程留下的镜像,可以使用 docker rmi 镜像ID 把它删除掉。

多阶段构建Golang程序Docker镜像

(4)运行镜像

docker run -d --name gin-vue-admin -p 8000:8000 zhubingjian/gin-vue-admin:1.0

-d
--name
-p

运行指令: docker ps -a

可以看到所有容器, STATUS 显示 Up 10 seconds ,表示两个意思:一是容器在运行;二是已经运行了10秒。如果显示 Exited 6 days ,则表示已经停止运行6天了。

多阶段构建Golang程序Docker镜像

目前为止,我们已经成功制作Docker镜像且运行了。接下来把前端的 VUE 项目也做成Docker镜像并运行。

制作VUE程序Docker镜像

  • 前提:服务器安装 Docker , nodejsnpm

(1)进入 vue-admin 目录,下载 npm

npm install

(2)修改 vue-admin 目录下的 .env.production 文件,改成自己的后台接口地址

多阶段构建Golang程序Docker镜像

(3)发布项目,生成 dist 文件夹 npm run build:prod

(4)生成Docker镜像 docker build -t zhubingjian/vue-admin:1.0 .

(5)运行镜像 docker run -p 80:80 -d --name vue-admin zhubingjian/vue-admin:1.0

参考: Docker 部署 vue 项目

最后,在浏览器上打开:http://zbj-home.picp.io

就可以看到程序已经在服务器上跑了。

把镜像推送到Docker Hub上

首先需要注册Docker Hub账号,我注册时候是有坑的,注册系统需要做人机检测,需要翻墙才能完成。官网地址:https://hub.docker.com/

(1)登录Docker Hub docker login

然后输入用户名和密码

多阶段构建Golang程序Docker镜像

(2)推送镜像

docker push zhubingjian/gin-vue-admin:1.0
docker push zhubingjian/vue-admin:1.0

总结

本篇主要介绍如何使用多阶段构建Golang程序的Docker镜像,此方法可以精简Docker镜像。

源码地址:https://github.com/Bingjian-Zhu/gin-vue-admin

参考:

  • http://blog.haohtml.com/archives/19334
  • https://blog.csdn.net/weixin_42852772/article/details/82013418
  • https://www.jianshu.com/p/4b345a9e768e

以上所述就是小编给大家介绍的《多阶段构建Golang程序Docker镜像》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

500 Lines or Less

500 Lines or Less

Amy Brown、Michael DiBernardo / 2016-6-28 / USD 35.00

This book provides you with the chance to study how 26 experienced programmers think when they are building something new. The programs you will read about in this book were all written from scratch t......一起来看看 《500 Lines or Less》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具