---
title: 代码化配置
description: 将面板配置导出为 YAML 文件，预览更改并使用 nexcmp config 或“导入/导出”页面应用它们；密钥不会保存在文件中，且可通过 JSON Schema 进行校验。
url: https://nexcmp.com/zh-cn/docs/configure-with-ai/config-as-code/
applies_to: NexCMP 1.6.1
updated: 2026-11-02
---

# 代码化配置 {#configuration-as-code}

> **后台位置：** System › Settings › Import/Export（`/agent/config`）。在服务器上：命令 `nexcmp config export`、`plan` 和 `apply`，以及 `nexcmp admin <tool>`。

## 功能说明 {#what-it-does}

您的面板配置（品牌、常规设置、电子邮件、Telegram警报、模块、货币、支付网关、限制、区域、套餐、AI提供商以及法律页面）可以保存为一个YAML文件。您可以自行编辑该文件、让AI助手协助编辑、将其纳入版本控制，或将其应用到相同或另一个面板中。在任何更改生效之前，您总能看到差异对比列表。敏感信息绝不会写入该文件。

使用它可以将配置克隆到第二个安装实例、在上线前审查更改、在出错后恢复设置，或者让AI生成一个作为完整文档供您阅读的整体配置。

## 前提条件 {#requirements}

| 项目 | 要求 |
|---|---|
| NexCMP | 1.4.0或更高版本。 |
| 命令行 | 您是面板服务器上的`root`（请使用`sudo`）。该命令会自动向面板请求一个临时密钥（15分钟，所有权限范围）。若要改用权限更窄的密钥，请将`NEXCMP_KEY`设置为一个[admin API key](https://nexcmp.com/zh-cn/docs/configure-with-ai/admin-api-keys/)并通过sudo保留它，例如`sudo --preserve-env=NEXCMP_KEY nexcmp config plan -f nexcmp.yaml`。 |
| 管理页面 | 已登录管理员账号。在演示面板上此页面为只读。 |
| 机密 | 在应用时提供的值（见[Secrets](#secrets)）；绝不放在文件内部。 |

## 导出、编辑、预览、应用 {#export-edit-preview-apply}

1. 导出当前配置：

   ```bash
   sudo nexcmp config export -o nexcmp.yaml
   ```

   不加`-o`时，YAML将直接打印到屏幕上。
2. 编辑`nexcmp.yaml`（参见下方的[example](#example-file)）。请将`version: 1`放在顶部。
3. 预览将要产生的更改。这不会做任何修改：

   ```bash
   sudo nexcmp config plan -f nexcmp.yaml
   ```

   每行显示部分、项目、字段和`old → new`。标记为`$`的行属于计费部分（见[Billing sections](#billing-sections)）。如果面板已经与文件匹配，您将看到“No changes”。
4. 应用。不加`--yes`时，该命令为**预演运行（dry run）**，仅打印相同的列表：

   ```bash
   sudo nexcmp config apply -f nexcmp.yaml --yes
   ```

5. 读取结果：`applied`、`pending`（等待您的确认）、`skipped`和`errors`。

| 选项 | 说明 |
|---|---|
| `-f <file>` | YAML文件（`plan`和`apply`所必需）。 |
| `--yes` | 真正应用。没有它，`apply`将只是预演运行。 |
| `--confirm-billing` | 同时应用计费部分（`payments`、`currency`、`plans`）。没有它这些部分将被跳过。 |
| `--section <name>` | 仅应用此部分。若要应用多个部分可重复使用该选项。 |
| `-o <file>` | 带有`export`时：将YAML写入文件。 |

当所有内容应用成功或无更改时退出代码为0，返回错误时为1，用法或密钥错误时为2。

### 机密 {#secrets}

该文件保存的是引用而非密钥，例如 `password: secret://smtp_password`。在应用时，其值将来自名为 `NEXCMP_SECRET_` 的环境变量加上大写的引用名：

```bash
sudo -i
read -rs NEXCMP_SECRET_SMTP_PASSWORD && export NEXCMP_SECRET_SMTP_PASSWORD
read -rs NEXCMP_SECRET_STRIPE_SECRET_KEY && export NEXCMP_SECRET_STRIPE_SECRET_KEY
nexcmp config apply -f nexcmp.yaml --yes --confirm-billing
```

如果某个引用没有值，则面板中先前保存的密钥将被**保留**。从未保存且未提供的密钥将保持为空。

| Reference name | Where it goes |
|---|---|
| `smtp_password` | `email.smtp.password` |
| `telegram_bot_token` | `telegram.bot_token` |
| `stripe_secret_key`, `stripe_webhook_secret` | `payments.stripe` |
| `paypal_client_secret` | `payments.paypal.client_secret` |
| `binance_api_key`, `binance_api_secret` | `payments.crypto` |
| `sepay_api_token`, `sepay_webhook_secret` | `payments.bank` |
| `ai_provider_key` | `ai_provider.api_key` |

## Example file {#example-file}

```yaml
# NexCMP configuration. Preview: nexcmp config plan -f nexcmp.yaml
version: 1

branding:
  name: Example Cloud
  primary: "#1677ff"
  currency: usd
  seller_name: Example Cloud LLC

settings:
  brand_name: Example Cloud
  support_email: support@example.com
  default_lang: en
  invoice_prefix: EX
  company_name: Example Cloud LLC
  company_address: "1 Example Street, New York, NY"
  min_topup_cents: 500

email:
  smtp:
    host: smtp.example.com
    port: 587
    security: starttls
    username: mailer@example.com
    password: secret://smtp_password
    from_email: no-reply@example.com
    from_name: Example Cloud
    reply_to: support@example.com

telegram:
  enabled: true
  chat_id: "123456789"
  bot_token: secret://telegram_bot_token

modules:
  s3: true
  k8s: false

currency:
  site_currency: usd
  manual_rate_vnd: 0        # 0 = automatic

payments:
  stripe:
    mode: test
    publishable_key: pk_test_XXXX
    secret_key: secret://stripe_secret_key
    webhook_secret: secret://stripe_webhook_secret
  bank:
    bank_code: BANK
    account_number: "0000000000"
    account_name: EXAMPLE CLOUD LLC
    prefix: EX
    api_token: secret://sepay_api_token
  channels:
    pay_card_enabled: true

quotas:
  quota_enabled: true
  quota_max_vms_24h: 5
  quota_max_vms_30d: 30

zones:
  - slug: new-york
    name: New York
    country: US
    city: New York
    enabled: true
    is_default: true

plans:
  - slug: vps-1c-1g
    name: 1 vCPU, 1 GB RAM, 25 GB
    cpu: 1
    ram_mb: 1024
    disk_gb: 25
    hourly_usd: 0.0112
    cs_offering_id: OFFERING_ID
    enabled: true
    visible: true

ai_provider:
  enabled: true
  name: Example AI
  base_url: https://api.example.com/v1
  model: example-model
  fallback_models: [example-model-mini]
  reasoning_effort: low
  api_key: secret://ai_provider_key

legal:
  terms:
    en: |
      # Terms of service
      Your terms in simple markdown (no HTML).
  privacy:
    en: |
      # Privacy policy
      Your policy in simple markdown (no HTML).
```

文件可以包含各部分的任意子集。未包含的部分不会被修改。大于 1 MB 的文件、缺失的 `version: 1`、不同的版本号或未知的部分都会在运行前被拒绝。

## 部分 {#sections}

| 板块 | What it controls | 备注 |
|---|---|---|
| `branding` | 品牌名称（最多 60 个字符）、主色调、显示货币（`usd` 或 `vnd`）、卖家名称。 | 徽标不属于该文件；请使用 [branding page](https://nexcmp.com/zh-cn/docs/customers/branding/)。 |
| `settings` | 通用设置的固定列表：`brand_name`、`support_email`、`support_telegram_url`、`default_lang`、`require_email_verified`、`min_topup_cents`、`max_topup_cents`、`invoice_prefix`、`company_name`、`company_address`、`company_tax_id`、`auto_destroy_days`、`low_balance_cents`。 | 忽略其他密钥。 |
| `email.smtp` | SMTP 主机、端口、安全类型（`starttls`、`tls`、`none`）、用户名、密码、发件人姓名与地址、回复地址。 | [SMTP and e-mail templates](https://nexcmp.com/zh-cn/docs/administration/smtp-and-emails/)。更改主机、端口或安全设置需要重新输入密码。 |
| `telegram` | 报警通道开启或关闭、chat id、bot token。 | [Telegram notifications](https://nexcmp.com/zh-cn/docs/administration/telegram-notifications/)。 |
| `modules` | 可选模块开启或关闭（`key: true/false`）。 | 仅限面板允许切换的键。参见[Modules](https://nexcmp.com/zh-cn/docs/infrastructure/modules/)。 |
| `currency` | 显示货币和手动USD兑VND汇率（`0`时为自动，否则为15000至50000）。 | 计费部分。参见[Currency and exchange rates](https://nexcmp.com/zh-cn/docs/catalog/currency-and-exchange-rates/)。 |
| `payments` | `stripe`、`paypal`、`crypto`、`bank`凭据以及`channels`开关（`pay_card_enabled`、`pay_wallets_enabled`、`pay_alipay_enabled`、`pay_paypal_enabled`、`pay_usdt_enabled`、`pay_sepay_enabled`）。 | 计费部分。参见[Payment channels](https://nexcmp.com/zh-cn/docs/billing/payment-channels/)。 |
| `quotas` | `quota_*`限制。 | 参见[Quotas](https://nexcmp.com/zh-cn/docs/billing/quotas/)。 |
| `zones` | 按`slug`划分的区域（必填：`slug`、`name`、`country`；可选：`city`、`enabled`、`is_default`）。 | 将创建新区域。已存在的区域文件**不会更改**。参见[Zones](https://nexcmp.com/zh-cn/docs/infrastructure/zones/)。 |
| `plans` | 按`slug`划分的套餐（必填：`slug`、`name`、`cpu`、`ram_mb`、`disk_gb`、`hourly_usd`；可选：`cs_offering_id`、`backend_id`、`zone_id`、`enabled`、`visible`、`sort`、`description`）。 | 计费部分。将创建新套餐，现有套餐将通过slug更新。价格为每小时USD。参见[Plans](https://nexcmp.com/zh-cn/docs/catalog/plans/)。 |
| `ai_provider` | 供客户AI Chat和AI Agent使用的面板AI提供商。 | [AI provider](https://nexcmp.com/zh-cn/docs/ai/ai-providers/)。 |
| `legal` | 各语言的服务条款和隐私文本（`en`、`vi`）。 | [Legal pages](https://nexcmp.com/zh-cn/docs/customers/legal/)。 |

应用顺序与上述顺序相同：基础设施类项优先于套餐。

## 注意事项 {#rules-to-remember}

- **幂等。** 第二次应用相同文件不会产生任何更改。`plan`显示“No changes”。
- **不进行删除。** 文件绝不会移除区域、套餐或设置。从文件中移除条目不会改变面板现状。
- **常规安全规则仍然适用。** 从命令行执行的每项更改都会通过与API更改相同的检查：作用域和IP规则。需要确认的更改（例如全站开关）会显示在`pending`下并带有一个预览，而不会直接应用，除非您传入`--confirm-billing`来确认所有更改。
- **AI客户端无法解锁计费。** 当MCP客户端调用`config_apply`时，`confirm_billing`将被忽略；资金变动需要您亲自处理。
- **应用前请检查。** JSON Schema描述了每个字段。将其指向您的编辑器，或者提供给AI使其编写出有效的YAML：`https://cloud.example.com/v1/admin/agent/config/schema.json`（公开可读）。

### 计费部分 {#billing-sections}

`payments`、`currency`和`plans`会更改价格或资金路径。`nexcmp config apply --yes`会**跳过**它们，除非您添加`--confirm-billing`；它们随后将列在`skipped`（“billing section - pass confirm_billing”）下。该标志即是您的确认：有了它，文件中的每个计费更改（以及任何其他需要确认的更改）都将直接应用，无需二次提示。请先运行`plan`并阅读标记为`$`的每一行。

当AI（MCP客户端或AI Chat中的`config_apply`工具）应用同一个文件时，该标志将被忽略，资金变动转而等待您的批准。

## 使用Import/Export页面 {#use-the-import-export-page}

1. 打开**System › Settings › Import/Export**。
2. 在**Export**下点击**Get current configuration**，然后点击**Download .yaml**保存`nexcmp.yaml`。密钥将显示为占位符。
3. 在**Import**下选择文件、将其拖入框中或粘贴YAML。
4. 可选：打开**Secrets that come with it (not in the file)**，为每个引用添加名称和值，例如`smtp_password`。
5. 点击**Preview changes**。表格按部分对更改进行分组；与资金相关的部分带有“Money-related”标签。取消勾选您不需要的部分。
6. 如果列出了与资金相关的部分，请勾选**同时应用与资金相关的更改（价格、支付网关、余额）**。如果不勾选，则会跳过这些部分。
7. 点击**Apply selected**。结果会显示已应用、已跳过或失败的内容。返回为等待确认的更改会显示为一个确认卡片；请点击其上的**Confirm**。

右上角的**JSON Schema**按钮可打开架构。

![带有Export卡片以及保存了已导出YAML的Import卡片的导入/导出页面](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/config-as-code-01-import-export.webp)

![按部分分组的更改预览表格，带有计费标签和Apply selected按钮](https://nexcmp.com/zh-cn/docs/images/configure-with-ai/config-as-code-02-preview.webp)

## 从命令行运行任意工具 {#run-any-tool-from-the-command-line}

`nexcmp admin`运行与AI助手相同的工具（[the tool list](https://nexcmp.com/zh-cn/docs/configure-with-ai/mcp-admin/#tools)）并输出JSON：

```bash
sudo nexcmp admin tools                       # name, scope and title of every tool
sudo nexcmp admin system_health
sudo nexcmp admin customers_search q=customer@example.com
sudo nexcmp admin settings_update --json '{"values":{"support_email":"support@example.com"}}'
```

参数为`key=value`对（可解析时值会作为JSON读取，否则作为文本读取）或一个`--json '{...}'`对象。如果操作需要确认，命令将打印预览并以退出码3及“Nothing changed”停止。请阅读预览，然后使用`--yes`再次运行该命令以应用它。以root身份运行该命令将获得一个具有所有作用域的15分钟密钥，因此确认步骤就是你的安全保障；使用`NEXCMP_KEY`时则应用密钥自身的作用域。

## 验证 {#verify}

1. `sudo nexcmp config plan -f nexcmp.yaml`在运行`apply --yes`后会显示 "No changes"。
2. 在管理后台中，你修改过的页面将显示新值，并且**Logs › Admin actions**会列出这些更改。
3. 再次应用同一个文件不会产生任何更改。

## 限制与注意事项 {#limits-notes}

- 该文件涵盖上述设置，不包括客户、服务器、发票或基础设施源（CloudStack和Proxmox连接）。请使用[AI Chat](https://nexcmp.com/zh-cn/docs/configure-with-ai/ai-chat-in-admin/)或管理后台页面来连接这些内容。
- 可用区和套餐通过`slug`进行匹配。请勿在文件中重命名slug：否则它会被创建为一个新项目。
- 已被客户使用的套餐无法更改其大小；请改为创建一个新套餐。
- 请妥善保管已导出的文件，即使它们不包含机密信息：它们列出了你的价格、地址和账户名称。

## 故障排查 {#troubleshooting}

| 症状 | 原因 | 解决办法 |
|---|---|---|
| `missing version: 1` | 文件不以`version: 1`开头 | 添加它。 |
| `unsupported version 2` | 文件具有其他版本号 | 此面板仅读取版本1。 |
| `unknown section 'x' (known: ...)` | 拼写错误或不支持的顶层键 | 使用上面的部分。 |
| `YAML error: ...` | YAML无效（缩进、制表符） | 修复消息中指出的行。 |
| `config is larger than 1 MB` | 文件太大 | 请将其拆分并使用`--section`。 |
| `no API key: set NEXCMP_KEY=ak_... or run as root on the server` | 命令未找到密钥 | 使用`sudo`运行，或者导出`NEXCMP_KEY`并通过sudo保留它。 |
| `panel not reachable` | 面板服务未在默认端口上运行 | 检查`sudo nexcmp status`。 |
| `skipped`下的计费行 | 计费部分需要`--confirm-billing` | 添加标志并首先审查`$`行。 |
| `pending`下的项目 | 该更改需要确认 | 打开**API & AI agents**或导入/导出结果，并点击卡片上的**Confirm**。 |
| 机密未更新 | 未设置`NEXCMP_SECRET_<NAME>`值，因此保留了已保存的机密 | 导出变量并再次应用。 |
| `errors`下的条目，带有HTTP 403 `insufficient_scope` | 密钥缺少该部分的作用域 | 使用具有该作用域的密钥，或以root身份运行。 |
| `errors`下的条目，带有HTTP 403 `demo_read_only` | 演示面板 | 在真实安装中应用。 |


