콘텐츠로 이동

Docker로 배포

Chorus는 공식 Docker 이미지 **chorusaidlc/chorus-app**을 제공합니다. 이 가이드는 두 가지 Compose 형태(스탠드얼론(내장 데이터베이스)과 프로덕션(외부 PostgreSQL + Redis)), 기존 데이터베이스에 연결하는 순수 docker run, 전체 환경 변수 참고, 그리고 컨테이너가 시작 시 무엇을 하는지 보여 줍니다.

먼저 이미지를 풀합니다.

Terminal window
docker pull chorusaidlc/chorus-app:latest

스탠드얼론 형태와 프로덕션 형태 중 무엇을 고를지는 배포 개요를 참고하세요.

스탠드얼론(내장 데이터베이스)

섹션 제목: “스탠드얼론(내장 데이터베이스)”

외부 데이터베이스가 필요 없습니다. 이미지는 PGlite(내장 PostgreSQL)를 함께 담고 있으며 모든 것을 자동으로 시작합니다. 데이터는 Docker 볼륨에 저장되어 컨테이너 재시작을 넘어 유지됩니다.

docker-compose.local.yml을 만듭니다.

# Standalone Chorus — embedded PGlite, no external PostgreSQL or Redis
services:
app:
image: chorusaidlc/chorus-app:latest
ports:
- "8637:8637"
environment:
# No DATABASE_URL — entrypoint auto-starts embedded PGlite
- REDIS_URL=
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET:-chorus-local-secret}
- COOKIE_SECURE=false
- DEFAULT_USER=${DEFAULT_USER:-admin@example.com}
- DEFAULT_PASSWORD=${DEFAULT_PASSWORD:-changeme}
volumes:
- chorus-local-data:/app/data
volumes:
chorus-local-data:

그런 다음 실행합니다.

Terminal window
docker compose -f docker-compose.local.yml up -d

http://localhost:8637을 열고 admin@example.com / changeme로 로그인합니다(또는 DEFAULT_USER / DEFAULT_PASSWORD 환경 변수로 재정의합니다).

스탠드얼론 모드에서 컨테이너는 다음을 수행합니다.

  • PGlite를 내부 포트(5433)에서 시작하며, 외부로 노출하지 않습니다.
  • 데이터를 chorus-local-data Docker 볼륨에 저장하므로 재시작을 넘어 유지됩니다.
  • Redis를 비활성화합니다(메모리 내 EventBus로 폴백 — 단일 인스턴스만).
  • 시작 시 Prisma 마이그레이션을 자동으로 실행합니다.

프로덕션 환경, 특히 다중 복제본을 둘 때는 앱을 외부 PostgreSQL과 Redis에 연결하세요. docker-compose.yml을 만듭니다.

services:
app:
image: chorusaidlc/chorus-app:latest
ports:
- "8637:8637"
environment:
- DATABASE_URL=postgresql://chorus:chorus@db:5432/chorus
- REDIS_URL=redis://default:chorus-redis@redis:6379
- NEXTAUTH_SECRET=change-me-to-a-random-secret
- DEFAULT_USER=admin@example.com
- DEFAULT_PASSWORD=your-password
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
redis:
image: redis:7-alpine
command: redis-server --requirepass chorus-redis
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "-a", "chorus-redis", "ping"]
interval: 5s
timeout: 3s
retries: 5
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: chorus
POSTGRES_PASSWORD: chorus
POSTGRES_DB: chorus
volumes:
- chorus-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U chorus -d chorus"]
interval: 5s
timeout: 5s
retries: 5
volumes:
chorus-data:
redis-data:

그런 다음 실행합니다.

Terminal window
docker compose up -d

http://localhost:8637을 열고 DEFAULT_USER / DEFAULT_PASSWORD에 설정한 자격 증명으로 로그인합니다.

기존 PostgreSQL에 연결해 실행하기

섹션 제목: “기존 PostgreSQL에 연결해 실행하기”

이미 PostgreSQL과 Redis가 실행 중이라면 컨테이너를 직접 시작합니다.

