# 에디션과 서피스 프로필

> Community, Business, Cloud 에디션을 비교하고, 셀프 호스팅 Nodaro를 Business로 전환한 뒤 NODARO_SURFACE_PROFILE로 인터페이스 범위를 좁혀 보세요.

Source: https://nodaro.ai/ko/docs/self-hosting/editions-and-profiles

Nodaro에는 Community, Business, Cloud라는 세 가지 **에디션**이 있습니다. 모두 같은 코드로 빌드하며 `EDITION` 변수로 선택합니다. Business 에디션에서는 **서피스 프로필**이 다시 빌드하지 않고도 설치가 보여 주는 범위를 좁힙니다. 인터페이스 일부를 숨기고, 노드와 모델을 제거하고, 제품 이름을 바꾸고, 로그인을 제한할 수 있습니다. 이 페이지에서는 두 가지를 모두 다룹니다.

## 세 가지 에디션
| | Community | Business | Cloud |
| --- | --- | --- | --- |
| **셀프 호스팅 가능** | 예 | 예 | 아니요, Nodaro가 관리 |
| **관리자 패널** | 아니요 | 예 | 예 |
| **사용자 관리** | 아니요 | 예 | 예 |
| **크레딧 원장** | 아니요 | 아니요 | 예 |
| **결제** | 아니요 | 아니요 | 예 |
| **관리자가 정하는 크레딧 가격** | 아니요 | 아니요 | 예 |
| **서피스 프로필** | 무시됨 | 예 | 예 |

- **Community**(`EDITION=community`, 기본값)는 무료 셀프 호스팅 에디션입니다. 가입하는 사람은 모두 일반 사용자가 됩니다.
- **Business**(`EDITION=business`)는 관리자 패널과 사용자 관리를 추가합니다. 여전히 셀프 호스팅이며 결제 기능은 없습니다.
- **Cloud**(`EDITION=cloud`)는 크레딧과 결제를 추가합니다. app.nodaro.ai를 구동하며 셀프 호스팅용이 아닙니다.

