# 主机与依赖要求

在安装 Raise 之前，你需要准备好一台 Linux 宿主机（或 Kubernetes 集群）、已配置解析的通配域名、开放必要的网络端口（80、443 以及运维管理网端口 8443），并根据选定的部署架构形态准备相应的依赖服务（如 PostgreSQL、Zitadel、对象存储、OpenBao、Temporal、Valkey 等）。本页汇总安装前的硬件规格基线、操作系统要求、网络端口规则与依赖矩阵。

## 谁能用

主机与依赖准备属于底层系统基础设施工作，主要面向部署方与平台运维人员（`platform.ops` 角色在系统安装部署完成后方可登录使用）：

- **权限要求**：执行主机预检与安装脚本必须具备 `root` 用户身份或具备 `sudo` 执行权限。
- **提权机制**：若以普通用户身份运行主机准备脚本，脚本会自动尝试通过 `sudo -E` 提升权限；若系统未安装 `sudo` 且当前并非 `root` 用户，脚本会终止执行并提示「run as root (or install sudo)」。
- **组织成员隔离**：各组织的普通成员与管理员不参与主机和依赖环境的准备工作。
- **校验失败保护**：当权限不足或硬件指标不满足要求时，安装脚本会直接报错并退出，不会拉起残缺不全的服务。

## 怎么打开

主机准备工作在服务器终端中进行，无独立的 Web 页面：

1. **单机环境预检入口**：在终端中运行主机准备脚本：
   ```bash
   sudo ./deploy/setup-host.sh --domain <你的基础域名>
   ```
   脚本在执行第 1 步时会自动根据指定的 pack 类型与扩展开关，检测主机的 CPU、内存容量、磁盘可用空间与端口状态。
2. **Kubernetes 集群入口**：通过 Helm Chart（`deploy/helm/kwork`）进行部署，要求 Kubernetes 集群版本 ≥ 1.30（工作负载使用了 `preStop.sleep` 平滑下线机制）。
3. **服务访问地址规划**：
   - 公网业务入口：`https://app.{base}` 等业务域名。
   - 运维管理入口：`https://ops.{base}:8443`（通过运维网专用端口访问）。

## 界面一览

主机准备环节无产品图形界面，所有检测指标均在终端标准输出中实时打印：

| 终端输出类型 | 输出示例 | 说明 |
|---|---|---|
| 预检通过项 | `✓ OS …`<br>`✓ arch …`<br>`✓ CPU n`<br>`✓ RAM nG`<br>`✓ disk nG free on …`<br>`✓ port 80/443/8443 free` | 检测指标满足安装要求；若端口显示 `held by kwork gateway (re-run)`，表示端口已被本系统的网关服务占用，判定为重新运行并通过 |
| 预检失败项 | `✗ CPU n < 需要值`<br>`✗ RAM nG < 需要值`<br>`✗ disk …`<br>`✗ port … in use` | 硬件资源未达到最低阈值，或关键端口已被宿主机上的其他进程占用，脚本会中止安装 |
| 未验证系统警告 | `! untested distribution '…': install curl git jq openssl and Docker yourself` | 当前 Linux 发行版未在自动化包管理适配列表中，需手动安装基础工具与 Docker |

## 常用操作

### 确认主机硬件规格（Compose 单机）

运行预检脚本时，系统会根据所选部署形态自动校验宿主机硬件资源（内存指标按 GiB 向下取整后进行数值比较）：

| 部署形态 | CPU 阈值 | 内存阈值 | 磁盘可用空间（`/var/lib/docker` 所在分区） |
|---|---|---|---|
| `--pack single`（默认基础形态，圈 0） | ≥ 4 核心 | ≥ 7 GB（生产建议 8 GB 起） | ≥ 40 GB |
| `--pack onprem` 或附加 `--with shell`（标准私有化） | ≥ 8 核心 | ≥ 15 GB（生产建议 16 GB 起） | ≥ 100 GB |
| 附加 `--with obs-llm`（大模型调用追踪） | 同上 | 在上述基础上再增加 8 GB 内存 | 同上 |

