# 多阶段构建:builder 出静态二进制,runner 极简 # Builder # 注:go.mod 的 go 指令是 1.26.0(本机 go mod tidy 用 Go 1.27 写入), # base image 必须 >= 1.26,否则 go mod download 会因 GOTOOLCHAIN=local 失败 FROM golang:1.27-alpine AS builder # 国内构建场景下可换成 aliyun / tencent 镜像 # RUN sed -i 's|dl-cdn.alpinelinux.org|mirrors.aliyun.com|g' /etc/apk/repositories # CGO=0 出纯静态二进制,目标 alpine 不用 glibc ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ GOPROXY=https://goproxy.cn,direct \ GOSUMDB=sum.golang.google.cn WORKDIR /src # 先拷贝 go.mod/go.sum 利用 Docker layer 缓存 COPY go.mod go.sum ./ RUN go mod download # 拷贝源码并构建 COPY . . RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/server ./cmd/server # Runner FROM alpine:3.20 # 时区(中国用户)+ tini 收僵尸进程 RUN apk add --no-cache ca-certificates tzdata tini && \ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ echo "Asia/Shanghai" > /etc/timezone # 非 root 运行 RUN addgroup -S fuellog && adduser -S -G fuellog fuellog WORKDIR /app COPY --from=builder /out/server /app/server # 数据目录(SQLite) RUN mkdir -p /data && chown -R fuellog:fuellog /data /app USER fuellog ENV SERVER_ADDR=:8080 \ GIN_MODE=release \ DB_PATH=/data/fuellog.db \ TZ=Asia/Shanghai EXPOSE 8080 # 数据卷挂载点 VOLUME ["/data"] ENTRYPOINT ["/sbin/tini", "--"] CMD ["/app/server"] # 健康检查(用 wget,alpine 自带 busybox;或用 curl apk add) HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ CMD wget -q -O- http://127.0.0.1:8080/health > /dev/null || exit 1