Business 에디션의 관리자 패널과 사용자 관리는 Enterprise 기능입니다. 개발과 테스트 용도로는 실행할 수 있지만, 프로덕션에서 사용하려면 Nodaro Enterprise 구독이 필요합니다. [라이선스](https://nodaro.ai/docs/self-hosting/license)를 참고하세요.

## 셀프 호스팅 설치를 Business로 전환
API는 시작할 때 `EDITION`을 읽습니다. 브라우저의 편집기는 이미지를 빌드할 때 `VITE_EDITION`에서 에디션을 읽습니다. 공개된 이미지는 Community Edition으로 빌드되어 있으므로, Business 설치는 소스에서 빌드합니다.

Community에서 Business로 옮겨도 데이터베이스에는 부담이 없습니다. 스키마가 같기 때문입니다.

### Compose 파일에서 두 값 바꾸기
`docker-compose.community.yml`의 `nodaro` 서비스 아래에서 `community`라고 적힌 두 줄을 바꾸세요.

```yaml
nodaro:
build:
args:
VITE_EDITION: business      # was: community
environment:
EDITION: business             # was: community
```

두 줄 모두 Compose 파일에 고정되어 있으므로, `.env`에서 `EDITION`을 설정해도 효과가 없습니다.

### 빌드하고 시작하기
```bash
docker compose -f docker-compose.community.yml build --no-cache nodaro
docker compose -f docker-compose.community.yml up -d
```

### 첫 관리자 승격
[첫 사용자와 관리자](https://nodaro.ai/docs/self-hosting/first-admin)를 참고하세요.

소스에서 빌드한 설치는 `git pull`과 `build`로 업데이트하세요. `docker compose pull`을 실행하면 공개된 Community 이미지를 다시 내려받게 됩니다.

빌드는 비어 있거나 알 수 없는 `VITE_EDITION`을 거부합니다. 이 검사가 없으면 설정하지 않은 값으로도 빌드가 문제없이 끝나 `community`로 대체되고, Business 이미지가 관리자 패널 없이 배포됩니다. Compose 파일이 값을 대신 전달합니다. 직접 작성한 `docker build`에는 `--build-arg VITE_EDITION=community`, `business`, `cloud` 중 하나가 필요합니다.

### 빌드 시점에 고정되는 것과 고정되지 않는 것
세 가지 브라우저 설정은 빌드 시점에 고정되지 **않습니다**. API 주소, 브라우저의 로그인 주소, anon 키입니다. 컨테이너는 부팅할 때 `PUBLIC_URL`, `FRONTEND_SUPABASE_URL`, `SUPABASE_ANON_KEY`에서 이 값을 가져와 `/config.js`에 쓰고, 브라우저는 앱이 시작되기 전에 그 파일을 읽습니다. 그래서 공개된 이미지는 재시작하면 어떤 포트나 도메인에서도 제공됩니다. `VITE_*` 빌드 인수는 런타임 값이 설정되지 않았을 때의 대체값일 뿐입니다.

빌드 시점에 고정되는 다른 브라우저 설정:

| 빌드 인수 | 역할 | 기본값 |
| --- | --- | --- |
| `VITE_STUDIO_URL` | **스튜디오에서 열기** 링크가 여는 Studio 앱의 주소 | `https://studio.nodaro.ai` |
| `VITE_PERSON_URL` | 홈 화면의 **Person 열기** 카드가 여는 Person 앱의 주소 | `https://person.nodaro.ai` |

## 서피스 프로필
`NODARO_SURFACE_PROFILE`은 다시 빌드하지 않고 **Business** 또는 **Cloud** 설치의 인터페이스 범위를 좁힙니다. Community Edition은 이 변수를 무시하고 항상 전체 인터페이스를 보여 줍니다.

- **형식.** 인라인 JSON이나, 파일을 읽는 `@/path/to/profile.json`입니다. Compose 스택에서 파일을 쓰려면 컨테이너에 마운트하고 컨테이너 안의 경로를 지정하세요.
- **좁히기만 합니다.** 프로필은 숨기고 제거할 수 있습니다. 에디션이 끈 기능을 켜는 일은 절대 없습니다.
- **모든 필드는 선택 사항입니다.** 빈 목록은 “기본값 유지”를 뜻합니다. 설정하지 않으면 설치는 전체 인터페이스를 보여 줍니다.
- **오류.** 형식이 잘못된 필드는 로그에 경고를 남기고 그 필드의 기본값으로 대체됩니다. 프로필을 전혀 불러올 수 없으면 Business 또는 Cloud 설치가 `[surface-profile] FATAL … Refusing to boot a narrowing deployment mainline-open`과 함께 부팅을 멈춥니다. 파일을 읽을 수 없거나, JSON이 잘못되었거나, 값 전체가 검증에 실패하면 이렇게 됩니다. 범위를 좁히는 설치가 모든 것을 보여 주는 상태로 실행되어서는 안 되기 때문입니다.
- **적용.** 앱을 재시작하세요. 프로필은 `/config.js`를 통해 브라우저에 전달됩니다.

### 예시
```bash
NODARO_SURFACE_PROFILE={"nav":{"hide":["gallery"]},"brand":{"productName":"Studio"},"outputs":{"allowPublic":false},"voice":{"allowedGenders":["male"]}}
```

이 설정은 갤러리를 숨기고, 제품 이름을 Studio로 바꾸고, 모든 출력물을 비공개로 유지하고, 남성 보이스만 제공합니다.

### 필드
| 필드 | 역할 |
| --- | --- |
| `nav.hide` | 사이드바 항목을 숨깁니다. 값: `gallery`, `explore`, `pricing`, `templates`, `apps`, `community`, `integrations`. |
| `dashboard.tabs` | 홈 화면 섹션의 순서가 있는 허용 목록 하나입니다. [홈 화면 섹션](#home-screen-sections)을 참고하세요. |
| `nodes.deny`, `models.deny` | 모든 곳에서 제거할 노드 유형과 모델 ID입니다. **노드 추가** 메뉴, `GET /v1/nodes`, `GET /v1/models`, MCP 도구, 실행 시점이 모두 해당합니다. 제거된 노드는 `node_not_available`로 실패합니다. |
| `nodes.allow`, `models.allow` | 허용 목록입니다. 목록이 비어 있지 않으면 나열된 노드 유형이나 모델 ID만 제공되며, `deny`는 여전히 그중에서 뺍니다. [허용 목록](#allow-lists)을 참고하세요. |
| `auth.methods`, `auth.ssoLabel` | 제공할 로그인 방법입니다: `email`, `google`, `sso`. `auth.ssoLabel`이 설정되지 않으면 `sso`는 빠집니다. [로그인 방법](#sign-in-methods)을 참고하세요. |
| `siblings.apps` | 제품 전환기의 Nodaro 링크를 바꿉니다: `[{ "label": "...", "url": "..." }]`. |
| `brand.productName` | 워드마크와 페이지 제목을 바꿉니다. 없으면 페이지 제목은 기본 상태 그대로입니다. |
| `brand.wordmark` | 자체 로고 파일을 제공하는 설치에서, 사이드바 헤더의 내 로고 옆에 표시되는 짧은 텍스트입니다. 예: 제품 이름 `Acme Studio`에 워드마크 `Studio`. |
| `brand.description` | 페이지의 메타 설명을 바꿉니다. |
| `brand.platformLinks` | `false`로 설정하면 플랫폼 자체의 법률, 문서, 릴리스 노트, 제품 홍보 링크를 숨깁니다. `siblings.apps`에 설정한 링크는 남습니다. |
| `locale.default` | 새 방문자가 시작하는 언어입니다. |
| `locale.picker` | `false`로 설정하면 언어 선택기를 숨깁니다. 기본값은 `true`입니다. |
| `outputs.allowPublic` | `false`로 설정하면 사용자의 선택과 관계없이 모든 출력물이 비공개가 됩니다. |
| `voice.allowedGenders` | 보이스를 `male`, `female`, `neutral`의 임의 부분 집합으로 제한합니다. 비어 있으면 모든 성별입니다. [보이스 성별](#voice-genders)을 참고하세요. |
| `features.hide` | 기능 전체를 끕니다. `copilot`은 Workflow Copilot을 제거하고, `presentation`은 캔버스의 **프레젠테이션** 탭을 숨깁니다. |
| `catalogs` | 검토된 피커 콘텐츠가 필요한 설치용 `{ "required": true, "factoryPresets": false }`입니다. [피커 카탈로그](#picker-catalogs)를 참고하세요. |

로고와 파비콘은 프로필에 포함되지 않습니다. Docker 이미지에 정적 파일 레이어를 추가해 교체하세요.

### 홈 화면 섹션
`dashboard.tabs`는 순서가 있는 허용 목록 하나입니다. 전체 키는 `workflows`, `projects`, `apps`, `miniapps`, `templates`, `tutorials`, `statistics`, `gallery`, `studio`, `mcp`입니다.

- **`workflows`, `projects`, `studio`**: **이어서 하기** 탭의 워크스페이스 필터에 나오는 목록으로, 내 목록의 순서를 따릅니다. 내 목록에 셋 중 아무것도 없으면 셋 모두 표시되므로, 기본 목록이 비는 일은 없습니다.
- **`apps`**: **이어서 하기**의 Nodaro 앱 띠입니다.
- **`templates`**: **탐색**의 “템플릿으로 시작하기” 행과 사이드바의 템플릿 항목입니다.
- **`tutorials`**: **탐색**의 **실력 키우기** 튜토리얼과 사이드바의 튜토리얼 항목입니다. `templates`와 `tutorials`가 모두 없으면 탐색 탭이 표시되지 않습니다.
- **`miniapps`**: 사이드바의 미니앱 항목입니다.
- **`statistics`**: 실행 기록 페이지의 통계 개요입니다.
- **`mcp`**: 네 번째 “이어서 작업하기” 목록으로, MCP 클라이언트가 자동으로 만든 `mcp` 프로젝트에 생성한 워크플로입니다.

유지할 섹션을 모두 나열하세요. 예를 들어 `["workflows","projects","statistics","tutorials"]`는 워크플로 및 프로젝트 목록, 튜토리얼, 통계를 유지합니다. 스튜디오 목록, 앱 띠, 템플릿 행, 사이드바의 템플릿 및 미니앱 항목은 빠집니다. 그 위에 `nav.hide`도 그대로 적용됩니다.

### 허용 목록
엄선한 설치에는 허용 목록이 더 안전한 형태입니다. 새 노드나 모델이 거부 목록에 없다는 이유로 나타나는 대신, 내가 나열할 때까지 사용할 수 없는 상태로 남기 때문입니다.

- `sticky-note`와 `preview` 같은 유틸리티 노드는 허용 목록에 빠졌다고 제거되지 않습니다. 명시적인 `deny`만 이 노드를 제거합니다.
- 관리자는 관리자 패널에서 런타임에 노드와 모델의 사용 가능 여부를 바꿀 수 있습니다. 저장된 런타임 설정은 초기 상태로 재설정할 때까지 프로필의 목록을 대신합니다.
- 관리자가 관리자 패널에서 끈 노드는 관리자에게는 계속 사용 가능합니다. 프로필로 제거한 노드는 관리자에게도 제거됩니다. 하지만 관리자가 프로필로 제거된 노드를 관리자 패널에서 다시 켜면 모든 사람에게 풀리므로, 그만큼 믿을 수 있는 사람에게만 관리자 역할을 주세요.
- 끈 모델은 관리자에게도 꺼집니다.
- 실행은 그 실행을 수행하는 사용자 기준으로 검사합니다. 앱이나 프레젠테이션 실행은 실행하는 사람으로 수행됩니다. 예약 실행이나 Webhook으로 트리거된 실행은 워크플로 소유자로 수행되며, API 토큰이나 연결된 앱은 각자의 소유자로 동작합니다. 그 소유자가 관리자라면 실행에서 사용자에게 숨겨진 노드를 쓸 수 있으므로, 그런 워크플로의 Webhook URL은 신중하게 다루세요.
- 숨겨진 노드가 들어 있는 앱, 컴포넌트, 템플릿은 게시할 수 없습니다. 요청이 `node_not_available`로 실패합니다.
- 역할 변경은 약 5분 안에 이 검사에 반영됩니다.

### 로그인 방법
`auth.methods`는 로그인 페이지의 로그인 방법을 `email`, `google`, `sso` 중에서 좁힙니다. `sso`는 SSO 버튼의 텍스트인 `auth.ssoLabel`과 함께 있을 때만 목록에 두세요.

`sso`**만** 나열한 목록은 서버 쪽 규칙도 켭니다. 로그인한 모든 계정은 싱글 사인온으로 만들었거나 연결된 계정이어야 합니다. 그 밖의 세션은 첫 API 호출에서 `403 sso_required`로 거부되므로, 로그인 서비스에 직접 등록한 계정은 설치를 쓸 수 없습니다. 목록에 `email`을 추가하면 이 규칙이 꺼집니다. [싱글 사인온](https://nodaro.ai/docs/self-hosting/sso)을 참고하세요.

### 보이스 성별
`voice.allowedGenders`는 서버에서 적용됩니다.

- 보이스 목록과 공유 보이스 라이브러리에는 허용된 성별의 보이스만 표시됩니다.
- 다른 성별의 기본 제공 보이스를 쓰는 요청은 `voice_not_available`로 거부됩니다.
- 모든 기본 보이스와 대체 보이스는 허용된 성별의 첫 번째 보이스가 됩니다.
- 편집기는 Suno 노드에서 다른 성별의 보컬 성별 태그를 숨깁니다.

보이스를 만드는 노드의 출력 성별은 미리 알 수 없습니다. 이 노드를 제거하려면 `"nodes":{"deny":["voice-design","voice-remix"]}`를 추가하세요.

### 피커 카탈로그
검토된 피커 콘텐츠만 제공해야 하는 설치라면 `"catalogs":{"required":true,"factoryPresets":false}`로 설정하세요.

- `required: true`이면 편집기는 서버에서 엄선된 전체 카탈로그를 받은 뒤에만 피커 선택지를 제공하며, 그 요청이 실패하면 아무것도 제공하지 않습니다. 새 노드와 초기화는 제공된 값만 사용합니다.
- `factoryPresets: false`이면 번들된 프리셋이 편집기와 API에서 숨겨집니다. 사용자가 직접 만든 프리셋은 남습니다.
- 서버는 가져오거나 이전에 저장한 워크플로에서도 제외된 카탈로그 선택지를 거부합니다.

## 자주 묻는 질문

### 셀프 호스팅 Nodaro를 Community에서 Business로 어떻게 전환하나요?

docker-compose.community.yml의 nodaro 서비스에서 EDITION과 VITE_EDITION 빌드 인수를 business로 설정한 뒤, 소스에서 이미지를 빌드하고 시작하세요. 데이터베이스는 바꿀 필요가 없습니다.

### 에디션을 바꾸려면 왜 이미지를 다시 빌드해야 하나요?

편집기는 이미지를 빌드할 때 에디션을 읽으며, 공개된 이미지는 Community Edition으로 빌드되어 있습니다. API는 시작할 때 EDITION을 읽지만, 브라우저 앱은 Business 빌드에서만 관리자 패널을 보여 줍니다.

### 서피스 프로필이란 무엇인가요?

다시 빌드하지 않고 Business 또는 Cloud 설치가 보여 주는 범위를 좁히는 JSON 설정 NODARO_SURFACE_PROFILE입니다. 사이드바 항목과 홈 화면 섹션을 숨기고, 노드와 모델을 제거하고, 제품 이름을 바꾸고, 로그인 방법을 제한하고, 출력물을 강제로 비공개로 만들 수 있습니다.

### Community Edition도 NODARO_SURFACE_PROFILE을 읽나요?

아니요. Community Edition은 이 변수를 무시하고 항상 전체 인터페이스를 보여 줍니다. 서피스 프로필을 쓰려면 EDITION=business로 설정하세요.

### 서피스 프로필로 에디션에 없는 기능을 켤 수 있나요?

아니요. 프로필은 범위를 좁히기만 할 수 있습니다. 에디션이 끈 기능을 켜는 일은 절대 없습니다.