> **建议容量**
>
> 生产环境中，标准私有化部署建议配置 8 vCPU / 32 GB 内存、500 GB SSD 存储空间；若同时启用数据分析与完整可观测性组件，建议配置 16 vCPU / 64 GB 内存或拆分为 2–3 台主机承载；公测验证建议配置 8 vCPU / 16 GB 内存、50–100 GB SSD。

### 确认操作系统与处理器架构

1. **核对处理器架构**：平台仅支持 `x86_64` 或 `aarch64` 架构。在其他架构上执行时，脚本会终止并报错 `arch … unsupported (x86_64 / aarch64)`。
2. **确认已验证的 Linux 发行版**：
   - **apt 系**：Ubuntu（已测 22.04、24.04）、Debian（已测 12）。
   - **dnf / yum 系**：CentOS、RHEL、Rocky Linux、AlmaLinux、Oracle Linux（ol）、Fedora、Anolis（龙蜥）、openEuler（欧拉）、OpenCloudOS、Kylin（银河麒麟）。
3. **处理未验证发行版**：若终端输出警告「untested distribution」，脚本不会自动配置软件源，你必须自行安装 `curl`、`git`、`jq`、`openssl` 以及 Docker 运行环境。
4. **离线环境说明**：离线安装包在 Alpine + Docker 27 环境下完成验证，未在真实国产操作系统环境下完成离线验证。

### 准备 Docker 与运行时环境

1. **Docker Engine 版本**：要求 Docker Engine ≥ 24。在连网环境下，脚本会自动通过官方安装脚本 `https://get.docker.com` 安装；在中国大陆网络环境下指定 `--mirror cn` 时，会自动切换为 `--mirror Aliyun` 镜像源。
2. **Docker Compose 插件**：必须安装 Compose v2 插件，且版本 **≥ 2.24**（系统依赖可选环境变量文件 `env_file` 特性）。若版本过低，脚本会终止并报错 `Compose $CV < 2.24 …`。
3. **配置守护进程（`daemon.json`）**：
   - 日志轮转配置：日志驱动配置为 `json-file`，单文件大小上限 `max-size=50m`，最大保留文件数 `max-file=5`。
   - 守护进程保活：配置 `live-restore=true`，确保 Docker 守护进程升级或重启时容器保持运行。
   - 镜像加速源：根据网络连通性按需配置 `registry-mirrors`。
4. **已有 Docker 环境**：若主机已预装满足要求的 Docker 和 Compose，在执行命令时可附加 `--skip-docker` 或 `--offline`，脚本会跳过 Docker 安装步骤。
5. **配置时钟同步服务**：宿主机必须安装 chrony 或启用 NTP 服务。系统签发的认证令牌与 OIDC 断言均具备严格有效时限，时钟不同步会导致登录和接口调用失败。在离线部署且仅缺少 chrony 时，系统会输出警告，需手动配置指向内网 NTP 服务器。

### 开放网络端口与配置防火墙

宿主机对外发布的网络端口仅包含网关端口：

| 端口 | 协议 | 监听绑定 | 用途说明 |
|---|---|---|---|
| 80 | TCP | 全网卡（`0.0.0.0`） | HTTP 流量接入，用于 ACME HTTP-01 证书申请验证与 HTTP 重定向 |
| 443 | TCP | 全网卡（`0.0.0.0`） | HTTPS 业务主入口 |
| 443 | UDP | 全网卡（`0.0.0.0`） | HTTP/3 QUIC 传输通道 |
| 8443 | TCP | 由 `OPS_BIND` 决定（默认 `127.0.0.1`） | 运维管理后台与 `*.ops.{base}` 运维域名入口 |

配置防火墙与安全组时需注意：
1. **自动放行规则**：若检测到宿主机启用了 `ufw`，脚本会自动放行 22、80、443/tcp 与 443/udp；若启用了 `firewalld`，会自动放行 ssh、http、https 与 443/udp。
2. **Docker 端口绕过防火墙**：Docker 发布的容器端口直接写入底层 iptables，**不受宿主机 ufw 或 firewalld 规则的约束**。
3. **管理端口安全加固**：8443 端口的监听范围完全由 `--ops-bind` 参数或环境变量 `OPS_BIND` 控制。在云厂商安全组中**严禁向公网开放 8443 端口**。若配置 `--ops-bind 0.0.0.0`，系统会提示警告：运营入口暴露在所有网卡。
4. **端口占用校验**：预检时会自动检测 80、443 与 8443 端口是否空闲；若已被 `kwork-gateway` 占用，脚本会判定为重新运行并允许通过。

