EmDash CMS 셀프호스트 Node 배포 참고
SQLite에서 PostgreSQL·오브젝트 스토리지로 이어지는 점진적 아키텍처 경로로 자체 인프라에서 EmDash를 실행합니다.
셀프호스팅이 맞는 선택일 때
운영·법률·아키텍처 제약이 있을 때 셀프호스팅을 선택하세요.
- 데이터 상주 요구가 엄격함
- 이미 내부에서 공유 플랫폼 서비스를 운영 중
- 런타임, 프로세스 모델, 네트워크 경로를 완전히 통제해야 함
- 초기 단계에서 관리형 클라우드 결합을 피하고 싶음
셀프호스팅이 자동으로 더 저렴한 것은 아닙니다. 보통 더 통제 가능합니다.
권장 점진 모델
최대 복잡도로 시작하지 마세요. 단계적 롤아웃을 사용하세요.
- Node.js + SQLite + 로컬 파일 저장소
- 다중 인스턴스 안전과 더 강한 내구성을 위한 PostgreSQL
- 미디어 이식성을 위한 S3 호환 오브젝트 스토리지
- 프로세스 감독 및 관측 가능성 강화
이 순서는 이전 충격을 최소화하면서 깔끔한 프로덕션 경로를 유지합니다.
기준 아키텍처(1단계)
단일 노드 프로덕션이나 초기 런치의 경우:
- 앱 런타임: Node 어댑터(
standalone) - 데이터베이스: 영구 디스크의 SQLite 파일
- 미디어: 로컬 업로드 디렉터리
- 리버스 프록시: Nginx 또는 Caddy
이 구성은 런타임 인스턴스 하나로 낮은~중간 편집 부하에 충분합니다.
# 프로덕션 빌드 및 실행
npm install
npm run build
npm run start
2단계 업그레이드 기준(PostgreSQL로 이전)
다음이 보이면 데이터베이스를 업그레이드하세요.
- 동시 쓰기 경합이 잦아짐
- 백업·복구 목표가 파일 복사 전략을 넘어섬
- 더 안전한 다중 인스턴스 배포가 필요함
수평 앱 스케일을 추가하기 전에 PostgreSQL을 사용하세요. SQLite에서 앱 노드를 늘리면 운영 위험이 빠르게 커집니다.
저장소 전략: 로컬 파일 vs 오브젝트 스토리지
로컬 파일(여기서 시작)
저장소 증가가 예측 가능한 단일 인스턴스 환경에 적합합니다.
S3 호환 오브젝트 스토리지(스케일을 위해 이쪽으로)
다음이면 사용하세요.
- 여러 앱 인스턴스가 공유 미디어 접근이 필요함
- 백업과 재해 복구를 표준화해야 함
- CDN·엣지 캐시 전략이 안정적인 객체 URL에 의존
MinIO는 S3 호환 동작을 위해 사설 인프라에서 사용할 수 있습니다.
런타임 프로세스와 프록시 기준
프로세스 관리
다음 중 하나를 사용하세요.
- Linux 네이티브 서비스 제어를 위한
systemd - 프로세스 메트릭과 빠른 재시작을 원하는 팀을 위한
pm2
리버스 프록시
프록시에서 TLS를 종료하고 Node 앱으로 전달하세요.
Host와X-Forwarded-*헤더 유지- 헬스 체크 경로 구성
- 업로드 정책에 맞춘 본문 크기 제한
백업 및 복구 정책
백업 정책을 런치 이후 과제가 아니라 런치 차단 요건으로 다루세요.
최소 기준:
- 일정에 따른 데이터베이스 스냅샷
- 미디어 저장소 백업 또는 복제
- 공개 런치 전 최소 한 번 복원 드릴
테스트에서 한 번도 복원하지 않은 백업은 통제가 아니라 소문입니다.
운영 준비 체크리스트
프로덕션 전환 전에 확인하세요.
- 수동 편집 없이 콜드 재시작이 동작함
- 애플리케이션 로그가 중앙화되어 검색 가능함
- 5xx 알림이 활성화됨
- 디스크 사용량과 저장소 증가가 모니터링됨
- 시크릿 로테이션 절차가 문서화됨
Cloudflare 중심 설정에서의 이전 노트
프로젝트가 Cloudflare 가정으로 시작했다면:
- 런타임 설정에서 클라우드 전용 바인딩 제거
- D1/R2 어댑터를 Node 호환 DB·스토리지 어댑터로 교체
- 리버스 프록시 뒤에서 인증과 콜백 URL 재검증
이전 위험은 대부분 페이지 수준 코드가 아니라 환경 가정에 있습니다.
팀을 위한 결정 프레임워크
다음 규칙을 사용하세요.
- 속도와 최소 운영이 필요하면 관리형 클라우드 경로 선호
- 기존 인프라와의 통제·통합이 필요하면 셀프호스트 경로 선호
환경마다 기본 경로를 하나 고르세요. 하이브리드 배포 모델도 가능하지만 인지 부하와 지원 부담이 커집니다.