打包go应用为镜像

123 阅读2分钟

第一步:编写 Dockerfile并构建镜像

我们需要创建一个下载go第三方包的共享镜像以免每次重复下载,然后分别为 masterworker 创建 Dockerfile,并基于 golang:1.24(或更新版本)进行构建。

1️⃣ 共享第三方包基础镜像的 Dockerfile

文件路径:./dockerfile.godeps

# 使用官方 Go 运行时镜像
FROM golang:1.24 AS builder

# 设置工作目录
WORKDIR /app

# 复制项目代码
COPY go.mod go.sum ./

RUN go env -w GOPROXY=https://goproxy.cn,direct

# 下载依赖
RUN go mod download

2️⃣ master、Worker 的 Dockerfile

文件路径:./masterfile,./workerfile

masterfile

# 使用官方 Go 运行时镜像
FROM godeps:v0.1 AS builder

# 设置工作目录
WORKDIR /app

# 复制项目代码
COPY . .

# 编译 Master 服务
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o masterapp /app/master/main.go

# 运行时镜像
FROM alpine:latest

WORKDIR /root/
COPY --from=builder /app/masterapp .

# 暴露端口(Gin API 和 Prometheus 监控)
EXPOSE 8080 8081

CMD ["./masterapp"]

workerfile

# 使用官方 Go 运行时镜像
FROM godeps:v0.1 AS builder

# 设置工作目录
WORKDIR /app

# 复制项目代码
COPY . .

# 编译 Master 服务
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o workerapp /app/worker/main.go

# 运行时镜像
FROM alpine:latest

WORKDIR /root/
COPY --from=builder /app/workerapp .

# 暴露端口(Gin API 和 Prometheus 监控)
EXPOSE 50051

CMD ["./workerapp"]

编译镜像

go build -t godeps:v0.1 -f dockerfile.godeps .
go build -t masterapp:v0.1 -f masterfile
go build -t workerapp:v0.1 -f workerfile

备注:dockerfile中CGO_ENABLED=0选项为静态编译,这样生成的二进制文件就不会依赖 glibc,可以直接在 alpine 上运行


📌 第二步:编写 Docker Compose 文件

我们使用 Docker Compose 来管理 Master 和多个 Worker 实例。

文件路径:docker-compose.yml

version: '3.8'

services:
  master:
    image: masterapp:v0.2
    ports:
      - "8080:8080"
      - "8081:8081"
    depends_on:
      - worker
    networks:
      - scheduler-net

  worker:
    image: workerapp:v0.1
    ports:
      - "50051:50051"
    networks:
      - scheduler-net

networks:
  scheduler-net:
    driver: bridge

备注:容器间的通信是通过域名解析ip地址来进行的,因此master代码中需要修改var workerNodes = []string{"worker:50051"},将127.0.0.1替换为worker域名,这样compose文件中可以指定域名通信。


📌 第三步:运行 Docker 容器

1 启动所有服务

docker-compose -f dockercompose.yml  up 

可以添加-d 选项表示以 后台模式 运行容器。

2 查看运行状态

docker ps

你应该能看到 MasterWorker 容器在运行:

image.png

📌 第四步:关闭和清理

1️⃣ 停止容器

docker-compose -f dockercompose.yml down

2️⃣ 清理镜像(如果需要)

docker system prune -a