From 9f40162c6be33797792a447fbda3843faf4621e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=AE=97=E7=90=A6?= <442782435@qq.com> Date: Sat, 15 Aug 2026 14:26:32 +0800 Subject: [PATCH] build: add self-contained alpine-only Go image build --- .../20260814-alpine-only-build-3b8e5a6d.md | 38 +++++++++++++++++++ backend/Dockerfile.alpine | 31 +++++++++++++++ backend/README.md | 9 +++++ docs/DEPLOYMENT.md | 6 ++- 4 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 .project-docs/30-worklog/tasks/20260814-alpine-only-build-3b8e5a6d.md create mode 100644 backend/Dockerfile.alpine diff --git a/.project-docs/30-worklog/tasks/20260814-alpine-only-build-3b8e5a6d.md b/.project-docs/30-worklog/tasks/20260814-alpine-only-build-3b8e5a6d.md new file mode 100644 index 0000000..6769c08 --- /dev/null +++ b/.project-docs/30-worklog/tasks/20260814-alpine-only-build-3b8e5a6d.md @@ -0,0 +1,38 @@ +# Task: Add self-contained alpine-only Go image build + +## Identity + +- Task ID: 20260814-alpine-only-build-3b8e5a6d +- Mode: Feature +- Branch: main +- Worktree: /Users/brother7/Documents/AI/NianAIGC +- Base commit: d82e7a104e84e0d6161adbda5339a6ad27088b91 +- Owner: dsh +- Status: Ready for Integration + +## Scope + +- Provide a single-command docker build for the Go image that pulls only the alpine base image: the Go toolchain is installed from Alpine's package repositories (aliyun apk mirror) and module downloads use goproxy.cn, so no golang builder image and no external dockerfile frontend are needed. + +## Intent And Constraints + +- Runtime stage identical to the existing images (non-root uid/gid 10001, ca-certificates, tzdata). +- Build-stage network dependencies are all China-accessible (aliyun apk mirror, goproxy.cn, sum.golang.google.cn). + +## Outcome + +- Added `backend/Dockerfile.alpine` with a self-contained two-stage build. +- Documented it as the recommended build in `backend/README.md` and `docs/DEPLOYMENT.md`. + +## Verification + +- Dockerfile static review; the compile step is the same `CGO_ENABLED=0 go build` already verified locally (12.3 MB static ELF). +- Actual image build must run on the CI machine: `docker build -f backend/Dockerfile.alpine -t REGISTRY/PROJECT/zhinian-go-api:TAG backend/`. + +## Follow-ups + +- Re-run the CI build with the new one-command path. + +## Promotion Candidates + +- None. diff --git a/backend/Dockerfile.alpine b/backend/Dockerfile.alpine new file mode 100644 index 0000000..ab97800 --- /dev/null +++ b/backend/Dockerfile.alpine @@ -0,0 +1,31 @@ +# Self-contained one-command build: only the alpine base image is pulled — +# no golang builder image, no external dockerfile frontend. The Go toolchain +# comes from Alpine's package repositories (mirrored to Aliyun), and module +# downloads use goproxy.cn, so the whole build works on China CI networks. +# +# docker build -f backend/Dockerfile.alpine \ +# -t REGISTRY/PROJECT/zhinian-go-api:TAG backend/ +FROM alpine:3.20 AS build +RUN sed -i 's#https\?://dl-cdn.alpinelinux.org#https://mirrors.aliyun.com#' /etc/apk/repositories \ + && apk add --no-cache go +WORKDIR /src +ENV CGO_ENABLED=0 \ + GOOS=linux \ + GOPROXY=https://goproxy.cn,direct \ + GOSUMDB=sum.golang.google.cn +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN go build -trimpath -ldflags="-s -w" -o /out/zhinian-api ./cmd/zhinian-api + +FROM alpine:3.20 +RUN sed -i 's#https\?://dl-cdn.alpinelinux.org#https://mirrors.aliyun.com#' /etc/apk/repositories \ + && apk add --no-cache ca-certificates tzdata \ + && addgroup -S -g 10001 zhinian \ + && adduser -S -D -H -u 10001 -G zhinian zhinian \ + && mkdir -p /var/lib/zhinian \ + && chown -R zhinian:zhinian /var/lib/zhinian +COPY --from=build /out/zhinian-api /usr/local/bin/zhinian-api +USER 10001:10001 +EXPOSE 8080 +ENTRYPOINT ["zhinian-api"] diff --git a/backend/README.md b/backend/README.md index 5d1f1b1..5348387 100644 --- a/backend/README.md +++ b/backend/README.md @@ -39,6 +39,15 @@ npm run go:build ## Container images +Self-contained build (recommended for China CI; single command, only the +alpine base image is pulled — the Go toolchain comes from Alpine's packages +via the Aliyun apk mirror and modules come from goproxy.cn): + +```bash +docker build -f backend/Dockerfile.alpine \ + -t REGISTRY/PROJECT/zhinian-go-api:TAG backend/ +``` + Standard multi-stage build (needs the `golang` builder image): ```bash diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index 80a8ef2..f298f19 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -25,9 +25,13 @@ RDS/服务商凭据,仅共享会话密钥);Go 工作负载 `zhinian-go-api` 独 Node Worker,`worker.yaml` 已弃用保留)。Ingress 按路径分流:页面 → Web, 后端路径 → Go,`/api/internal/worker` → 无端点 deny Service。 -Go 镜像构建(三选一,详见 [`backend/README.md`](./backend/README.md)): +Go 镜像构建(四选一,详见 [`backend/README.md`](./backend/README.md)): ```bash +# 自包含构建(推荐国内 CI):单条命令,只拉 alpine 基础镜像,Go 工具链来自 +# alpine 包(阿里云 apk 镜像),模块走 goproxy.cn +docker build -f backend/Dockerfile.alpine -t REGISTRY/PROJECT/zhinian-go-api:TAG backend/ + # 标准多阶段构建 docker build -f backend/Dockerfile -t REGISTRY/PROJECT/zhinian-go-api:TAG backend/