ARG GO_VERSION=1.26 ARG ALPINE_VERSION=3.22 # ============================== 构建阶段 ============================== FROM golang:${GO_VERSION}-alpine AS builder # TARGETOS/TARGETARCH 由 BuildKit 在 --platform 下自动注入,此处默认值保证 # 未启用 buildx 时也能正常构建(默认 linux/amd64)。 ARG TARGETOS=linux ARG TARGETARCH=amd64 # Go 模块代理:默认官方代理;国内或受限网络可覆盖: # --build-arg GOPROXY=https://goproxy.cn,direct ARG GOPROXY=https://proxy.golang.org,direct ENV GOPROXY=${GOPROXY} WORKDIR /src # 先只复制依赖清单,源码未变动时复用 go mod 下载缓存,加快重建。 COPY go.mod go.sum ./ RUN go mod download COPY . . # 静态编译:CGO_ENABLED=0 使二进制不依赖 libc,可运行在任意精简基础镜像; # -trimpath 去除本地绝对路径保证构建可复现,-s -w 去除符号表与调试信息以减小体积。 ENV CGO_ENABLED=0 RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -trimpath -ldflags="-s -w" -o /out/zt-closet-manage-backend . # ============================== 运行阶段 ============================== FROM alpine:${ALPINE_VERSION} # ca-certificates:访问 HTTPS 端点需要根证书; # tzdata:业务按本地时区计算「每日 0 点」相关展示,需与 TZ 配合使用; # 运行进程使用非 root 用户 app(uid/gid 10001)。 RUN apk add --no-cache ca-certificates tzdata \ && addgroup -g 10001 -S app \ && adduser -u 10001 -S -G app app WORKDIR /app COPY --from=builder /out/zt-closet-manage-backend /app/zt-closet-manage-backend # configs/ :配置文件挂载点(config.yaml 含密钥,不打入镜像,必须运行时挂载) # storage/logs:日志目录(对应配置 Log.LogSavePath) RUN mkdir -p /app/configs /app/storage/logs \ && chown -R app:app /app ENV TZ=Asia/Shanghai # 仅用于 EXPOSE 与健康检查:真实监听端口由 configs/config.yaml 的 Server.HttpPort 决定,两者需保持一致(当前 8081)。 ENV APP_PORT=8081 USER app EXPOSE ${APP_PORT} HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ CMD wget -q -O - "http://127.0.0.1:${APP_PORT}/ping" || exit 1 # 启动服务(admin_users 表由服务启动时 AutoMigrate 幂等创建,无独立迁移命令) CMD ["/app/zt-closet-manage-backend"]