---
title: 코드 기반 설정
description: 패널 설정을 YAML 파일로 내보내고, 변경 사항을 미리 본 후 nexcmp config 또는 가져오기/내보내기 페이지를 통해 적용하세요. 보안 비밀은 파일에 포함되지 않으며 JSON Schema가 이를 검증합니다.
url: https://nexcmp.com/ko/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}

패널 설정(브랜딩, 일반 설정, 이메일, 텔레그램 알림, 모듈, 통화, 결제 게이트웨이, 제한, 존, 플랜, AI 공급업체 및 법적 페이지)을 하나의 YAML 파일로 저장할 수 있습니다. 파일을 직접 편집하거나, AI 어시스턴트에 편집을 요청하고, 버전 관리 시스템에서 유지하며, 동일한 패널이나 다른 패널에 적용할 수 있습니다. 변경 사항이 적용되기 전에 항상 변경 내용 목록을 확인할 수 있습니다. 보안 비밀은 파일에 기록되지 않습니다.

이 기능을 사용해 두 번째 설치에 설정을 복제하거나, 라이브 반영 전에 변경 사항을 검토하거나, 실수 후 설정을 복원하거나, AI가 전체 구성을 하나의 문서로 읽을 수 있는 제안을 작성하도록 할 수 있습니다.

## 요구 사항 {#requirements}

| 항목 | 요구 사항 |
|---|---|
| NexCMP | 1.4.0 이상. |
| 명령줄 | 패널 서버에 `root` 상태입니다(`sudo` 사용). 명령은 자체적으로 패널에 임시 키(15분, 모든 스코프)를 요청합니다. 대신 더 제한적인 키를 사용하려면 `NEXCMP_KEY`을(를) [admin API key](https://nexcmp.com/ko/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`은(는) dry run으로 실행됩니다. |
| `--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
```

참조에 값이 없으면 패널에 이미 저장된 보안 비밀이 **유지**됩니다. 저장된 적이 없고 제공되지도 않은 보안 비밀은 빈 상태로 유지됩니다.

| 참조 이름 | 저장 위치 |
|---|---|
| `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}

```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}

| 섹션 | 제어 항목 | 참고 |
|---|---|---|
| `branding` | 브랜드 이름(최대 60자), 기본 색상, 표시 통화(`usd` 또는 `vnd`), 판매자 이름. | 로고는 파일에 포함되지 않으며 [branding page](https://nexcmp.com/ko/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/ko/docs/administration/smtp-and-emails/). 호스트, 포트 또는 보안을 변경하려면 비밀번호를 다시 입력해야 합니다. |
| `telegram` | 알림 채널 켜기/끄기, 채팅 ID, 봇 토큰. | [Telegram notifications](https://nexcmp.com/ko/docs/administration/telegram-notifications/). |
| `modules` | 선택적 모듈 켜기/끄기(`key: true/false`). | 패널에서 전환할 수 있는 키만 해당합니다. [Modules](https://nexcmp.com/ko/docs/infrastructure/modules/)를 참조하세요. |
| `currency` | 표시 통화 및 수동 USD 대 VND 환율(`0` 자동, 그 외의 경우 15000~50000). | 결제 섹션. [Currency and exchange rates](https://nexcmp.com/ko/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/ko/docs/billing/payment-channels/)를 참조하세요. |
| `quotas` | `quota_*` 제한. | [Quotas](https://nexcmp.com/ko/docs/billing/quotas/)를 참조하세요. |
| `zones` | `slug`별 영역(필수: `slug`, `name`, `country`; 선택: `city`, `enabled`, `is_default`). | 새 영역이 생성됩니다. 이미 존재하는 영역은 파일에 의해 **변경되지 않습니다**. [Zones](https://nexcmp.com/ko/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`). | 결제 섹션. 새 플랜이 생성되고, 기존 플랜은 슬러그별로 업데이트됩니다. 가격은 시간당 USD 기준입니다. [Plans](https://nexcmp.com/ko/docs/catalog/plans/)를 참조하세요. |
| `ai_provider` | 고객 AI Chat 및 AI Agent에서 사용하는 패널 AI 공급자. | [AI provider](https://nexcmp.com/ko/docs/ai/ai-providers/). |
| `legal` | 언어별 이용약관 및 개인정보 처리방침 텍스트(`en`, `vi`). | [Legal pages](https://nexcmp.com/ko/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. 금액 관련 항목이 나열된 경우 **Also apply money-related changes (prices, payment gateways, balances)**에 체크하세요. 체크하지 않으면 건너뜁니다.
7. **Apply selected**를 클릭합니다. 결과에는 적용, 건너뜀 또는 실패한 항목이 표시됩니다. 확인 대기 중으로 반환된 변경 사항은 확인 카드 형식으로 나타나며, 해당 카드의 **Confirm**을 누르세요.

우측 상단의 **JSON Schema** 버튼을 누르면 스키마가 열립니다.

![Export 카드와 내보낸 YAML이 포함된 Import 카드가 있는 Import/Export page](https://nexcmp.com/ko/docs/images/configure-with-ai/config-as-code-01-import-export.webp)

![빌링 태그와 Apply selected 버튼이 섹션별로 그룹화된 변경 사항 미리보기 표](https://nexcmp.com/ko/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/ko/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"}}'
```

인수(Argument)는 `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/ko/docs/configure-with-ai/ai-chat-in-admin/) 또는 관리자 페이지를 통해 연결하세요.
- 존(Zone)과 플랜은 `slug`을(를) 기준으로 매칭됩니다. 파일 내의 슬러그(slug)를 이름 변경하지 마세요. 새 항목으로 생성됩니다.
- 이미 고객이 사용 중인 플랜은 크기를 변경할 수 없습니다. 대신 새 플랜을 생성하세요.
- 비밀 정보가 포함되어 있지 않더라도, 가격, 주소, 계정 이름이 나열되므로 내보낸 파일은 비공개로 유지하세요.

## Troubleshooting {#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** 또는 Import/Export 결과를 열고 카드의 **Confirm**을 누르세요. |
| 비밀(secret)이 업데이트되지 않았습니다. | `NEXCMP_SECRET_<NAME>` 값이 설정되지 않아 저장된 비밀이 유지되었습니다. | 변수를 내보낸 후 다시 적용하세요. |
| HTTP 403 오류와 함께 `errors` 아래에 항목 표시 `insufficient_scope` | 키에 해당 섹션의 스코프가 없습니다. | 스코프가 있는 키를 사용하거나 root로 실행하세요. |
| HTTP 403 오류와 함께 `errors` 아래에 항목 표시 `demo_read_only` | 데모 패널 | 실제 설치 환경에 적용합니다. |