### 准备域名与 DNS 解析

1. **配置通配符解析**：在域名服务商处添加一条通配符 A 记录：`*.{base} A <主机公网 IP>`。
2. **核对核心二级域名**：解析生效后，下列二级域名必须能够正确解析到本机 IP：
   - `app.{base}`（[工作台](/guide/workspace) 入口）
   - `id.{base}`（身份认证中心）
   - `api.{base}`（API 网关）
   - `dev.{base}`（开发者平台）
   - `files.{base}`（文件与存储服务）
   - `ops.{base}`（运营管理后台）
3. **子域名继承机制**：
   - 各组织的独立应用域名 `organization.apps.{base}` 及租户应用域名 `*.apps.{base}` 均继承 `apps.` 通配规则。
   - 站点预览域名格式为 `*.*.sites.{base}`。
4. **证书签发准备**：
   - 公网环境：确保域名解析已指向本机且 80 与 443 端口公网可达，网关会自动完成 ACME HTTP-01 证书申请。
   - 局域网环境：安装时指定 `--tls internal` 选项，由网关自签发证书，访问时需在客户端操作系统导入网关生成的根证书。详细说明参见 [域名与证书](/deploy/domains)。

### 选择部署形态：Compose 单机还是 Kubernetes

根据业务规模与高可用要求选择部署架构：

#### 1. Compose 单机部署（`setup-host.sh` 与 `install.sh`）
单机模式默认拉起「圈 0」核心基础容器，并按安装包（pack）和组件开关（profile）拉起扩展服务：

| Profile / 组件组 | 包含服务 | 启用时机与触发条件 |
|---|---|---|
| 圈 0（核心基础） | gateway（Caddy 网关与门户）、oauth2-proxy、postgres、zitadel、kwork | 任何 pack 均必定启动（共 5 个基础容器） |
| `--profile infra` | seaweedfs、openbao、gotenberg | 使用 `--pack onprem` 时，脚本自动启用 `--infra` |
| `--profile core-infra` | 仅 openbao（不包含 SeaweedFS 与 Gotenberg） | 使用 `--pack tencent` 时自动启用 |
| `--profile shell` | kwork-agent、temporal、temporal-ui、bifrost | 指定 `--with shell` 时启动（提供助手能力） |
| `--profile llm` | bifrost | 执行 `install.sh --llm` 时启动；指定 `--shell` 时亦会自动配置模型网关地址 |
| `--profile coord` | redis（采用 Valkey 镜像） | 指定 `--with coord` 时启动，用于多副本限流支持 |
| `--profile backup` | pg-backup | 指定 `--with backup` 时启动，提供数据库自动备份 |
| `--profile obs` | otel-collector、prometheus、alertmanager、tempo、loki、grafana | 指定 `--with obs` 时启动，提供基础监控观测面板 |
| `--profile obs-llm` | langfuse、langfuse-worker、clickhouse、redis、seaweedfs | 指定 `--with obs-llm` 时启动，提供大模型调用追踪与分析 |
| `--profile analytics` | cube、superset、redis | 数据分析组件，需带 `--force` 参数且自备镜像（镜像未公开发布） |
| `--profile collab` | collab、redis | 文档协同组件，需带 `--force` 参数且自备镜像（镜像未公开发布） |
| `--profile apps` | app-runner（Docker socket 代理） | 仅在执行 `install.sh --apps` 时启动，用于宿主机托管应用运行 |
| `--profile byo-test` | minio-byo、llm-mock、oidc-mock、wecom-sim、pay-sim、wechatmp-sim、sms-sim | 外部依赖模拟器，仅用于测试与演示环境 |

