리버스 프록시와 HTTPS
포트 3000 앞에 nginx나 Caddy를 두어 셀프 호스팅 Nodaro를 내 도메인에서 HTTPS로 제공하고, PUBLIC_URL과 CORS_ORIGIN을 설정한 다음 앱을 재시작하세요.
리버스 프록시를 쓰면 셀프 호스팅 Nodaro를 HTTPS가 적용된 실제 도메인에서 제공할 수 있습니다. Nodaro 컨테이너는 이미 포트 3000에서 웹 서버 Caddy를 실행하므로, 그 포트 앞에 TLS를 종료하는 프록시 하나를 두고 Nodaro에 공개 주소를 알려 주면 됩니다. nginx와 Caddy 모두 쓸 수 있습니다.
포트 3000이 제공하는 것
컨테이너 안의 웹 서버는 모든 것을 하나의 출처에 둡니다.
| 경로 | 응답하는 것 |
|---|---|
/ | 정적 파일로 제공되는 편집기와 앱 |
/v1/* | 컨테이너 안의 포트 9000에서 수신하는 API |
/storage/* | 번들된 MinIO의 미디어 |
/supabase/* | 번들된 로그인과 데이터 API |
/config.js | 앱이 시작되기 전에 브라우저가 읽는 런타임 설정 |
프록시는 모든 요청을 포트 3000으로 전달하기만 하면 됩니다.
방법 A: nginx
이미 nginx나 다른 프록시를 쓰고 있다면 이 방법을 쓰세요.
server {
listen 443 ssl http2;
server_name nodaro.example.com;
ssl_certificate /etc/letsencrypt/live/nodaro.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nodaro.example.com/privkey.pem;
client_max_body_size 100M;
proxy_buffering off; # important for SSE
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}client_max_body_size 100M은 업로드가 통과하게 합니다.proxy_buffering off는 Server-Sent Events가 계속 흐르게 합니다. Nodaro는 이것으로 텍스트 출력과 실행 진행 상황을 스트리밍합니다.
방법 B: 호스트의 Caddy
Caddy는 Let's Encrypt 인증서를 자동으로 받아 줍니다.
nodaro.example.com {
reverse_proxy 127.0.0.1:3000 {
flush_interval -1
}
}포트 80과 443을 열고, 도메인의 A 또는 AAAA 레코드가 호스트를 가리키게 하세요. flush_interval -1은 Server-Sent Events가 계속 흐르게 합니다.
Nodaro에 공개 주소 알리기
어느 방법을 쓰든 그다음 .env에 다음 값을 설정하세요.
PUBLIC_URL=https://nodaro.example.com
CORS_ORIGIN=https://nodaro.example.com
# On the bundled MinIO, serve the media from the same domain:
R2_PUBLIC_URL=https://nodaro.example.com/storage/nodaro-assets그런 다음 적용하세요.
docker compose -f docker-compose.community.yml up -d다시 빌드할 필요는 없습니다. 컨테이너는 부팅할 때 공개 URL, 브라우저의 로그인 주소, anon 키를 /config.js에 쓰고, 브라우저는 앱이 시작되기 전에 이 파일을 읽습니다.
PUBLIC_URL은 모든 곳에서 쓰이는 설치의 주소입니다. 로그인과 OAuth 콜백, 미디어 URL, CORS 검사에 쓰입니다. http://localhost:3000과 PUBLIC_URL은 항상 브라우저 출처로 허용됩니다.
여러 호스트 이름으로 제공
- 추가 출처.
CORS_ORIGIN에 쉼표로 구분해 나열하세요. 예:CORS_ORIGIN=https://nodaro.example.com,http://192.168.1.20:3000. - 방문자의 호스트 이름에서 스트림 유지. 기본 컨테이너처럼 API가 앱과 같은 출처를 쓴다면
PUBLIC_URL_SAME_ORIGIN=true로 설정하세요. 그러면/config.js가 브라우저에PUBLIC_URL대신 API 주소/를 알려 주므로, 스트림이 방문자가 연 호스트 이름에 머뭅니다. 정확히true값일 때만 활성화됩니다. API가 실제로 다른 호스트에 있다면 설정하지 마세요.
Compose 파일은 .env에서 PUBLIC_URL_SAME_ORIGIN을 전달하지 않습니다. nodaro 서비스의 environment: 아래에 추가하세요. 구성을 참조하세요.
포트 변경
앱을 다른 호스트 포트에서 제공하려면 docker-compose.community.yml에서 매핑의 호스트 쪽 포트를 바꾸세요. 예: "3001:3000". 그런 다음 PUBLIC_URL도 그에 맞게 http://localhost:3001처럼 설정하세요.
클라이언트 주소 기록 방식
컨테이너 안의 웹 서버는 사설 주소에 있는 프록시에서 온 X-Forwarded-* 헤더만 받습니다. 사설 주소는 127.0.0.1/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fd00::/8, ::1입니다.
- 신뢰할 수 있는 프록시에서 온 경우,
X-Forwarded-For를 클라이언트 주소 하나로 줄입니다. 그 자체가 신뢰할 수 있는 프록시가 아닌 가장 오른쪽 항목입니다. 클라이언트가 헤더에 직접 쓴 주소는 건너뜁니다. - 공인 주소에 있는 프록시에서 온 경우, 해당 헤더를 웹 서버가 직접 관찰한 값으로 바꿉니다.
인트라넷에서는 사용자의 주소도 사설 주소이면 같은 규칙에 따라 그 주소도 건너뜁니다. 그러면 LAN의 클라이언트가 API에 기록되는 주소를 직접 고를 수 있습니다. 예를 들어 요청 한도에 쓰이는 주소입니다.
내 도메인의 임베디드 편집기
NodarCut에서 편집, 또는 앱의 동영상 결과에서 편집을 누르면 freecut.nodaro.ai의 호스팅된 동영상 편집기가 열립니다. 이 편집기는 http://localhost:3000에서만 임베딩을 허용합니다. 도메인이나 LAN 주소 같은 다른 출처에서는 브라우저가 임베딩을 거부하고, 패널에 그 이유가 표시됩니다. 내가 제공하는 URL과 함께 GitHub에 이슈를 열거나, 직접 편집기를 실행하고 FREECUT_URL을 설정하세요. 구성을 참조하세요.
MCP 전용 호스트 이름
MCP 클라이언트는 포트 9000의 API에 직접 닿아야 합니다. 포트 3000의 웹 서버는 MCP 요청을 거부합니다. MCP를 참조하세요.
자주 묻는 질문
Nodaro 컨테이너에 이미 웹 서버가 들어 있나요?
네. 컨테이너는 포트 3000에서 Caddy를 실행합니다. 편집기를 제공하고, /v1을 포트 9000의 API로 전달하며, 미디어와 번들된 로그인을 같은 출처에서 제공합니다. HTTPS를 쓰려면 포트 3000 앞에 TLS를 종료하는 프록시를 두세요.
Nodaro를 도메인 뒤에 둔 다음 무엇을 바꿔야 하나요?
PUBLIC_URL과 CORS_ORIGIN을 내 https 주소로 설정하고, 번들된 MinIO에서는 R2_PUBLIC_URL을 https://your-domain/storage/nodaro-assets로 설정하세요. 그런 다음 docker compose up -d를 실행하세요. 다시 빌드할 필요는 없습니다.
nginx 프록시를 쓰면 스트리밍 출력이 끊기는 이유는 무엇인가요?
nginx는 기본적으로 응답을 버퍼링하므로 Server-Sent Events가 지연됩니다. proxy_buffering off로 설정하세요. 호스트에서 Caddy를 쓴다면 reverse_proxy 블록에 flush_interval -1을 설정하세요.
Nodaro가 여러 호스트 이름으로 응답할 수 있나요?
네. 추가 출처를 CORS_ORIGIN에 쉼표로 구분해 나열하세요. 기본 컨테이너처럼 API가 앱과 같은 출처를 쓴다면, 스트림이 방문자가 연 호스트 이름에 머물도록 PUBLIC_URL_SAME_ORIGIN=true도 설정하세요.
관련 문서
설치
구성
셀프 호스팅 설치의 MCP
문제 해결
최종 업데이트