# 문제 해결

> /setup부터 시작해 셀프 호스팅 Nodaro의 흔한 문제를 해결하세요. 시작 오류, 포트, CORS, 마이그레이션, 스토리지, 큐, 키 문제의 증상과 해결 방법을 정리했습니다.

Source: https://nodaro.ai/ko/docs/self-hosting/troubleshooting

이 페이지에는 셀프 호스팅 Nodaro에서 가장 흔한 문제가 각각의 **증상**과 **해결 방법**과 함께 정리되어 있습니다. 대부분의 문제를 한눈에 보여 주는 `/setup` 페이지부터 시작하세요.

## /setup에서 시작
셀프 호스팅 설치는 `http://<your-host>/setup`에서 실시간 상태 화면을 제공합니다. 로그인이 필요 없으며, 각 구성 요소가 있고 작동하는지만 보여 주고 시크릿은 절대 보여 주지 않습니다.

- 데이터베이스, Redis, 스토리지, 암호화 키, 공급자 키의 **카드**가 초록색이나 빨간색으로 표시됩니다. 데이터베이스 카드에는 **마이그레이션 누락** 상태가 따로 있습니다.
- 실패한 카드마다 확인할 변수를 알려 주는 **힌트**가 있습니다.
- **실시간 업데이트**: 페이지가 5초마다 다시 확인합니다.

페이지에 **API에 연결할 수 없음**이 표시되면 웹 서버는 실행 중이지만 API가 응답하지 않는 것입니다. `docker compose -f docker-compose.community.yml logs -f`로 컨테이너 로그를 읽고, 포트 `3000`을 막는 것이 없는지 확인하세요.

## 설치가 시작되지 않음
**시작할 때 `Missing or invalid env vars`가 나타납니다.**
메시지에 검증에 실패한 변수가 나열됩니다. 흔한 원인은 비어 있는 `SUPABASE_SERVICE_ROLE_KEY`와 32자보다 짧은 `INTERNAL_ORCHESTRATOR_SECRET`입니다.

**`docker compose up`에서 `port is already allocated`가 나타납니다.**
스택이 공개하는 호스트 포트는 두 개뿐입니다. 앱용 `3000`과 루프백에만 바인딩되는 MinIO 콘솔용 `9001`입니다. Redis와 데이터베이스는 호스트 포트를 쓰지 않습니다. `docker-compose.community.yml`에서 충돌하는 매핑의 호스트 쪽 포트를 바꾸세요. 예: `"3001:3000"`. 앱 포트를 바꿨다면 `PUBLIC_URL`도 그에 맞게 설정하세요.

**부팅할 때 마이그레이션이 실패했습니다.**
앱 로그에 정확한 파일 이름이 나옵니다. API는 마이그레이션이 중간에 멈춘 데이터베이스로는 시작하지 않습니다. 원인을 해결하고 `docker compose -f docker-compose.community.yml up`을 다시 실행하세요. 이미 적용된 파일은 건너뜁니다.

**로그인 로그에 `password authentication failed for user "supabase_auth_admin"`이 나타납니다.**
`db-data` 볼륨이 데이터베이스의 역할 설정보다 오래되었거나, 처음 시작한 뒤 `POSTGRES_PASSWORD`를 바꾼 경우입니다. 역할 비밀번호는 처음 시작할 때만 `POSTGRES_PASSWORD`를 따릅니다. `docker compose -f docker-compose.community.yml down -v`로 볼륨을 삭제하거나(**데이터가 삭제됩니다**), `supabase_admin`으로 역할 비밀번호를 직접 바꾸세요.

**Docker 빌드에서 ffmpeg 아카이브를 내려받거나 검증하지 못합니다.**
이미지를 직접 빌드할 때만 해당합니다. ffmpeg 버전에 따라 렌더링된 오디오와 동영상이 달라지므로, Dockerfile은 `ARG FFMPEG_TARBALL_URL_*`와 `ARG FFMPEG_TARBALL_SHA256_*`로 아키텍처마다 정확한 정적 ffmpeg 빌드를 고정합니다. 다운로드에 실패하거나 체크섬이 맞지 않으면 출력 결과를 조용히 바꾸는 대신 빌드를 멈춥니다. 고정된 빌드는 GitHub의 `nodaroai/ffmpeg-static` 릴리스입니다. 업스트림 ffmpeg에 스케줄러 수정 하나를 더해 소스에서 빌드한 것이며, 소스와 라이선스가 함께 공개되어 있습니다. 공개된 릴리스를 고르고, **두 아키텍처 모두**의 URL과 SHA-256을 **둘 다** 업데이트하세요. 실제 ffmpeg 업그레이드로 취급하고, 이후 렌더링된 출력을 확인하세요.

