PortalConsole DB-less 최초 설치 및 환경변수 운영 가이드
적용 대상: DATABASE_URL이 없는 PortalConsole의 최초 production deployment입니다. 이 문서는 MySQL 또는 PostgreSQL을 선택해 /setup에서 초기화하는 방법과 관리형 클라우드, 온프레미스에서 설치 접근 token 및 최종 runtime 환경변수를 안전하게 적용하는 방법을 설명합니다.
PORTAL_CONSOLE_SETUP_TOKEN은 로그인 비밀번호·DB 비밀번호·PortalConsole JWT가 아닙니다. DB 없는 production service에서 setup API를 승인하는 bootstrap secret입니다.NODE_ENV=production이면 이 secret이 없을 때 DB 검증·설치·계획 수립이 모두 거부됩니다.

Mobile preview
아래 390×844 CSS pixel mobile viewport preview는 단계 rail이 상단으로 전환되고, 설치 접근 token·관리형 클라우드·온프레미스 안내와 database 선택 card가 한 열로 자연스럽게 이어지는지 확인한 결과입니다. 가로 overflow 없이 세로 scroll로 모든 입력과 action에 접근할 수 있습니다.

1. DB-less 설치의 작동 원리
최초 deployment에서는 DATABASE_URL을 설정하지 않습니다. PortalConsole는 정상 관리자 화면 대신 /setup만 제공하고, setup wizard는 MySQL 또는 PostgreSQL 연결을 검증한 뒤 선택한 dialect의 migration을 적용합니다. 초기 관리자 생성이 끝나면 wizard는 runtime에 필요한 database URL, dialect, JWT secret, portal JWT secret을 생성합니다. 관리형 클라우드 자동 적용을 선택하면 명시적 승인 후 해당 플랫폼 service에 기록하고 재배포를 요청합니다. 직접 적용을 선택하면 secret 값을 포함한 environment bundle을 한 번만 화면에 표시합니다.
| 시점 | 설정 또는 입력 | 보안 경계 |
|---|---|---|
| 최초 service 기동 전 | NODE_ENV=production, PORTAL_CONSOLE_SETUP_TOKEN | 두 값은 platform secret 또는 권한 제한 env file에만 저장 |
/setup 1단계 | setup token, MySQL 또는 PostgreSQL URL | URL은 connection validation·migration transaction에서만 사용 |
/setup 2단계 | 초기 관리자, 선택 FileStore·UiPlatform URL | 초기 관리자 password는 scrypt hash로만 저장 |
/setup 3단계 | MANUAL/관리형 클라우드 선택, provider 식별값 | provider write는 최종 승인 전에는 실행되지 않음 |
| setup 완료 뒤 | generated runtime variables 적용 후 재시작 | secret 값은 installation API response나 log에 다시 노출하지 않음 |
2. Bootstrap 환경변수
아래 두 값은 DB 없는 public service를 처음 열기 위한 최소 bootstrap configuration입니다. PORTAL_CONSOLE_SETUP_TOKEN과 JWT_SECRET·PORTAL_JWT_SECRET은 목적이 다르며, setup 전에는 후자의 두 값을 직접 설정할 필요가 없습니다. wizard가 설치 시 별도 무작위 값을 생성합니다.
| 변수 | 최초 기동에서의 값 | 언제 사용하는가 |
|---|---|---|
NODE_ENV | production | production security policy를 활성화 |
PORTAL_CONSOLE_SETUP_TOKEN | 별도 무작위 secret | /setup의 validate, plan, install 승인 |
DATABASE_URL | 설정하지 않음 | 미설정일 때만 DB-less wizard가 표시 |
DATABASE_DIALECT | 설정하지 않음 | setup이 최종 database 선택에 따라 생성 |
JWT_SECRET | 설정하지 않음 | setup이 random secret 생성 후 runtime으로 전달 |
PORTAL_JWT_SECRET | 설정하지 않음 | setup이 random secret 생성 후 runtime으로 전달 |
안전한 운영 terminal에서 아래 명령으로 setup token을 생성할 수 있습니다. 출력값은 Git, .env.example, 스크린샷, issue, chat에 넣지 말고 조직의 secret manager에만 저장합니다.
openssl rand -base64 48 | tr -d '\n'; echo3. 공통 wizard 절차
빈 database와 database owner 또는 migration에 필요한 최소 권한 계정을 준비한 뒤, 아래 platform별 방법으로 bootstrap environment를 등록하고 새 deployment를 시작합니다. 공개 service URL의 /setup을 열어 token을 입력하고 database dialect·URL을 선택합니다. 연결 확인을 통과한 뒤 초기 관리자와 선택 endpoint를 입력하고, deployment plan을 검토합니다. provider 자동 적용은 최종 checkbox로 승인해야만 실행됩니다.
| setup 선택 | 설치 완료 후 처리 |
|---|---|
MANUAL | 화면에 한 번 표시되는 environment bundle을 platform/secret manager에 붙여넣고 직접 restart |
PortalConsole는 사용자 승인 없이 관리형 클라우드에 환경변수를 쓰거나 deploy를 요청하지 않습니다. UI에서
MANUAL을 선택하면 외부 provider write 자체가 수행되지 않습니다.
4. 관리형 클라우드 설정 절차
배포 콘솔에서 PortalConsole Web Service를 열고 좌측 Environment 화면으로 이동합니다. Environment Variables의 + Add Environment Variable로 아래 bootstrap key를 등록합니다. 여러 값을 .env 형식으로 준비했다면 Add from .env도 사용할 수 있습니다.[1]
NODE_ENV=production
PORTAL_CONSOLE_SETUP_TOKEN=<별도로-생성한-무작위-setup-secret>
# DATABASE_URL, DATABASE_DIALECT, JWT_SECRET, PORTAL_JWT_SECRET은 최초 wizard 전에 입력하지 않습니다.환경변수를 저장할 때는 Save, rebuild, and deploy 또는 Save and deploy를 선택합니다. 관리형 클라우드의 Save only는 다음 deploy 전까지 실행 중인 instance에 반영하지 않습니다.[1] deploy가 완료되면 service public URL 뒤에 /setup을 열고 token을 입력합니다.
관리형 클라우드 자동 반영을 선택한 경우
wizard 2단계의 배포 방식을 관리형 클라우드로 선택하고 관리형 클라우드 service ID와 platform API access token을 입력합니다. 계획 검토 후 external configuration approval checkbox를 선택하면 PortalConsole는 다음 key만 service별로 갱신합니다. 값 전체를 목록 교체 방식으로 쓰지 않으므로 기존의 무관한 관리형 클라우드 variable을 삭제하지 않습니다.
| setup이 관리형 클라우드에 기록하는 key | 값의 출처 |
|---|---|
DATABASE_URL | wizard에서 검증한 URL |
DATABASE_DIALECT | MySQL 또는 PostgreSQL 선택 |
JWT_SECRET | setup 시 생성한 random secret |
PORTAL_JWT_SECRET | setup 시 생성한 random secret |
PORTAL_CONSOLE_SETUP_ENABLED | false |
UI_PLATFORM_BASE_URL | 입력한 경우만 |
모델 게이트웨이 관리 화면(좌측 메뉴 → 모델 게이트웨이 관리)을 쓰려면 게이트웨이를 별도로 배포한 뒤 Console service에 MODEL_GATEWAY_URL과 MODEL_GATEWAY_ADMIN_TOKEN을 직접 설정합니다(게이트웨이의 같은 이름 토큰과 일치해야 합니다). wizard는 이 두 key를 기록하지 않으며, 토큰은 서버 간 호출에만 쓰이고 브라우저에는 노출되지 않습니다.
평문(내부망 http) 예외 — PORTAL_ALLOW_INSECURE_PLATFORM_URL: 기본 규칙은 MODEL_GATEWAY_URL·FILE_STORE_BASE_URL 같은 플랫폼 서비스 주소에 https만 허용합니다(localhost http는 예외). 콘솔과 게이트웨이를 같은 호스트에 함께 배포하면 컨테이너에서 공인 도메인으로 나가는 경로(hairpin NAT)가 막혀 모델 게이트웨이에 연결하지 못했습니다(…). fetch failed가 날 수 있습니다. 그때는 내부 서비스 주소(예: http://model-gateway:8080)를 쓰고 PORTAL_ALLOW_INSECURE_PLATFORM_URL=true를 함께 설정하세요.
- 켜면 플랫폼 서비스 호출이 평문이 될 수 있으므로 내부망 전용 배포에서만 씁니다(외부 노출 배포에서는 끕니다).
- 켠 상태는 화면 상단에 경고 문구로 표시됩니다(모델 게이트웨이 관리 화면).
- 값은 정확히
true여야 합니다(1·yes등은 켜지지 않습니다).
FileStore URL과 포탈별 FileStore 연결 정보는 설치 마법사의 환경변수가 아니라 관리자 화면의 포털 URL 등록 → FileStore 첨부파일 연결에서 포탈별로 저장합니다. Service Token은 PortalConsole의 envelope 암호화 키로 보호됩니다.
provider access token은 browser state에서만 사용하고 setup 완료 후 비웁니다. 운영 원칙상 배포 콘솔에서 token을 장기 보관하지 말고 조직 secret manager에서 필요 시 재발급합니다.
관리형 클라우드 수동 반영을 선택한 경우
wizard에서 MANUAL을 선택했다면 installation complete 화면의 one-time environment bundle을 Environment 화면에 key별로 입력한 뒤 Save and deploy를 실행합니다. source-controlled 배포 설정(IaC)을 쓰더라도 secret 값을 Git에 commit하지 말고 secret placeholder 또는 Dashboard secret input으로 주입해야 합니다.
5. 관리형 클라우드 설정 절차
관리형 클라우드 Project에서 PortalConsole service를 연 뒤 Variables tab으로 이동합니다. New Variable로 bootstrap key를 추가하거나 RAW Editor에 .env 형식의 두 줄을 붙여넣습니다. 관리형 클라우드는 변수 변경을 staged changes로 보관하므로, 변경 내역을 검토한 뒤 대상 environment에 Deploy해야 실행 중인 service에 반영됩니다.[2]
NODE_ENV=production
PORTAL_CONSOLE_SETUP_TOKEN=<별도로-생성한-무작위-setup-secret>
# DATABASE_URL, DATABASE_DIALECT, JWT_SECRET, PORTAL_JWT_SECRET은 최초 wizard 전에 입력하지 않습니다.PORTAL_CONSOLE_SETUP_TOKEN은 Variables 화면에서 저장 후 Seal을 적용합니다. sealed variable 값은 build·deployment에는 전달되지만 UI와 API에서 다시 조회되지 않습니다. seal은 되돌릴 수 없으므로 원본 token은 secret manager에 먼저 보관합니다.[2]
관리형 클라우드 자동 반영을 선택한 경우
wizard 2단계에서 관리형 클라우드를 선택하고 project ID, environment ID, service ID, platform API access token을 입력합니다. 계획을 확인한 뒤 최종 승인하면 PortalConsole는 variableUpsert 범위로 위 표의 runtime key를 해당 service/environment에 기록하고, 환경변수 반영 후 재배포 요청을 선택했다면 deployment trigger를 요청합니다. PORTAL_CONSOLE_SETUP_TOKEN은 bootstrap secret이므로 자동 runtime bundle에 포함하지 않습니다.
관리형 클라우드 수동 반영을 선택한 경우
MANUAL completion 화면에 표시된 bundle을 배포 환경변수 tab에 등록한 뒤 해당 environment의 staged changes를 deploy합니다. DB가 관리형 클라우드의 별도 service라면 URL을 wizard 1단계에 입력하되, setup token·JWT secret을 database service에 복사하지 않습니다. 관리형 클라우드 service reference variable은 ${{SERVICE_NAME.VARIABLE}} 형식이며 DB connection variable에만 제한적으로 사용합니다.[2]
6. 온프레미스 Linux 설정 절차
온프레미스에는 root only 또는 PortalConsole service account만 읽을 수 있는 env file을 만들고 systemd, Docker, Kubernetes secret 등 조직 표준 process manager로 주입합니다. 다음은 /etc/directory-service/bootstrap.env를 쓰는 예시입니다.
sudo install -d -m 0750 -o directoryservice -g directoryservice /etc/directory-service
sudo sh -c 'cat > /etc/directory-service/bootstrap.env <<"EOF"
NODE_ENV=production
PORTAL_CONSOLE_SETUP_TOKEN=<별도로-생성한-무작위-setup-secret>
# DATABASE_URL은 최초 setup 동안 비워 둡니다.
EOF'
sudo chown directoryservice:directoryservice /etc/directory-service/bootstrap.env
sudo chmod 0600 /etc/directory-service/bootstrap.envsystemd unit은 다음처럼 bootstrap file을 process에 연결합니다. 경로와 node/pnpm 실행 위치는 조직 release directory에 맞춰 조정합니다.
[Service]
User=directoryservice
Group=directoryservice
WorkingDirectory=/srv/directory-service/current
EnvironmentFile=/etc/directory-service/bootstrap.env
ExecStart=/usr/bin/env pnpm start
Restart=on-failuresudo systemctl daemon-reload && sudo systemctl restart directory-service 후 private management network에서 /setup에 접속합니다. Docker 기반 운영도 같은 원칙으로 docker run --env-file /etc/directory-service/bootstrap.env ... 또는 orchestrator secret mount를 사용할 수 있습니다. installation 후 MANUAL bundle을 별도 runtime env file/secret object에 안전하게 반영하고 service를 다시 시작합니다.
7. 설치 후 token rotation과 점검
설치가 완료되면 DATABASE_URL이 runtime에 존재하므로 setup wizard는 더 이상 동작하지 않습니다. bootstrap token은 setup database나 provider environment bundle에 저장되지 않습니다. 조직 정책에 따라 token을 platform secret에서 제거하거나, disaster recovery 대비용 sealed secret으로 유지하고 주기적으로 교체할 수 있습니다.
| 운영 정책 | 권장 처리 |
|---|---|
| 최소 노출 | 최초 installation 확인 후 PORTAL_CONSOLE_SETUP_TOKEN 제거. 새 빈 DB로 재설치가 필요하면 새 token을 설정·배포 |
| 재설치 대비 | platform secret manager에 유지하고 rotation schedule 적용. 값은 UI·Git·문서에 노출하지 않음 |
다음 항목을 확인하면 최초 설치가 완료된 것입니다. /setup이 아닌 /admin으로 이동하고, 새 초기 관리자로 로그인할 수 있으며, 관리형 클라우드 자동 적용을 선택했다면 해당 플랫폼의 deployment event가 성공 상태여야 합니다. 수동 적용을 선택했다면 display된 bundle을 모두 반영한 뒤 새 process가 DATABASE_URL을 읽고 시작했는지 service log에서 확인합니다.
8. 문제 해결
| 증상 | 확인할 항목 | 조치 |
|---|---|---|
| setup validate/plan/install이 token 오류로 거부됨 | production에서 PORTAL_CONSOLE_SETUP_TOKEN 설정 여부와 입력값 일치 | 새 secret을 등록했다면 platform deploy/restart 완료 후 재시도 |
/setup 대신 관리자 route가 열림 | DATABASE_URL이 이미 설정되었거나 기존 DB가 연결됨 | UI 최초 설치가 필요하면 새로운 empty environment/database에서 시작 |
| 관리형 클라우드 variable이 반영되지 않음 | Save only 사용 또는 deploy 미완료 | Save and deploy/rebuild를 실행하고 Events에서 새 deployment 확인 [1] |
| 관리형 클라우드 variable이 반영되지 않음 | staged changes가 Deploy되지 않음 | Variables change를 review하고 target environment에 Deploy [2] |
| provider 자동 적용이 거부됨 | final approval 또는 provider ID/access token 부족 | 계획을 다시 검토하고 필요한 provider field를 입력한 뒤 명시적 승인 |