#### 2. Kubernetes 集群部署（Helm Chart：`deploy/helm/kwork`）
Helm Chart 仅负责部署平台自身的工作负载（kwork 默认 2 副本、可选 Agent、gateway 与 oauth2-proxy），集群版本要求 ≥ 1.30。
- 默认资源请求：kwork 请求 200m CPU / 256Mi 内存（上限 1Gi 内存）；gateway 请求 100m CPU / 128Mi 内存（上限 512Mi 内存）。
- 高可用保护：配置 PodDisruptionBudget，保障 `minAvailable: 1`。
- **不在 Chart 内、需自备的外部依赖**：
  | 依赖服务 | 准备与配置要求 |
  |---|---|
  | PostgreSQL 17 | 自备托管高可用主备或 Patroni 集群；若经 PgBouncer 连接，**必须采用 session 模式**（不支持 transaction 模式） |
  | Zitadel v3 | 自备官方 Helm Chart（配置 `fullnameOverride: zitadel`）或配置 `externalServices.zitadel` |
  | 对象存储 | 自备 S3 兼容对象存储；多副本部署时必须配置 `storage.blob=s3`；本地文件模式 `fs` 仅允许 1 副本（emptyDir，仅限测试） |
  | Redis / Valkey | 当 `kwork.replicas > 1` 多副本运行时，必须在 Chart 配置中填写 `secrets.redisUrl` |
  | Temporal 与模型网关 | 启用 `agent.enabled` 时需自备 Temporal 集群；模型网关地址配置至 `llm.baseUrl` |
  | OpenBao | 当配置机密管理后端 `secretsBackend: openbao` 时自备实例 |
  | 托管应用容器 | Kubernetes 环境下不支持托管 ISV 应用运行时（底层仅提供单机 Docker 适配） |

### 确认外部依赖矩阵（按部署形态对照）

| 依赖组件 | 单机 `single` | 单机 `onprem` | 单机云厂商（`tencent` / `aliyun` / `aws`） | Helm（Kubernetes） |
|---|---|---|---|---|
| PostgreSQL 17 | Compose 自带（`postgres:17-alpine`；语义检索需 pgvector 镜像） | Compose 自带 | Compose 自带 | 客户自备 |
| Zitadel v3 | Compose 自带 | Compose 自带 | Compose 自带 | 客户自备 |
| 对象存储 | 本地文件卷（配置 `KWORK_BLOB=fs`） | Compose 自带 SeaweedFS | 云对象存储（COS / OSS / S3），并在 `.env` 中填写密钥 | 客户自备 S3 兼容存储 |
| OpenBao | 不需要（配置 `KWORK_SECRETS=local`） | Compose 自带，宿主机重启后需执行解封 | Compose 自带（`core-infra` 或 `infra`） | 可选自备 |
| Temporal | 仅在指定 `--with shell` 时启动 | 仅在指定 `--with shell` 时启动 | 推荐开启 | `agent.enabled` 时需自备 |
| Bifrost（模型网关） | 仅在指定 `--shell` 或 `--llm` 时启动 | 仅在指定 `--shell` 或 `--llm` 时启动 | 推荐开启 | 客户自备，配置 `llm.baseUrl` |
| Valkey / Redis | 指定 `--coord`、`analytics` 或 `obs-llm` 时启动 | 同左 | 多副本运行时需要 | 多副本运行时必须自备 |
| Gotenberg | 包含在 `--infra` 中启动 | 启动 | `tencent` 不启动 | 不在 Chart 内 |
| SMTP 邮件服务 | 生产建议配置；未配置时可在界面勾选「直接返回邮箱验证码」 | 同左 | 同左 | 在 Zitadel 中配置 |

第三方容器镜像的具体基准版本，以配置文件 `deploy/versions.env` 中的 BOM 镜像清单为准。详细配置步骤参见 [安装部署](/deploy/install) 与 [存储配置](/deploy/storage)。

### 检查网络出口与权限要求