이미지에는 `/usr/local/share/doc/ffmpeg-static/`에 ffmpeg 바이너리의 라이선스가 들어 있습니다. `LICENSE`, `SOURCE`, `LINK-TRACE.txt`, 그리고 정적으로 링크된 각 라이브러리의 라이선스 텍스트가 담긴 `LICENSES/` 폴더입니다. ffmpeg 바이너리는 GPL-3.0-or-later이며, 소스는 같은 릴리스의 에셋으로 공개되어 있습니다.

## 브라우저 오류
**편집기가 렌더링되지만 빈 화면으로 남거나 “불러오는 중…”이 계속 표시됩니다.**
브라우저 콘솔을 여세요.

- **CORS 오류:** 다음 항목을 참조하세요.
- **로그인 오류:** 내 설치의 `/config.js`를 여세요. 브라우저가 접근할 수 있는 Supabase URL(번들된 스택에서는 `PUBLIC_URL/supabase`)과 anon 키가 들어 있어야 합니다. 컨테이너는 부팅할 때 `PUBLIC_URL`, `FRONTEND_SUPABASE_URL`, `SUPABASE_ANON_KEY`로 이 파일을 씁니다. 이 값들을 고치고 재시작하세요.

**브라우저에 CORS 오류가 나타납니다.**
`http://localhost:3000`과 `PUBLIC_URL`은 항상 허용되므로, LAN 주소나 다른 포트 같은 다른 출처에서 앱을 연 것입니다. `PUBLIC_URL`을 그 출처로 설정하거나, `CORS_ORIGIN`에 추가 출처를 쉼표로 구분해 나열하세요. 예: `CORS_ORIGIN=http://192.168.1.20:3000`. 그런 다음 `docker compose -f docker-compose.community.yml up -d`를 실행하세요.

