# ---------- 0) 拉取源码 ---------- FROM alpine:3.20 AS src RUN apk add --no-cache git ARG REPO_URL=https://github.com/tbphp/gpt-load.git # 如需可复现构建,可把 main 改为固定 tag 或 commit ARG REPO_REF=main WORKDIR /src # 为了能获取到全部 tag,这里不做浅克隆 RUN git clone --branch "${REPO_REF}" "${REPO_URL}" . \ && git fetch --tags --force || true \ # 取最新语义化 tag(如 v1.3.1),没有 tag 就用短 commit && LATEST_TAG="$(git tag -l --sort=-v:refname | head -n1)" \ && if [ -n "$LATEST_TAG" ]; then VERSION="${LATEST_TAG#v}"; else VERSION="$(git rev-parse --short HEAD)"; fi \ && printf "%s" "$VERSION" > /version.txt # ---------- 1) 构建前端 ---------- FROM node:20-alpine3.20 AS web-builder WORKDIR /build/web # 利用缓存:先依赖清单后源码 COPY --from=src /src/web/package*.json ./ RUN npm ci COPY --from=src /src/web ./ # 从 src 阶段带入版本号文件 COPY --from=src /version.txt ./VERSION # Vite 只认编译期变量的 VITE_ 前缀:用一次性环境变量注入 RUN VITE_VERSION="$(cat VERSION)" npm run build # ---------- 2) 构建后端(Go 1.23) ---------- FROM golang:1.23-alpine3.20 AS go-builder ENV GO111MODULE=on \ CGO_ENABLED=0 \ GOOS=linux \ GOTOOLCHAIN=auto WORKDIR /build # 先缓存依赖 COPY --from=src /src/go.mod ./ COPY --from=src /src/go.sum ./ RUN go mod download # 复制全部后端源码 COPY --from=src /src ./ # 注入前端产物 COPY --from=web-builder /build/web/dist ./web/dist # 带入版本号 COPY --from=src /version.txt ./VERSION # 更小二进制 + 正确注入版本(自动读取模块名) RUN MODULE="$(grep ^module go.mod | awk '{print $2}')" \ && VERSION="$(cat VERSION)" \ && echo ">> building ${MODULE} version=${VERSION}" \ && go build -trimpath \ -ldflags "-s -w -X ${MODULE}/internal/version.Version=${VERSION}" \ -o gpt-load . # ---------- 3) 运行阶段 ---------- FROM alpine:3.20 WORKDIR /app RUN apk add --no-cache ca-certificates tzdata && update-ca-certificates COPY --from=go-builder /build/gpt-load /app/gpt-load COPY ./run.sh /app/run.sh RUN chmod +x /app/run.sh # 关键权限:root 组可写,适配 HF 的 gid=0 运行方式 RUN mkdir -p /app/data \ && chgrp -R 0 /app \ && chmod -R g+rwX /app ENV DATABASE_DRIVER=sqlite ENV DATABASE_DSN=/app/data/gpt-load.db # Hugging Face Spaces 会注入 PORT;这里保留默认值以便本地运行 ENV PORT=7860 EXPOSE 7860 ENTRYPOINT ["/app/run.sh"]