如何 Docker 化一个 GO 应用程序

简介: 使用 Golang,可以构建小到简单的可执行工具大到完整的 Web 服务器的任何东西。为了交付应用程序,使用 Docker 是首选,它允许我们创建一个包含项目运行所需的一切的自包含环境。值得一提的是,Docker 命令行界面本身也是使用 GO 所开发。

如何 Docker 化一个 GO 应用程序

使用 Golang,可以构建小到简单的可执行工具大到完整的 Web 服务器的任何东西。为了交付应用程序,使用 Docker 是首选,它允许我们创建一个包含项目运行所需的一切的自包含环境。值得一提的是,Docker 命令行界面本身也是使用 GO 所开发。

为任何 GO 应用程序编写 Docker 镜像

通常,从一个尽可能小且具有所需基本依赖项的基本镜像开始,是一个好主意。alpine 镜像通常是一个可靠的选择,因为它们仅包含操作系统所需的最低限度。

所以,我们可以这样写 Dockerfile

FROM golang:alpine3.15

在这个镜像中,我们可以像在任何其他环境中一样,指定构建应用程序的后续步骤。

FROM golang:alpine3.15
WORKDIR /path
COPY . .
RUN go mod download
RUN go build -o "app" .

然后,我们必须将执行权限也添加到生成的二进制文件中,以便它可以执行:

RUN chmod +x /path/app

但是,使用这样的镜像运行 GO 应用程序存在一个小问题。事实上,在构建和生成二进制文件之后,我们将不再需要在容器中安装 GO 编译环境。它只是一个依赖项,完全可以从镜像中排除掉,以优化镜像大小。这个问题的解决方案是使用 Docker 的多阶段构建。

使用多阶段构建

多阶段构建,允许将构建镜像的过程划分为一个单独的部分,并从中收集运行时所需的各种不同文件。有一种常见的模式称为 构建器模式(builder pattern)。我们可以在Dockerfile的最前面添加构建器阶段。它负责使用其构建时依赖项来组装应用程序,然后我们只需要从中挑选运行时必要的文件。

FROM golang:alpine3.15 as builder

WORKDIR /path
COPY . .

RUN go mod download
RUN go build -o "app" . 

FROM alpine:3.15.5

WORKDIR /path