Terminal window
docker run -d \
-p 8637:8637 \
-e DATABASE_URL=postgresql://user:pass@your-db-host:5432/chorus \
-e REDIS_URL=redis://default:password@your-redis-host:6379 \
-e NEXTAUTH_SECRET=change-me-to-a-random-secret \
-e COOKIE_SECURE=false \
-e DEFAULT_USER=admin@example.com \
-e DEFAULT_PASSWORD=your-password \
chorusaidlc/chorus-app:latest
변수설명
DATABASE_URLPostgreSQL 연결 문자열. 형식: postgresql://user:password@host:port/dbname. 대신 개별 DB_* 변수를 설정할 수도 있습니다(아래 참고). 생략하면 엔트리포인트가 내장 PGlite 인스턴스를 자동으로 시작합니다.
NEXTAUTH_SECRETJWT 세션 토큰에 서명하기 위한 비밀 키. 무작위 문자열을 사용하세요(예: openssl rand -base64 32).

데이터베이스(DATABASE_URL의 대안)

섹션 제목: “데이터베이스(DATABASE_URL의 대안)”

DATABASE_URL이 설정되지 않은 경우, 엔트리포인트는 다음 개별 변수로 그것을 조립합니다.

변수설명
DB_HOSTPostgreSQL 호스트
DB_PORTPostgreSQL 포트(기본값: 5432)
DB_USERNAMEPostgreSQL 사용자 이름
DB_PASSWORDPostgreSQL 비밀번호
DB_NAME데이터베이스 이름
변수설명
REDIS_URL전체 Redis 연결 문자열. 형식: redis://username:password@host:port. 개별 변수보다 우선합니다.
REDIS_HOSTRedis 호스트(REDIS_URL이 설정되지 않은 경우 사용)
REDIS_PORTRedis 포트(기본값: 6379)
REDIS_USERNAMERedis 사용자 이름(기본값: default)
REDIS_PASSWORDRedis 비밀번호
변수설명
DEFAULT_USER내장 로그인용 이메일 주소(OIDC를 우회합니다). 첫 로그인 시 사용자와 회사를 자동으로 프로비저닝합니다.
DEFAULT_PASSWORD기본 사용자의 비밀번호(평문이며, 런타임에 bcrypt로 대조합니다).
NEXTAUTH_URL앱의 외부 공개 기본 URL(기본값: http://localhost:8637). 리버스 프록시 뒤에서 실행할 때 설정합니다.
COOKIE_SECUREHTTP 전용 배포에서 보안 쿠키를 끄려면 "false"로 설정합니다(docker-compose에서는 기본값 "false"). 프로덕션에서 HTTPS로 배포할 때는 "true"로 설정합니다.
변수기본값설명
LOG_LEVELinfo(프로덕션) / debug(개발)서버 최소 로그 레벨. 허용 값: trace, debug, info, warn, error, fatal, silent. Prisma 쿼리 로그를 억제하려면 info로 설정합니다.
NEXT_PUBLIC_LOG_LEVELwarn(프로덕션) / debug(개발)브라우저 최소 로그 레벨. 허용 값: debug, info, warn, error.

프로덕션 Docker 이미지는 항상 JSON을 stdout으로 출력합니다(CloudWatch / ELK에 바로 연결 가능). 색상이 입혀진 보기 좋은 출력은 로컬 개발에서만 사용할 수 있습니다.

변수설명
SUPER_ADMIN_EMAIL슈퍼 관리자 계정의 이메일(/admin 패널에 접근할 수 있습니다).
SUPER_ADMIN_PASSWORD_HASH슈퍼 관리자 비밀번호의 bcrypt 해시. 생성 방법: node -e "console.log(require('bcryptjs').hashSync('your-password', 10))"

컨테이너의 엔트리포인트는 시작할 때마다 같은 순서를 실행합니다.

  1. DATABASE_URL이 설정되지 않고 DB_* 변수도 하나도 제공되지 않으면, 엔트리포인트는 내부 포트(5433)에서 내장 PGlite 인스턴스를 시작합니다. 외부 데이터베이스가 구성되어 있으면 PGlite는 시작하지 않습니다.
  2. prisma migrate deploy를 실행해 보류 중인 데이터베이스 마이그레이션을 적용합니다.
  3. 데이터베이스가 아직 준비되지 않았으면 10초마다 재시도합니다(최대 30회, 약 5분).
  4. 마이그레이션이 성공하면 Next.js 서버가 8637 포트에서 시작합니다.
  • 기본 이미지: node:22-alpine
  • 내부 포트: 8637
  • 아키텍처: linux/amd64, linux/arm64
  • 프로덕션 배포: 글로벌 npm 패키지에서 실행하기와 전체 AWS CDK 안내.
  • 운영: 첫 로그인 부트스트랩, 배포 측 인증, 그리고 업그레이드 전 백업.