将预览密钥内置到API镜像
固定Jenkins预览密钥宿主路径并收紧文件校验 通过BuildKit secret向API和工作进程镜像安装密钥文件 增加摘要缓存门禁和普通无密钥构建兼容验证 同步预览部署文档、安全边界与排障记忆
This commit is contained in:
@@ -58,6 +58,14 @@ Linux Docker Engine 若要从宿主机 CLI 连到容器内服务,直接用 `ht
|
||||
|
||||
`api-server` 容器镜像只构建 Linux release API 二进制,不构建 `spacetime-module`。当前 `api-server -> spacetime-client -> spacetimedb-sdk 2.7.0` 依赖链继续兼容 Rust 1.93,因此 `deploy/container/api-server.Dockerfile` 的 Rust builder 固定为 `rust:1.93-bookworm`。Web builder 显式安装并校验 npm `10.9.7`,再按唯一根 workspace lock 执行一次 `npm ci`,不依赖 Node 基础镜像隐含的 npm 版本。镜像构建阶段会同时复制 `public/`,用于满足 API 二进制里 `include_bytes!` 引用的内置素材;不要把 `public/generated-*` 放入镜像上下文。如果本机 Docker Hub 拉取失败,可以先在本机准备同名本地 builder 镜像,但不要把临时 bootstrap 容器或私有 registry 凭据写入仓库。
|
||||
|
||||
### Jenkins 预览 secrets 镜像边界
|
||||
|
||||
Jenkins 分支预览构建固定从宿主 `/data/jenkins/preview-secrets/.env.secrets.local` 读取 secrets。目录由 Jenkins 运行账号所有且权限为 `0700`,文件由同一账号所有且权限为 `0600`;构建入口对缺失、链接、非普通文件、owner 不匹配和过宽权限均失败关闭。不要把真实值写入本 README、仓库示例或 Jenkins 参数。
|
||||
|
||||
该文件不复制到源码 checkout 和 Docker build context,而是以 BuildKit `secret` mount 只提供给 `api-runtime` stage。构建会把它安装到 API 运行镜像的 `/srv/genarrative/.env.secrets.local`,owner 为 `genarrative`、权限为 `0400`。Web builder、`nginx-runtime`、SpacetimeDB 和其它运行镜像不得获得该 mount 或目标文件;构建日志和 artifact 也不得回显或保存文件内容。容器的显式运行环境变量优先于该内置文件,可按预览实例覆盖其中的值。
|
||||
|
||||
修改宿主固定文件后必须重新构建并替换 API 镜像;重启旧容器不会读取宿主新内容。这个镜像不是可公开分发的无密钥产物:镜像持有者可以提取 `/srv/genarrative/.env.secrets.local`。只允许在当前受信任内网 Docker 主机使用,禁止 push 或 `docker save`、artifact 导出到跨信任边界的 registry、主机或存储。
|
||||
|
||||
### Gitea CI 预构建 Job 镜像
|
||||
|
||||
`.gitea/workflows/project-ci.yml` 的四个 job 统一使用 `deploy/container/gitea-ci-job.Dockerfile` 构建的 `genarrative-ci` 环境。镜像固定 Ubuntu job base digest `sha256:58ea92624c7c09582e05594d95488331045053d3a3f34cf09649f2a32313a614` 和 Rust stage digest `sha256:19817ead3289c8c631c73df281e18b59b172f6a31f4f563290f69cddd06c30e9`;Node `22.23.1` 发行包在解压前执行 SHA-256 校验,Google Linux 主签名指纹固定为 `EB4C1BFD4F042F6DDDCCEC917721F63BD38B4796`,Chrome 固定为 `150.0.7871.181-1`。镜像预装 Rust `1.96.0`、`rustfmt`、Chrome、`bwrap`、`rg`、`ffmpeg`、`clang/lld` 和 Tauri / 后端系统依赖,并设置 `RUSTUP_AUTO_INSTALL=0`;仓库工具链变更时必须先重建镜像,不允许 job 现场下载补齐。
|
||||
@@ -245,5 +253,5 @@ npm run container:logs -- otelcol
|
||||
- 不改生产 systemd 单元。
|
||||
- 不改 Jenkins 发布主流程。
|
||||
- 不要求真实 HTTPS 证书。
|
||||
- 不把真实 `.env`、`.env.local`、`.env.secrets.local` 或 `deploy/container/api-server.env` 放入 Docker build context。
|
||||
- 不把真实 `.env`、`.env.local`、`.env.secrets.local` 或 `deploy/container/api-server.env` 放入 Docker build context;Jenkins 预览只使用上述 BuildKit secret 边界将固定文件内置到 `api-runtime`。
|
||||
- 不在容器镜像里内置 SpacetimeDB 数据或 token。
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
|
||||
FROM rust:1.93-bookworm AS rust-builder
|
||||
WORKDIR /workspace
|
||||
|
||||
@@ -21,6 +23,15 @@ COPY --from=rust-builder /tmp/api-server /usr/local/bin/api-server
|
||||
RUN mkdir -p /var/lib/genarrative/auth /var/lib/genarrative/tracking-outbox /var/lib/genarrative/wallet-refund-outbox && \
|
||||
chown -R genarrative:genarrative /srv/genarrative /var/lib/genarrative
|
||||
|
||||
ARG GENARRATIVE_PREVIEW_SECRETS_SHA256=
|
||||
RUN --mount=type=secret,id=genarrative_preview_secrets,required=false \
|
||||
if [ -n "${GENARRATIVE_PREVIEW_SECRETS_SHA256}" ]; then \
|
||||
test -f /run/secrets/genarrative_preview_secrets; \
|
||||
test "$(sha256sum /run/secrets/genarrative_preview_secrets | cut -d ' ' -f 1)" = "${GENARRATIVE_PREVIEW_SECRETS_SHA256}"; \
|
||||
install -o genarrative -g genarrative -m 0400 \
|
||||
/run/secrets/genarrative_preview_secrets /srv/genarrative/.env.secrets.local; \
|
||||
fi
|
||||
|
||||
USER genarrative
|
||||
EXPOSE 8082
|
||||
|
||||
|
||||
Reference in New Issue
Block a user