# ==================== 阶段 1:构建前端 SPA ==================== FROM node:20-alpine AS ui # 国内网络直连官方源不稳定,npm 走 npmmirror ENV npm_config_registry=https://registry.npmmirror.com WORKDIR /ui COPY ui-src/package.json ui-src/package-lock.json ./ RUN npm ci COPY ui-src/ ./ RUN npm run build # ==================== 阶段 2:构建后端二进制(modernc sqlite 纯 Go,无 CGO) ==================== FROM golang:1.26 AS build # 国内网络直连官方源不稳定,go module 走 goproxy.cn ENV GOPROXY=https://goproxy.cn,direct WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o rag-local . # ==================== 阶段 3:精简运行镜像 ==================== # 时区数据与 CA 证书直接从 golang 构建阶段拷贝,避免 apk 联网拉包(构建环境可能无外网) FROM alpine:3.20 WORKDIR /app COPY --from=build /usr/share/zoneinfo /usr/share/zoneinfo COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt # gse 中文分词词典:LoadDict 按编译期源码位置(builder 的 /go/pkg/mod/...)逐文件加载整套 zh 词典,运行时必须同路径存在 COPY --from=build /go/pkg/mod/github.com/go-ego/gse@v1.0.2/data/dict/zh /go/pkg/mod/github.com/go-ego/gse@v1.0.2/data/dict/zh RUN adduser -D -u 1000 app && \ mkdir -p /app/data /app/workspace && \ chown -R app:app /app ENV TZ=Asia/Shanghai COPY --from=build /app/rag-local /app/rag-local COPY --from=build /app/config.yml /app/config.yml COPY --from=ui /ui/dist /app/ui-src/dist USER app EXPOSE 8080 VOLUME ["/app/data", "/app/workspace"] ENTRYPOINT ["/app/rag-local"]