> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arupa.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# 服务配置

> 配置服务的启动方式、执行方式、访问权限和参数。

`[Services]` 部分控制内核如何发现并运行每个服务。服务由其包元数据中声明的名称标识，内核加载该服务时会使用与该名称对应的配置。

```toml theme={null}
[Services]
  [Services.default]
    Restart = "no"
    RunAsUser = ""

  [Services.hello]
    Restart = "no"
    RunAsUser = ""
    Checksum = "sha256:<digest>"
    Allow = ["staff"]

    [Services.hello.Params]
      greeting = "env://HIHI?"
```

## 默认配置

`[Services.default]` 为被发现的服务提供一份基础配置。`[Services.<name>]` 表会合并到该基础配置之上，生成某个服务最终生效的配置。

合并规则如下：

* 非空的 `Restart` 值会替换默认值；
* 非空的 `RunAsUser` 值会替换默认值；
* 非空的 `Checksum` 值会替换默认值；
* 非空的 `Allow` 列表会替换默认的组列表；以及
* `Params` 按键合并，某个服务自己的值优先。

对于这些字段，服务自身配置中被省略或为空的值不会清除继承的默认值。特别地，在当前实现中，设置 `Allow = []` 并不会移除非空的默认 `Allow` 列表。

只有名称匹配的服务才会收到对应的具名配置。如果某个名称出现在 `[Services]` 中，但在 `ServiceDir` 中找不到匹配的包，内核会在扫描时将该配置项报告为缺失。

## `Restart`

尽管名为 `Restart`，它目前实际控制的是服务是否在内核启动时自动启动，而不是一般意义上的崩溃后自动重启循环。

以下值（忽略大小写和首尾空白）会启用自动启动：

```text theme={null}
always, yes, true, on, enable, enabled, 1
```

其他值，包括 `no`、`false` 和 `off`，都会禁用自动启动。被禁用的服务仍然可以被服务管理器发现，并通过显式的管理操作启动。

在配置中更改 `Restart` 本身并不会启动或停止一个已经在运行的服务。它仅在内核决定启动序列中要启动哪些已发现的服务时才会被使用。

## `RunAsUser`

`RunAsUser` 用于选择运行 `grpc` 服务进程所使用的操作系统用户。空值表示该服务以当前 Arupa 进程用户身份运行。

```toml theme={null}
[Services.ssh]
  RunAsUser = "arupa-service"
```

该设置只对 `grpc` 服务有效，因为只有它们是以独立操作系统进程运行的服务。它对运行在内核进程内部的 `wasm` 服务没有影响，对完全没有进程或模块可启动的 `static` 服务同样没有影响。内核必须具备以所选用户身份启动进程所需的操作系统权限。如果将该值留空，内核不会切换用户。

## `Checksum`

`Checksum` 用于在内核解压或加载服务包之前验证其完整性。将其设置为完整 `.plg` 归档文件的 SHA-256 摘要，并带上 `sha256:` 前缀：

```toml theme={null}
[Services.hello]
  Checksum = "sha256:<digest>"
```

该值必须使用 `sha256:<64 位十六进制数字>` 的形式。算法名称和十六进制摘要都不区分大小写。空值或省略该字段会禁用校验。将 `<digest>` 替换为您的包对应的 64 位摘要。

请基于 `.plg` 文件本身计算摘要，而不是基于其解压后的内容。例如，`sha256sum hello.plg` 的输出就是应放在 `sha256:` 之后的摘要值。

如果非空的校验和不符合要求的格式，内核会拒绝该配置。

当摘要不匹配时，内核会拒绝加载或启动该服务。大多数情况下应为每个服务单独设置校验和。虽然 `Checksum` 也可以设置在 `[Services.default]` 中，但该值会被每个没有自己非空校验和的服务继承。校验和验证适用于所有运行时类型，包括 `static`，因为它保护的是包归档文件本身。

## `Allow`

`Allow` 是服务级别的访问限制，其中包含来自 [`Groups`](./config-users) 配置的组名：

```toml theme={null}
[Services.hello]
  Allow = ["staff"]
```

空列表会使服务在此层保持开放。非空列表只允许属于列表中至少一个组的用户访问。该策略适用于该服务拥有的每一条路由，无论其背后是哪种传输——HTTP 路由和通过静态传输提供的静态内容都包含在内。

服务级访问会与主机路由规则以及路由级策略结合评估，每一层适用的策略都必须允许该请求。完整的权限模型请参阅[访问控制](./config-access)。

## `Params`

`Params` 包含在服务注册时传递给它的任意字符串设置：

```toml theme={null}
[Services.hello.Params]
  greeting = "hello"
  endpoint = "https://example.com"
```

来自 `[Services.default.Params]` 的参数构成基础值。`[Services.<name>.Params]` 中的键会覆盖匹配的默认键，而不相关的默认键仍然可供该服务使用。

### 环境变量引用

参数值可以引用环境变量，而不是直接把值存储在 `config.toml` 中：

```toml theme={null}
[Services.hello.Params]
  required_secret = "env://ARUPA_SECRET"
  optional_label = "env://ARUPA_LABEL?"
```

内核会在服务注册时解析这些引用：

* `env://NAME` 要求该环境变量必须存在。如果缺失，服务加载会失败。
* `env://NAME?` 是可选的。如果该变量缺失，服务会收到一个空字符串。
* 不带 `env://` 前缀的值会原样传递。

`?` 必须是引用的最后一个字符，且环境变量名称前后不能有空白字符。

## 配置变更

内核可以在不重建 HTTP 服务器的情况下重新加载服务配置。重新加载会更新服务管理器持有的有效配置，并刷新已加载服务的 `Allow` 组。对 `Params`、`RunAsUser`、`Checksum` 或启动行为的更改，会在服务下次被加载或启动时生效；它们不会重写一个已经在运行的服务进程。