RUN apk update \
  && apk -U upgrade \
  && apk add --no-cache ca-certificates bash gcc \
  && update-ca-certificates --fresh \
  && rm -rf /var/cache/apk/*

COPY --from=builder /path/app .

RUN chmod +x /path/app

ENTRYPOINT ["/path/app"]

在上面的Dockerfile,我们已经指定了构建器镜像的步骤。它将构建用于运行应用程序的二进制文件。之后,它将被转移到最终镜像。请注意,最终的镜像只是一个普通的 alpine 镜像,并没有包含任何 GO 编译环境,因为应用程序已经构建完了,不需要了。

以非root身份运行

为了完成我们的镜像,我们应该以专用用户身份来运行容器。默认情况下,docker 容器内的进程将以 root 身份运行。反之,以非 root 用户身份运行我们的容器,被认为是一种最佳的安全实践。在有人获得对容器的访问权的情况下,如果某个进程突破它,它也获取不到底层操作系统的任何特权权限。

因此,我们可以将以下几行添加到我们的Dockerfile:

RUN addgroup app_user && adduser -S app_user -u 1000 -G app_user
USER app_user

最终结果

完成所有这些步骤后,我们将得到下面的最终Dockerfile

FROM golang:alpine3.15 as builder

WORKDIR /path
COPY . .

RUN go mod download
RUN go build -o "app" .

FROM alpine:3.15.5

WORKDIR /path

RUN apk update \
  && apk -U upgrade \
  && apk add --no-cache ca-certificates bash gcc \
  && update-ca-certificates --fresh \
  && rm -rf /var/cache/apk/*

RUN addgroup app_user && adduser -S app_user -u 1000 -G app_user

COPY --chown=app_user:app_user --from=builder /path/app .

RUN chmod +x /path/app

USER app_user

ENTRYPOINT ["/path/app"]

因此,这是一个通用镜像,可用于发布用 GO 编写的应用程序。

结论

在这篇文章中,我们了解了如何创建 GO 应用程序的容器镜像。

一些与之相关的最佳实践是:

  • 使用运行程序所需的最低限度的基本镜像。
  • 多阶段构建作为优化镜像大小的一种方式。
  • 出于安全原因,以非 root 用户身份运行容器。

谢谢你坚持到最后。我希望这些技巧对你有用!

翻译自:https://medium.com/@leonardo5621_66451/how-to-dockerize-a-go-application-d196ea292c34

目录
相关文章
|
21天前
|
弹性计算 运维 持续交付
探索Docker容器化技术及其在生产环境中的应用
探索Docker容器化技术及其在生产环境中的应用
70 5
|
7天前
|
Kubernetes Go 持续交付
一个基于Go程序的持续集成/持续部署(CI/CD)
本教程通过一个简单的Go程序示例,展示了如何使用GitHub Actions实现从代码提交到Kubernetes部署的CI/CD流程。首先创建并版本控制Go项目,接着编写Dockerfile构建镜像,再配置CI/CD流程自动化构建、推送Docker镜像及部署应用。此流程基于GitHub仓库,适用于快速迭代开发。
24 3
|
7天前
|
Kubernetes 持续交付 Go
创建一个基于Go程序的持续集成/持续部署(CI/CD)流水线
创建一个基于Go程序的持续集成/持续部署(CI/CD)流水线
|
22天前
|
Cloud Native 持续交付 Docker
探索Docker容器化技术及其在软件开发中的应用
探索Docker容器化技术及其在软件开发中的应用
21 7
|
20天前
|
Devops jenkins 持续交付
DevOps实践:构建和部署一个Docker化的应用
【9月更文挑战第14天】在当今快节奏的软件开发领域,DevOps已经成为提升效率、加速交付的关键。本文将引导你理解DevOps的核心概念,并通过一个实际的示例—构建和部署一个Docker化的应用—来深入探讨其实践方法。我们将从简单的应用出发,逐步实现Docker容器化,并最终通过CI/CD流水线自动化部署过程。这不仅是对DevOps流程的一次实操演练,也是对现代软件开发理念的一次深刻体验。
|
25天前
|
持续交付 开发者 Docker
掌握 Docker:容器化技术在现代开发中的应用
Docker 是一个开源容器化平台,使开发者能够将应用程序及其依赖项封装在轻量级容器中,确保跨平台的一致性。本文介绍了 Docker 的基本概念、核心组件及优势,并展示了其在快速部署、一致性、可移植性和微服务架构中的应用。通过示例说明了 Docker 在本地开发环境搭建、服务依赖管理和 CI/CD 流程中的作用,以及多阶段构建、资源限制和网络模式等高级特性。掌握 Docker 可大幅提升开发效率和应用管理能力。
|
29天前
|
安全 大数据 Go
深入探索Go语言并发编程:Goroutines与Channels的实战应用
在当今高性能、高并发的应用需求下,Go语言以其独特的并发模型——Goroutines和Channels,成为了众多开发者眼中的璀璨明星。本文不仅阐述了Goroutines作为轻量级线程的优势,还深入剖析了Channels作为Goroutines间通信的桥梁,如何优雅地解决并发编程中的复杂问题。通过实战案例,我们将展示如何利用这些特性构建高效、可扩展的并发系统,同时探讨并发编程中常见的陷阱与最佳实践,为读者打开Go语言并发编程的广阔视野。
|
1月前
|
负载均衡 持续交付 Docker
Docker的应用场景有哪些?
Docker的应用场景有哪些?
58 6
|
1月前
|
负载均衡 大数据 测试技术
docker容器技术有哪些应用场景?
docker容器技术有哪些应用场景?
38 5
|
6天前
|
IDE Go 数据处理
Go to Learn Go之第一个Go程序
Go to Learn Go之第一个Go程序
11 0
下一篇
无影云桌面