1. **镜像拉取与证书出网**：宿主机必须能够访问公网容器镜像仓库与 Let's Encrypt 证书验证服务；完全隔离的局域网环境需采用离线安装包。
2. **中国大陆网络加速**：安装时可指定 `--mirror cn`（启用 goproxy.cn 加速），并配合 `--registry-mirror` 参数配置国内镜像加速源。
3. **模型价格同步放行**：模型网关 Bifrost 启动时会访问 `getbifrost.ai` 同步最新模型价格表；在受限网络中需在边界防火墙放行该域名，或接受价格表离线同步失败。
4. **域名 ICP 备案合规**：在中国大陆机房部署并使用自有域名面向公网开放时，域名必须依法取得工信部 ICP 备案。平台自身不校验备案状态，但未备案域名会被机房运营商在网络层拦截阻断。

## 状态说明

执行预检与准备操作时，检查项状态流转与判定规则如下：

```
硬件与环境检测 ───[ 全部满足 ]───> 终端显示 ✓ ───> 允许进入安装
      │
      ├───[ 资源不足 / 端口冲突 ]───> 终端显示 ✗ ───> 脚本终止退出（可通过 --force 跳过硬件拦截）
      │
      └───[ 非主流 Linux 发行版 ]───> 终端显示 ! ───> 输出警告，需自行安装 Docker 与依赖
```

| 检查状态 | 终端标志 | 业务含义与处理方式 |
|---|---|---|
| 检测通过 | `✓` | 操作系统、CPU 架构、CPU 核心数、内存容量、磁盘空间与端口完全满足要求，预检顺利通过。 |
| 网关占用判定通过 | `✓`（显示 `held by kwork gateway (re-run)`） | 端口已被平台原有的网关服务占用，判定为重新安装，允许继续。 |
| 发行版警告 | `!`（显示 `untested distribution`） | 未适配自动化包管理的 Linux 发行版，需自行安装 curl、git、jq、openssl 与 Docker。 |
| 资源不足或冲突 | `✗` | CPU 核心数、内存容量、磁盘空间低于阈值，或关键端口被其他非 Raise 进程占用，脚本立即中止。 |

## 让助手帮你做

底层宿主机规格确认、操作系统环境准备、防火墙端口开放与外部依赖部署均属于系统基础设施维护工作，平台助手（Agent）未接入主机准备环节，无法通过助手在终端中执行预检命令或配置服务器。

你可以在日常使用中向助手咨询主机规格基线与依赖部署的相关规则，例如：
> 安装 Raise 单机版需要准备多大规格的服务器？
> 启用工作台的助手功能需要部署哪些底层依赖？
> 为什么公网安全组不能放行 8443 端口？
> Kubernetes 部署形态下需要我们自备哪些外部服务？

## 设置

主机准备环节无产品图形界面设置项。各项硬件预检阈值（`NEED_CPU`、`NEED_MEM`、`NEED_DISK`）硬编码在预检脚本中。

若在非生产测试环境中主机硬件规格略低于标准预检阈值，可通过在命令中附加 `--force` 参数跳过预检失败检查继续安装。

## 注意事项

- **禁止在服务器使用 dev pack**：`dev` pack 仅用于本地开发环境，其内部使用的是临时密钥（ephemeral keys）。在服务器上执行预检时脚本会直接拦截并退出，提示 `the dev pack runs kwork in dev mode (ephemeral keys); use single or onprem on a server`。生产与公测服务器必须选择 `single`、`onprem` 或云厂商 pack。
- **单机模式无高可用**：Compose 单机部署不提供高可用保障。若生产业务要求高可用，请选择 Kubernetes（Helm）部署架构，其默认提供 2 副本并在 PodDisruptionBudget 中配置 `minAvailable: 1`。
- **数据库主备切换风险**：若在自备 PostgreSQL 环境中采用异步复制架构，发生数据库主备切换时存在丢失已提交写入事务的风险。
- **时钟同步一致性**：宿主机必须保证时钟严格同步。认证令牌与 OIDC 断言对时间漂移极度敏感，时钟不同步将直接导致登录认证失败。
- **8443 运维端口暴露风险**：Docker 发布的容器端口不受宿主机系统防火墙（ufw / firewalld）过滤。8443 端口完全通过 `OPS_BIND`（默认绑定为 `127.0.0.1`）与云安全组进行安全隔离。切勿在公网安全组中放行 8443 端口；若传入 `--ops-bind 0.0.0.0` 会收到暴露在所有网卡的警告。
- **PgBouncer 模式限制**：在 Kubernetes 部署中若通过 PgBouncer 连接自备 PostgreSQL，连接池模式必须设置为 session 模式，严禁使用 transaction 模式。
- **硬件与功能联动关系**：
  - 只有在部署时开启 `--shell` 开关（拉起 Temporal、Bifrost 与 kwork-agent）后，工作台中的「助手」功能方可正常使用（参见 [模型与 Agent](/deploy/llm)）。
  - 对象存储的形态决定了各组织在工作台「存储」应用中看到的是平台本地/SeaweedFS 桶还是云厂商 COS/OSS 存储桶（参见 [存储配置](/deploy/storage)）。
  - 观测组件 profile 决定了在平台运维端能否通过 [服务导航](/ops/runtime) 查看 Grafana、Loki 与 Langfuse 监控面板。
  - 软件许可约束：社区版（Community）默认支持 10 席位，不包含 Agent 运行时与 ISV 应用托管，未授权模块不会被启动。

