使用 Docker 部署
部署包通过 Business 渠道提供;此处未验证其发布状态。使用本地 chart 前,请按渠道说明验证包及其发布者。清单示例使用 Business 提供的
business-install.yaml。隔离环境安装需要 Enterprise。
Helm, Kubernetes operators, Terraform, appliance and FIPS/STIG images are Business deployment artifacts. The source paths below are in the Business distribution. Air-gapped installation requires Enterprise.
本指南面向用 Docker 将 Olivares AI control plane 投入生产的工程师与 SRE。 整个产品是一个单镜像——引擎内嵌 web UI——因此单台主机即可运行 SQLite 拓扑而无需任何外部依赖,在需要时通过 Postgres override 即可获得多租户拓扑。 容器镜像基于 Debian 13 slim(含供智能体工具使用的 Node.js 24),并以非 root 用户运行。 每条路径都保持相同的安全默认值:无默认凭据、一次性 setup token、默认开启 TLS, 以及默认启用的 TLS。主机端口默认发布在所有网络接口上,因为这是一台服务器——请按下文有意识地加以限制。
要从决策页的角度查看所有部署选项及其默认值,参见 自托管 control plane。对于断网站点,参见 在 air-gapped 环境中安装;对于横向扩展, 参见下文的 Kubernetes/Helm 路径。
1. 拉取并验证镜像
Section titled “1. 拉取并验证镜像”主要的容器拉取来源是 Docker Hub:
docker pull docker.io/olivaresai/olivares:0.4相同的内容也发布到 ghcr.io/olivaresai/olivares——按 digest 完全一致,
用作备份和构建 registry。Docker Hub 对匿名拉取施加速率限制;ghcr.io 不对公共镜像的匿名拉取
限速——因此当 CI 节点或大规模集群触及上限时,可以先 docker login,或改用 ghcr.io 坐标。
Tag 不带前导 v:
:0.4 固定一个版本,:latest 浮动,而 :0.4-fips / :0.4-stig
是加固变体。基础 tag 和 :latest 是多架构的
(linux/amd64、linux/arm64);fips/stig 仅有 amd64。
control plane 是一款安全产品,所以运行前先验证。签名是
**无密钥(keyless,Sigstore)**的,针对项目的 GitHub Actions 身份,
并且对任一 registry 工作方式相同——签名与证明(attestation)通过
cosign copy 复制到 Docker Hub,因此 digest 相同:
IMAGE=docker.io/olivaresai/olivares # fallback: ghcr.io/olivaresai/olivares (same digest)DIGEST="$(crane digest "$IMAGE:0.4")"REF="$IMAGE@$DIGEST"
cosign verify "$REF" \ --certificate-identity-regexp '^https://github\.com/olivaresai/olivares/\.github/workflows/release\.yml@refs/tags/[0-9]+\.[0-9]+$' \ --certificate-oidc-issuer https://token.actions.githubusercontent.comcosign verify-attestation "$REF" --type spdxjson \ --certificate-identity-regexp '^https://github\.com/olivaresai/olivares/\.github/workflows/release\.yml@refs/tags/[0-9]+\.[0-9]+$' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com完整的信任链——校验和签名、SBOM、OpenVEX、SLSA provenance——在 验证你下载的内容中。验证完成后, 请按你所验证的 digest 进行部署,绝不要用可变的 tag (参见 §8)。
2. 单节点,SQLite
Section titled “2. 单节点,SQLite”使用 docker run(加固)
Section titled “使用 docker run(加固)”镜像的默认命令在容器内部绑定 0.0.0.0,以便你用 ingress 在前面承载它;
主机侧端口映射决定暴露面:下面发布在所有主机接口上——改用 -p 127.0.0.1:8443:8443 可把控制台留在本机。以非 root、只读、丢弃所有
capabilities 的方式运行:
docker volume create olivares-data
docker run -d --name olivares \ --user 65532:65532 \ --read-only \ --tmpfs /tmp \ --cap-drop ALL \ --security-opt no-new-privileges \ -v olivares-data:/var/lib/olivares \ -p 8443:8443 \ -p 8444:8444 \ docker.io/olivaresai/olivares:0.4 \ serve \ --listen=0.0.0.0:8443 \ --grpc-listen=0.0.0.0:8444 \ --data-dir=/var/lib/olivares \ --checkpoint-interval=1h| 标志 | 原因 |
|---|---|
--user 65532:65532 |
以烘焙进镜像的非 root nonroot UID 运行 |
--read-only |
根文件系统不可变;只有数据卷和 /tmp 可写 |
--tmpfs /tmp |
一个可写的临时 tmpfs,因 rootfs 只读而必需 |
--cap-drop ALL |
引擎不需要任何 Linux capabilities |
--security-opt no-new-privileges |
阻止通过 setuid 二进制提权 |
-v olivares-data:/var/lib/olivares |
持久化数据目录(参见 §5) |
-p 8443:8443 |
向所有主机接口发布 HTTPS(REST + web UI) |
-p 8444:8444 |
向所有主机接口发布 gRPC(摄取 / ControlPlane API) |
从日志读取一次性 setup token 并创建第一位管理员:
docker exec olivares olivares first-boot # the console address(es) + setup statedocker logs olivares | sed -n '/FIRST-BOOT SETUP/,/========================/p'
curl -fsS -k -X POST https://127.0.0.1:8443/v1/setup \ -H 'Content-Type: application/json' \ -d '{"token":"<olst_ token>","email":"you@example.com","password":"<strong-password>"}'-k 接受引擎在首次启动时签发的自签名证书;请通过反向代理
(§6)或你自己的 TLS 材料将其替换为
真实证书。该 token 只显示一次,且为一次性使用。
使用 Docker Compose
Section titled “使用 Docker Compose”仓库附带一套 Compose stack,它接好数据卷、发布的端口, 以及与上文相同的加固标志:
docker compose -f deploy/compose/docker-compose.yml up -d
# Where the console answers, and whether first setup is still pending:docker compose -f deploy/compose/docker-compose.yml exec olivares olivares first-boot
# Read the one-time first-boot setup token:docker compose -f deploy/compose/docker-compose.yml logs olivares | sed -n '/FIRST-BOOT SETUP/,/========================/p'
# What is running, and how to stop it. Every command needs the -f: this file lives in# deploy/compose/, so a bare `docker compose ps` answers "no configuration file provided".docker compose -f deploy/compose/docker-compose.yml psdocker compose -f deploy/compose/docker-compose.yml down
# Then open https://localhost:8443 (self-signed TLS by default)基础文件将镜像默认设为 docker.io/olivaresai/olivares:latest(Docker Hub);
若要进行可验证的生产部署,请在 deploy/compose/.env 中将 OLIVARES_IMAGE
设为一个 digest 固定的引用(参见 §8)。
数据持久化在 olivares-data 卷中。
3. 多租户 Postgres
Section titled “3. 多租户 Postgres”对于多租户拓扑,在基础文件之上叠加 Postgres override。
首先设置三个不同的密码。此 Compose 演示只允许使用 A-Z a-z 0-9 . _ ~ -,
然后启动栈:
cp deploy/compose/.env.example deploy/compose/.env # set three distinct passwords in deploy/compose/.env:# POSTGRES_SUPERUSER_PASSWORD, OLIVARES_DB_PASSWORD, OLIVARES_ADMIN_PASSWORDdocker compose -f deploy/compose/docker-compose.yml \ -f deploy/compose/docker-compose.postgres.yml up -d该 override 会拉起 postgres:16-alpine,在首次初始化时配置最小权限的
olivares_app 角色和 olivares 数据库(通过 initdb/10-app-role.sh 运行
规范的 deploy/postgres/01-app-role.sql),并用 --engine=postgres 将引擎
指向该非超级用户角色。这使得 FORCE-RLS 租户兜底真正生效:
引擎面对超级用户/BYPASSRLS 角色时拒绝启动。
覆盖文件还会创建 olivares_admin,这是一个独立的 NOSUPERUSER BYPASSRLS
角色,对引擎表只有只读访问权限。引擎通过 --admin-dsn 使用它进行跨租户读取,
包括首次设置。
4. 灾难恢复备份
Section titled “4. 灾难恢复备份”backup profile 生成定时的、账本连续性安全的 DR 包:存储快照加上签名密钥, 在你的 KEK 下加密,并附带一份各租户链尖(chain tip)的清单。
将口令保存在仓库和镜像之外的私密文件中,并在这台主机之外的安全位置保留一份副本:
没有口令,任何备份包都无法恢复。让备份容器以只读方式访问该文件
(镜像以 UID 65532 运行):
sudo install -d -o 65532 -g 65532 -m 0700 /srv/olivares-drsudo install -o 65532 -g 65532 -m 0400 /path/to/private-passphrase /srv/olivares-dr/dr-pass
BACKUP_TS="$(date -u +%Y%m%dT%H%M%SZ)" \docker compose -f deploy/compose/docker-compose.yml \ -f deploy/compose/docker-compose.backup.yml \ -f - --profile backup run --rm backup <<'YAML'services: backup: volumes: - /srv/olivares-dr/dr-pass:/run/secrets/dr-pass:roYAML该作业共享引擎的数据卷,将包写入 olivares-backups 卷,并且
把保留策略交给主机:用主机 cron 清理旧包
(find <backups> -name '*.drbundle' -mtime +14 -delete)。把该运行包进主机
cron 以实现定时 RPO,并将 olivares-backups 卷异地镜像——同主机的备份
不构成灾难恢复。用以下命令恢复并验证:
olivares dr restore --in <bundle> --data-dir <dir> --passphrase-file /path/to/private-passphrase完整的 RPO/RTO、密钥保管和 DR 演练流程随仓库的 DR runbook 一同提供; 更高层的演练在备份与恢复中。
5. 运维须知
Section titled “5. 运维须知”从主机而非容器探测健康状态。 该镜像
有意不在容器内设 HEALTHCHECK。引擎在 HTTPS 端口上暴露
/livez 和 /readyz;请从主机(或你的编排器)探测它们:
# liveness — process is up; no dependency checks, so a store outage never restart-loops:curl -fsS -k https://127.0.0.1:8443/livez
# readiness — store ping (and HA leadership): 200 when serving, 503 when the store is down:curl -fsS -k https://127.0.0.1:8443/readyz/readyz 的可达性就是可用性信号——把它接入你的外部监控
(参见 用 Prometheus 监控)。
setup token 只在日志中出现一次。 首次启动会在容器输出中打印一个一次性的
olst_… token。请在缓冲区轮转之前用
docker logs olivares | sed -n '/FIRST-BOOT SETUP/,/========================/p'(或 Compose 等效命令)
将其捕获;它在你创建第一位管理员时被消耗。
备份数据目录。 /var/lib/olivares(即 olivares-data 卷)保存着
SQLite 存储、审计签名密钥以及 TLS 材料。丢失它就会丢失账本的签名身份
并破坏审计连续性,所以请保护并备份该卷——使用 §4
中的 DR profile,而非对运行中存储的临时拷贝。
6. 反向代理 / TLS 终止
Section titled “6. 反向代理 / TLS 终止”开箱即用时引擎提供自己的自签名证书,这对评估足够,但不适用于会校验
信任的客户端。在生产环境中,用一个以运营者提供的证书(来自你的 CA 或 ACME)
先把引擎限制到 loopback(OLIVARES_BIND=127.0.0.1),再用终止 TLS 的反向代理承载它,并让该代理成为网络上唯一
被暴露的东西。
由于引擎本身讲 TLS,代理通过这个受限端口以 HTTPS 连接它。一个最小的 nginx server 块:
server { listen 443 ssl; server_name olivares.example.com;
ssl_certificate /etc/ssl/olivares/fullchain.pem; # operator-provided cert ssl_certificate_key /etc/ssl/olivares/privkey.pem;
location / { proxy_pass https://127.0.0.1:8443; # engine restricted to loopback, own TLS proxy_ssl_verify off; # engine cert is self-signed proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }}用 Caddy 的等效配置,它会自动配置一张公开证书:
olivares.example.com { reverse_proxy https://127.0.0.1:8443 { transport http { tls_insecure_skip_verify # the engine's cert is self-signed } }}将引擎的主机端口保持绑定在 127.0.0.1(上文的默认值),这样只有代理可达。
gRPC 摄取端口(8444)用于 collector;只有在你运行分布式拓扑时,才有意地、
用其自己的 TLS 路径暴露它。
数据卷在容器替换间保持持久,所以一次升级即为:备份、拉取新的固定 tag、 重新创建容器。
# 1. Back up first (see §4).# 2. Pull the new release and re-verify it (see §1):docker pull docker.io/olivaresai/olivares:<new-version>
# docker run:docker stop olivares && docker rm olivares# re-run the §2 command with the new tag — the olivares-data volume is reused.
# Compose: set OLIVARES_IMAGE to the new digest in .env, then:docker compose -f deploy/compose/docker-compose.yml up -d重新创建容器不会触及命名卷,因此存储、签名密钥和 TLS 材料会延续过来。 始终在升级前备份,并在重新创建之前重新验证新镜像。
8. 生产环境按 digest 固定
Section titled “8. 生产环境按 digest 固定”可变 tag(:0.4、:latest)用于评估。在生产环境中,请固定你所验证的
digest——digest 不可变,且正是你签字确认过的东西:
docker run ... docker.io/olivaresai/olivares@sha256:<digest> serve ...对于 Compose,在 deploy/compose/.env 中设置 digest 引用:
OLIVARES_IMAGE=docker.io/olivaresai/olivares@sha256:<digest>对于横向扩展和多节点,请使用 ./business-chart 中的 Helm chart,
并按 digest 固定已发布的镜像。该 chart 的 OCI 发布未经验证(publication-unverified:从未从本仓库发布过,registry 一侧无法观测)。
源 chart 命令参见自托管 control plane,
完全断网站点参见在 air-gapped 环境中安装。