**NodarCut에서 편집, 또는 앱의 동영상 결과에서 편집을 누르면 편집기 대신 패널이 표시됩니다.**
호스팅된 동영상 편집기는 `http://localhost:3000`에서만 임베딩을 허용합니다. 다른 출처에서는 직접 편집기를 실행하고 `FREECUT_URL`을 설정하세요. [동영상 및 오디오 편집기](https://nodaro.ai/docs/self-hosting/configuration#video-and-audio-editors)를 참조하세요.

**오디오 결과에서 편집을 눌러도 아무 일도 일어나지 않거나, 편집기 대신 패널이 표시됩니다.**
호스팅된 오디오 편집기는 없습니다. 직접 AudioMass를 실행하고 `AUDIOMASS_URL`을 설정하세요.

## 데이터베이스
**마이그레이션이 “relation … does not exist”로 실패합니다.**
마이그레이션이 순서에 맞지 않게 실행되었습니다. `supabase/migrations/`의 파일을 파일 이름 순서대로 적용하세요. 예를 들어 Supabase SQL 편집기에서 적용할 수 있습니다. 각 파일은 이미 적용된 데이터베이스에서 다시 실행해도 됩니다.

**OAuth 콜백이 `500`을 반환합니다.**
마이그레이션 하나가 적용되지 않아서 OAuth 앱용 테이블이 없습니다. 모든 마이그레이션을 파일 이름 순서대로 적용하세요. [데이터베이스](https://nodaro.ai/docs/self-hosting/database#apply-the-migrations-to-a-managed-project)를 참조하세요.

**API가 계속 재시작됩니다.**
Postgres에 연결할 수 없습니다. 데이터베이스가 내려가 있는 동안에는 정상입니다. Postgres가 돌아오면 `docker compose -f docker-compose.community.yml restart nodaro`를 실행하세요.

## 스토리지
**번들된 스택에서 업로드가 실패합니다.**
`http://localhost:9001`에서 MinIO 콘솔을 여세요. 기본 자격 증명은 Compose 파일에 있습니다.

**Cloudflare R2로의 업로드가 `401` 또는 `403`으로 응답합니다.**
API 토큰에 버킷에 대한 **Object Read & Write** 권한이 있는지 확인하세요. R2 앞에 커스텀 도메인을 두었다면 버킷의 공개 접근 설정도 확인하세요. Nodaro는 브라우저에 공개 미디어 URL을 주므로, 인증 없이 읽을 수 있어야 합니다.

**모든 스토리지 요청이 인증 오류나 엔드포인트 오류로 실패합니다.**
`R2_REGION`을 스토리지의 리전으로 설정하세요. AWS, DigitalOcean Spaces, 로컬 Supabase는 기본값 `auto`를 거부하며, 그 오류에는 리전이 언급되지 않습니다.

**`STORAGE_OBJECT_ACL`을 설정한 뒤 모든 업로드가 실패합니다.**
스토리지 키에 객체 ACL을 설정할 권한이 없습니다. 스토리지가 버킷 정책을 거부하는 경우가 아니라면 이 변수를 비워 두세요.

**R2를 쓸 때 부팅 로그에 `[storage] failed to create bucket`이 나타납니다.**
무해합니다. R2 토큰은 버킷을 만들 수 없고, 내 버킷은 이미 있기 때문입니다.

## 실행과 노드
**워크플로가 대기열에 들어가지만 시작되지 않습니다.**
`docker compose -f docker-compose.community.yml logs nodaro`로 로그를 읽으세요. 오케스트레이터는 Redis에서 작업을 가져오므로, Redis에 연결할 수 없으면 아무것도 실행되지 않습니다. `REDIS_URL`을 확인하고 `docker compose -f docker-compose.community.yml exec redis redis-cli ping`을 실행하세요. `PONG`으로 응답해야 합니다.

**노드가 `Missing API key`로 실패합니다.**
노드가 키가 없는 공급자를 호출하고 있습니다. `/setup`이나 `.env`에 키를 추가하세요. [공급자 키](https://nodaro.ai/docs/self-hosting/provider-keys)를 참조하세요.

**이미지와 동영상은 작동하지만 모든 텍스트 기능이 실패합니다.**
`KIE_API_BASE_URL`이 미디어 경로만 전달하는 프록시를 가리키고 있습니다. [내 프록시로 공급자 트래픽 보내기](https://nodaro.ai/docs/self-hosting/provider-keys#send-provider-traffic-through-your-own-proxy)를 참조하세요.

**키를 붙여 넣거나 Nodaro Cloud에 연결할 때 `EncryptionKeyMissingError`로 실패합니다.**
설치에 암호화 키가 없습니다. 관리형 Supabase 프로젝트를 쓴다면 `NODARO_ENCRYPTION_KEY`를 `openssl rand -hex 32`로 만든 64자 16진수 값으로 설정하세요.

**복원 후 공급자 키가 누락됨으로 표시됩니다.**
데이터베이스가 짝이 맞는 암호화 키 없이 복원되었습니다. [백업과 복원](https://nodaro.ai/docs/self-hosting/backups#troubleshooting)을 참조하세요.

**노드가 `503 nodaro_connection_required`로 실패합니다.**
Nodaro Cloud 연결이 필요한 Nodaro 전용 노드입니다. [Nodaro Cloud에 연결](https://nodaro.ai/docs/self-hosting/cloud-connect)을 참조하세요.

**Cloud 실행이 `Token expired`로 실패합니다.**
연결의 90일짜리 토큰이 만료되었습니다. **연결 해제**를 클릭한 다음 **연결**을 클릭하세요.

**Cloud 실행이 `402 instance_cap_reached`로 실패합니다.**
설치가 월간 지출 한도에 도달했습니다. app.nodaro.ai의 **결제 › 연결된 인스턴스**에서 한도를 올리세요.

**정상인 실행이 `Execution orphaned`로 표시됩니다.**
두 설치가 데이터베이스 하나를 공유하면서 서로 다른 Redis를 쓰고 있습니다. 설치마다 고유한 `RUNTIME_ENV`를 지정하세요. [확장](https://nodaro.ai/docs/self-hosting/scaling#two-installs-one-database)을 참조하세요.

**3D 렌더링 Pro가 `503 SCENE_CAPABILITY_UNAVAILABLE`로 응답합니다.**
[3D 렌더링 Pro](https://nodaro.ai/docs/nodes/video/pro-3d-render)는 호스팅된 빌드 서비스에서 실행되며, 셀프 호스팅 에디션에는 포함되지 않습니다. 다른 렌더러로 조용히 대체되는 일은 없습니다. 내 서버에서 실행되는 [3D 장면 생성](https://nodaro.ai/docs/nodes/video/generate-3d-scene)과 [동영상 렌더링](https://nodaro.ai/docs/nodes/video/render-video)을 쓰세요.

## 로그인과 MCP
**SSO 경로가 `404 unknown_provider`로 응답합니다.**
구성된 공급자가 없습니다. `EXTERNAL_SSO_PROVIDERS`를 확인하고, Compose 스택에서는 `nodaro` 서비스의 `environment:` 아래에 추가하세요. [싱글 사인온](https://nodaro.ai/docs/self-hosting/sso)을 참조하세요.

**모든 API 호출이 `403 sso_required`로 응답합니다.**
서피스 프로필이 SSO만 허용하는데, 계정이 SSO를 통해 만들어지거나 연결되지 않았습니다. [로그인 방법](https://nodaro.ai/docs/self-hosting/editions-and-profiles#sign-in-methods)을 참조하세요.

**MCP 클라이언트가 `405 wrong_mcp_host`를 받습니다.**
클라이언트가 앱의 기본 주소를 쓰고 있습니다. 대신 MCP 호스트의 주소를 지정하세요. [MCP](https://nodaro.ai/docs/self-hosting/mcp)를 참조하세요.

## 업데이트
**버전 레이블에 내장 버전만 표시되고 릴리스 노트가 비어 있습니다.**
업데이트 확인이 GitHub를 읽지 못합니다. 로그 줄 `[update-check] … read failed: HTTP 403 (rate limit: 0 of 60 left…)`은 내 외부 주소가 GitHub의 익명 할당량을 모두 썼다는 뜻입니다. `NODARO_UPDATE_CHECK_TOKEN`을 설정하세요. [업데이트](https://nodaro.ai/docs/self-hosting/updating#which-version-you-run)를 참조하세요.

## 도움 받기
그래도 해결되지 않으면 앱 컨테이너의 Docker 로그와 함께 [GitHub](https://github.com/nodaroai/app.nodaro.ai/issues)에 이슈를 여세요.

## 자주 묻는 질문

### 셀프 호스팅 Nodaro가 이상하게 동작할 때는 어디서부터 확인해야 하나요?

내 설치의 /setup을 여세요. 데이터베이스, Redis, 스토리지, 암호화 키, 공급자 키의 상태를 초록색이나 빨간색 카드로 실시간 표시하고, 실패한 카드마다 힌트를 보여 주며, 로그인이 필요 없습니다.

### docker compose up에서 “port is already allocated”는 무슨 뜻인가요?

내 컴퓨터의 다른 프로그램이 포트 3000이나 9001을 쓰고 있다는 뜻입니다. docker-compose.community.yml에서 해당 매핑의 호스트 쪽 포트를 바꾸고(예: "3001:3000"), PUBLIC_URL도 그에 맞게 설정하세요.

### 편집기가 빈 화면으로 남거나 계속 불러오는 중으로 표시되는 이유는 무엇인가요?

브라우저 콘솔을 여세요. CORS 오류는 연 출처가 허용되지 않았다는 뜻이므로 PUBLIC_URL이나 CORS_ORIGIN을 설정하세요. 로그인 오류는 /config.js에 브라우저가 쓸 수 없는 Supabase URL이나 anon 키가 들어 있다는 뜻입니다.

### 워크플로가 실행을 시작하지 않는 이유는 무엇인가요?

오케스트레이터는 Redis에서 작업을 가져옵니다. docker compose logs nodaro로 로그를 확인하고, REDIS_URL을 확인한 다음 docker compose exec redis redis-cli ping을 실행하세요. PONG으로 응답해야 합니다.

### 셀프 호스팅 설치에 대한 도움은 어디서 받을 수 있나요?

앱 컨테이너의 Docker 로그와 함께 github.com/nodaroai/app.nodaro.ai에 이슈를 여세요.