## 目前不支持

- **数据分析与协同套件镜像公开发布**：`analytics` 与 `collab` 依赖的 `duckdb-worker` 与 `collab` 镜像尚未公开发布，目前需使用 `--force` 且自备镜像方可启动。
- **Kubernetes 托管 ISV 应用运行时**：Kubernetes 环境下暂不支持托管 ISV 容器应用运行（目前仅提供单机 Docker 适配能力）。
- **可用性承诺压测套件**：99.9% 可用性承诺所需的压测工具与外部拨测仓库目前尚未公开发布提供。

## 常见问题

### 执行预检脚本时提示 CPU 或内存不足（✗ CPU / ✗ RAM），应该如何处理？
预检脚本根据部署形态设定了硬性阈值：`--pack single` 要求 CPU ≥ 4 核心且内存 ≥ 7 GB；`--pack onprem` 或附加 `--with shell` 要求 CPU ≥ 8 核心且内存 ≥ 15 GB。如果主机硬件规格低于要求，预检会直接中止。若仅为内部功能验证且资源略有不足，可在命令后添加 `--force` 参数跳过硬件预检限制强行安装；但在生产环境中必须扩容服务器硬件规格，否则容器可能因内存不足被系统杀掉。

### 为什么云服务器公网安全组不能开放 8443 端口？
8443 端口是平台的运维管理后台入口（对应 `*.ops.{base}` 运维域名）。由于 Docker 发布端口时会直接在宿主机底层配置 iptables 转发规则，宿主机上的 ufw 或 firewalld 防火墙规则无法对其进行拦截。8443 端口的访问保护完全依赖参数 `--ops-bind`（默认仅绑定本地回环地址 `127.0.0.1`）以及云控制台安全组。为防止平台运维控制面直接暴露给公网攻击者，云安全组切勿放行 8443 端口。

### 在完全隔离的局域网或内网离线环境中部署，需要做哪些准备？
在离线环境下部署，首先需使用离线安装包或在命令中指定 `--skip-docker` / `--offline`（主机需提前安装 Docker 24+ 与 Compose 2.24+）；其次，域名证书需配置 `--tls internal` 并在访问客户端中导入网关自签发的根证书；此外，宿主机必须配置内网 NTP 服务器保持时钟严格同步；同时由于无法出网访问 `getbifrost.ai`，需在防火墙为该域名配置放行规则或接受模型价格表离线同步失败。

### 单机 Compose 部署与 Kubernetes（Helm）部署在外部依赖上有何区别？
Compose 单机部署自带完整的「圈 0」基础容器（包括 PostgreSQL 17、Zitadel v3、网关、OAuth2 代理与 kwork 核心服务），无需用户在部署前自建底层数据库或认证中心。而 Kubernetes（Helm）部署仅负责调度平台自身的工作负载（kwork、网关、OAuth2 代理与可选 Agent），不包含底层基础设施。用户必须自备高可用 PostgreSQL 17（若经 PgBouncer 连接必须为 session 模式）、Zitadel v3 认证中心、S3 兼容对象存储，以及多副本运行时所需的 Redis / Valkey 缓存服务。
