Docker 镜像¶
构建¶
两个构建文件除镜像源配置外完全一致,二选一:
docker build -f docker/CN.Dockerfile -t acmecast:dev . # 中国网络:阿里云 apt / rsproxy / npmmirror
docker build -f docker/Dockerfile -t acmecast:dev . # 国际/上线:官方源
- 构建上下文 = 仓库根;
- 镜像源配置只写入 builder 层,最终运行镜像不含任何镜像源或代理配置;
- 目标平台由 buildx 的
TARGETPLATFORM决定(linux/amd64→x86_64-unknown-linux-musl,linux/arm64→aarch64-unknown-linux-musl), 镜像与目标平台同架构,不做交叉编译。
三段式结构¶
| 阶段 | 基础镜像 | 产物 |
|---|---|---|
builder |
rust:1-slim + musl target |
静态链接的 /acmecast-server |
frontend-builder |
node:24-slim + corepack/pnpm |
frontend/dist |
| 运行阶段 | gcr.io/distroless/static-debian13:nonroot |
最终镜像 |
选择依据:
- 全程 rustls(无 OpenSSL)、SSH 用纯 Rust 的 russh、无系统库依赖 → 可以 musl 静态链接,运行阶段用 distroless/static(无 shell、无包管理器)。
- 容器以 uid 65532(nonroot) 运行;
/data声明为 VOLUME。 - Swagger UI 资源用仓库内随附的
docker/swagger-ui-v5.17.14.zip(SWAGGER_UI_DOWNLOAD_URL=file:///tmp/swagger-ui.zip),构建不访问外网。 - builder 阶段用 cache mount 复用 cargo registry 与 target,增量构建快。
镜像内固定环境变量:
ENTRYPOINT ["acmecast-server"](二进制位于 /usr/bin)——子命令直接作为
参数:docker run --rm acmecast:dev hash-password --password 'xxx'。
.dockerignore 要点¶
构建上下文排除:target/、data/、*.db*、编辑器文件、
frontend/node_modules、frontend/dist、site/、.cache/、.cargo/、
mise.toml/mise.lock、openspec/,以及 DNSTOKEN.md(本地 DNS 凭据
笔记,绝不进镜像与构建上下文)。
发布流水线¶
- GitHub Actions 只跑 CI(lint/test/build/集成),不发布镜像。
- CNB(
.cnb.yml):push 到main构建并推送<registry>/<repo>:latest,push 到dev推送:dev;同流水线还把 本文档站点(zensical build)部署到 EdgeOne Pages(main → 生产, dev → 预览)。