ARG GO_VERSION=1.27
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-backend .

# ============================== 运行阶段 ==============================
FROM alpine:${ALPINE_VERSION}

# ca-certificates：访问 COS / 微信支付 / 大模型网关等 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-backend /app/zt-closet-backend

# configs/    ：配置文件挂载点（config.yaml 含密钥，不打入镜像，必须运行时挂载）
# storage/logs：日志目录（对应配置 Log.LogSavePath）
# storage/uploads：上传临时目录（对应配置 Upload.TmpSavePath）
RUN mkdir -p /app/configs /app/storage/logs /app/storage/uploads \
    && chown -R app:app /app

ENV TZ=Asia/Shanghai
# 仅用于 EXPOSE 与健康检查：真实监听端口由 configs/config.yaml 的 Server.HttpPort 决定，两者需保持一致。
ENV APP_PORT=8080

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

# 启动服务（数据库迁移在容器外通过 go run ./cmd/migrate 手动执行）
CMD ["/app/zt-closet-backend"]
