Docker 和 Go:使用 Golang 进行应用容器化

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Docker 和 Go:使用 Golang 实现应用容器化



在现代开发中,容器化已成为部署和扩展应用程序的实际标准。Docker 和 Go 是创建轻量、快速且安全的微服务的理想组合。Go 编译成静态二进制文件,使其对容器化特别有吸引力:最终镜像可能仅有几兆字节。在本文中,我们将介绍如何正确地容器化 Go 应用程序、优化 Dockerfile 以及避免常见错误。



为什么 Docker 和 Go 是完美组合?



Go (Golang) 从设计之初就考虑了现代云端架构。其关键特性是静态编译、内建并发支持以及无外部运行时依赖。而 Docker 则提供了隔离的应用程序运行环境。两者结合,可以创建出具有以下特点的镜像:



  • 占用空间极小 — Go 应用程序镜像可以小于 10 MB。
  • 启动快速 — 静态二进制文件无需解释器或虚拟机。
  • 易于扩展 — 非常适合在 Kubernetes 中进行编排。
  • 安全性更高 — 最小化的镜像减少了攻击面。


创建一个用于容器化的简单 Go 应用程序



首先,我们编写一个简单的 Web 应用程序来进行容器化。创建文件 main.go:



package main

import ( "fmt" "log" "net/http" "os")

func main() { port := os.Getenv("PORT") if port == "" { port = "8080" }

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello from Go in Docker! 🐳") })

log.Printf("Server starting on port %s", port) log.Fatal(http.ListenAndServe(":"+port, nil))}


此应用程序监听 HTTP 请求并返回问候消息。端口可通过 PORT 环境变量设置。



为 Go 应用程序编写 Dockerfile



现在我们来创建一个 Dockerfile。我们将从基本方法开始,然后进行优化。



基础 Dockerfile(未优化)



FROM golang:1.22-alpine AS builder

WORKDIR /app

COPY go.mod go.sum ./RUN go mod download

COPY . .RUN go build -o main .

FROM alpine:latest

WORKDIR /root/

COPY --from=builder /app/main .

EXPOSE 8080

CMD ["./main"]


此 Dockerfile 使用 多阶段构建 — 这是 Go 的最佳实践之一。第一阶段(builder)编译应用程序,第二阶段(最终镜像)仅包含构建好的二进制文件。这种方法避免了将 Go 编译器和工具包含在最终镜像中。



优化后的 Dockerfile(最佳实践)



为了使镜像更小、更安全,我们使用 scratch — 一个没有 shell 或工具的空白镜像:



FROM golang:1.22-alpine AS builder

WORKDIR /app

COPY go.mod go.sum ./RUN go mod download

COPY . .

# 禁用 CGO,启用优化RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o main .

FROM scratch

WORKDIR /root/

COPY --from=builder /app/main .

# 为 HTTPS 添加根证书COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

EXPOSE 8080

CMD ["./main"]


关键优化点:

  • CGO_ENABLED=0 — 禁用 CGO,减少二进制文件大小。
  • -ldflags="-s -w" — 移除符号表和调试信息。
  • scratch — 不包含多余层的最小镜像。
  • 复制 ca-certificates.crt — 使用 HTTPS 所必需。

博客

书籍推荐