환경변수 명세 (Environment Variables)
PortalConsole(제어평면 중앙 운영 콘솔 · 내부 식별자 DirectoryService)이 읽는 환경변수를 한 곳에 정리한다. 각 변수의 필수 여부·기본값·설명·코드 사용 위치를 밝혀, 배포 Secret 구성과 진단의 기준으로 삼는다.
읽는 방법
- 표시 —
필수(없으면 기동/기능 실패) ·조건부(해당 기능을 쓸 때만 필요) ·선택(없으면 기본값) ·테스트(검증 전용). - 기본값 — 코드가 명시한 폴백.
—는 기본값 없음(미설정 시 빈 값/미동작). - 사용 위치 — 값을 실제로 읽는 파일:줄. 서버는 대부분
env = process.env를 주입받는 함수라 호출 시점에 읽는다(재기동 없이 반영되는 값도 있다). - 로딩 규칙 — 서버 코드는
.env를 자동 로드하지 않는다(drizzle 설정만 로드). 호스트에서 실행할 때는 다음 중 하나를 쓴다.bashset -a; . ./.env; set +a; pnpm dev NODE_OPTIONS=--env-file=.env pnpm dev - 프론트엔드 —
client/는 런타임 환경변수를 쓰지 않는다(import.meta.env·VITE_*미사용). 서버가 필요한 값을 API로 내려보낸다.
요약
- 이 콘솔이 읽는 변수는 50여 개(테스트 전용 · compose 전용 포함). 문서는
데이터베이스 → 인증·시크릿 → 연동(ModelGateway/FileStore) → 문서 라이브러리 → 탐색·정책·런타임 → 설치·compose → 레거시 별칭 → 산출/스크립트순으로 나눈다. - 레거시 접두(
DIRECTORY_*등)는server/envAliases.ts가 새 이름으로 복사한다(아래 레거시 별칭 참조). - 이 콘솔이 생성만 하고 읽지 않는(다른 포털로 넘기는) 변수는 프로비저닝 산출에 따로 둔다.
1. 데이터베이스
| 변수 | 필수 | 기본값 | 설명 | 사용 위치 |
|---|---|---|---|---|
DATABASE_URL | 조건부 | — | DB 접속 문자열(mysql:// · postgresql://). 비어 있으면 /setup 설치 마법사 모드로 뜬다. | server/db.ts:6 · server/portalSettings.ts:266 · server/setupBootstrap.ts:60,245 · drizzle.config.ts · drizzle.config.postgres.ts |
DATABASE_DIALECT | 선택 | URL 스킴 추론(postgres→postgresql, 그 외 mysql) | 드라이버 선택. mysql | postgresql 외 값은 오류. | server/db/provider.ts:10 |
DB_POOL_MAX | 선택 | 10 | PostgreSQL pool 최대 연결 수(MySQL에는 미적용). | server/db/provider.ts:28 |
AIVEN_DATABASE_URL | 선택 | — | DB URL 레거시 폴백. 스키마 보증 스크립트가 DATABASE_URL ?? AIVEN_DATABASE_URL로 읽는다. | scripts/ensure-pkce-schema.mjs · scripts/ensure-common-ui-schema.mjs · scripts/ensure-ontology-glossary-schema.mjs |
PORTAL_CONSOLE_RESET_DATABASE_URL | 스크립트 필수 | — | 파괴적 DB 리셋 스크립트의 접속 URL. 없으면 스크립트가 즉시 실패. | scripts/reset-directory-db.mjs:5 |
PORTAL_CONSOLE_RESET_DATABASE_NAME | 스크립트 필수 | — | 리셋 대상 DB 이름(안전장치 — 실제 접속 DB와 다르면 거부). | scripts/reset-directory-db.mjs:6 |
SETUP_INTEGRATION_DATABASE_URL | 테스트 | — | 설치 마법사 통합 검증용 PostgreSQL URL. 없으면 테스트가 SKIP. | scripts/verify-setup-bootstrap.ts:3 |
RUN_POSTGRES_INTEGRATION | 테스트 | — | 1일 때만 PostgreSQL 통합 테스트를 실행(opt-in). | server/postgresMigrationApiKey.integration.test.ts:9 |
2. 인증 · 시크릿
| 변수 | 필수 | 기본값 | 설명 | 사용 위치 |
|---|---|---|---|---|
PORTAL_JWT_SECRET | 조건부 | JWT_SECRET 폴백 | 포털 REST·공통 UI 세션을 검증하는 공유 비밀. 소비 포털 앱과 같은 값이어야 로그인 세션이 통한다. 미설정이면 포털 REST 라우트가 비활성화된다(경고 후 기동). | server/index.ts:100 · server/portalConfig.ts:5 · server/uiDelivery.ts:27 · server/directoryJwt.ts:5 · server/userIdentity.ts:38 |
JWT_SECRET | 선택(폴백) | — | 관리자·디렉터리 JWT 서명 비밀. 설치 마법사가 생성한다. | server/directoryJwt.ts:5 · server/userIdentity.ts:38 · server/adminIdentity.ts:65 · server/setupBootstrap.ts:228 |
PORTAL_JWT_ISSUER | 선택 | directory-service | 포털 기계 토큰의 발급자(iss). | server/portalConfig.ts:11 |
PORTAL_JWT_AUDIENCE | 선택 | directory-portals | 포털 기계 토큰의 audience. directory-user는 항상 추가 허용. | server/portalConfig.ts:7 |
PORTAL_CONSOLE_ENVELOPE_MASTER_KEY | 조건부 | — | 비밀값 봉투 암호화 마스터 키. 32바이트 Base64 한 개. 암호화 경로를 쓰면 필수이며, 형식이 틀리면 오류. | server/envelopeEncryption.ts:17 |
PORTAL_CONSOLE_ENVELOPE_LEGACY_MASTER_KEYS | 선택 | "" | 키 회전용 수용 키 목록(쉼표 구분 Base64). 복호화만 담당. | server/envelopeEncryption.ts:21 |
PORTAL_CONSOLE_ADMIN_API_KEYS_JSON | 선택 | [] | 관리자 API 키 배열 JSON(x-directory-admin-key 헤더). 형식이 틀리면 관리자 키 인증이 꺼진다. | server/adminAuth.ts:13 |
PORTAL_CONSOLE_ADMIN_BOOTSTRAP_TOKEN | 선택 | "" | 레거시 관리자 부트스트랩 토큰(DB 생성 후에만 유효). | server/adminBootstrap.ts:20 · server/adminIdentity.ts:46 |
PORTAL_CONSOLE_SETUP_TOKEN | 조건부(필수*) | — | 공개 설치 마법사 접근 토큰. public 배포(NODE_ENV=production)에서는 필수 — 없으면 설치 실행을 거부한다. | server/setupBootstrap.ts:56,115 |
PORTAL_CONSOLE_REGISTRATION_TOKEN | 조건부 | — | 포털 자기등록(POST /api/internal/portal-registrations) 서비스 토큰. 미설정이면 그 API는 항상 401. | server/portalRegistrationRoute.ts:15 |
PORTAL_CONSOLE_TOKEN_CONSUMERS_JSON | 선택 | 레거시 소비자 폴백 | 서비스 토큰 소비자(위임 audience·scope) 배열 JSON. 비거나 형식 오류면 PROCESS_CENTER_SERVICE_CLIENT_SECRET로 폴백. | server/serviceTokenConsumers.ts:46 |
PROCESS_CENTER_SERVICE_CLIENT_SECRET | 선택(레거시) | — | 단일 소비자 폴백 시크릿(위 소비자 목록 미설정 시). | server/serviceTokenConsumers.ts:57 |
PORTAL_API_KEYS_JSON | 선택 | [] | 포털 API 키 배열 JSON(portalId·apiKey·scopes). 부팅 시 DB로 upsert(환경값이 원장 DB를 채운다). | server/portalApiKeys.ts:28 |
PORTAL_LOGIN_CLIENTS_JSON | 선택 | 내장 목록(BUILT_IN_PORTAL_LOGIN_CLIENTS) | 브라우저 로그인 클라이언트(redirect URI) override. DB 설정이 있으면 그 값이 우선. | server/centralAuth.ts:87 |
PORTAL_CONSOLE_TENANT_ID | 선택 | default | 서버 위임 토큰의 테넌트 키. | server/delegationTokenRoute.ts:11 |
PORTAL_CONSOLE_DEFAULT_CLEARANCE_LEVEL | 선택 | INTERNAL | 위임 토큰의 기본 clearance 등급. | server/delegationTokenRoute.ts:15 |
PORTAL_CONSOLE_SSO_MAP_JSON | 선택 | — | 디렉터리 SSO 사용자 매핑 JSON. 형식 오류면 로컬 계정만 동작. | server/directorySso.ts:88,98 |
3. 연동 서비스
3.1 ModelGateway
게이트웨이는 화면을 갖지 않는다 — 콘솔이 운영 화면의 정본이고(docs/MODEL_GATEWAY_DESK_HANDOFF_2026-09-26.md), 서버 간 토큰으로만 호출한다. 관리 토큰과 소비(서비스) 토큰을 섞지 않는다 — 관리 권한을 좁게 유지한다.
| 변수 | 필수 | 기본값 | 설명 | 사용 위치 |
|---|---|---|---|---|
MODEL_GATEWAY_URL | 조건부 | — | 게이트웨이 base URL. https만 허용하며, localhost/127.0.0.1 또는 PORTAL_ALLOW_INSECURE_PLATFORM_URL=true일 때만 http 허용. | server/modelGateway.ts:10 · server/modelGatewayInference.ts:11 |
MODEL_GATEWAY_ADMIN_TOKEN | 조건부 | — | 게이트웨이 관리(운영 화면) 토큰. 게이트웨이의 같은 이름 값과 일치해야 하며 브라우저에 내려보내지 않는다. | server/modelGateway.ts:11 |
MODEL_GATEWAY_ADMIN_TOKENS | 조건부 | — | 위 관리 토큰의 쉼표 구분 다중 값(회전). 첫 값이 활성. | server/modelGateway.ts:11 |
MODEL_GATEWAY_SERVICE_TOKEN | 조건부 | — | 게이트웨이 소비(추론·번역) 토큰. 설정하면 중앙 번역·AI 호출이 게이트웨이를 경유하고, 없으면 그 기능만 503. | server/modelGatewayInference.ts:12 |
MODEL_GATEWAY_SERVICE_TOKENS | 조건부 | — | 위 서비스 토큰의 쉼표 구분 다중 값(회전). 첫 값이 활성. | server/modelGatewayInference.ts:12 |
3.2 FileStore
첨부파일·프로필 사진 본문은 FileStore가 소유한다(docs/SERVICE_BOUNDARIES.md). 콘솔은 consumerId/mappingId 연결과 정책만 안다.
| 변수 | 필수 | 기본값 | 설명 | 사용 위치 |
|---|---|---|---|---|
FILE_STORE_BASE_URL | 조건부 | — | FileStore base URL. | server/fileStoreClient.ts:13 |
FILE_STORE_SERVICE_TOKEN | 조건부 | — | 콘솔 소비자 서비스 토큰(프로필 사진 업로드). 브라우저에 내려보내지 않는다. | server/fileStoreClient.ts:14 |
FILE_STORE_ADMIN_TOKEN | 조건부 | — | 관리자 토큰(파일 보관 데스크 — 정책·백엔드 관리). | server/fileStore.ts:134 |
FILE_STORE_SYNC_TOKEN | 조건부 | — | 중앙 R2 동기화 내부 계약(/api/internal/file-store/v1/...)의 Bearer 토큰. FileStore의 같은 이름 값과 일치해야 한다. | server/fileStoreRoutes.ts:27 |
PORTAL_CONSOLE_FILESTORE_CONSUMER_ID | 조건부 | — | 콘솔 FileStore 소비자 ID(예: portal-console). | server/fileStoreClient.ts:15 |
PORTAL_CONSOLE_FILESTORE_MAPPING_ID | 조건부 | — | 콘솔 FileStore 매핑 ID(FileStore 관리자 화면에서 등록). | server/fileStoreClient.ts:16 |
PORTAL_CONSOLE_FILESTORE_ORGANIZATION_ID | 선택 | 00000000-0000-0000-0000-000000000000 | 업로드 시 함께 보낼 조직 식별자. | server/fileStoreClient.ts:17 |
PORTAL_CONSOLE_FILESTORE_ENABLED | 선택 | true | 문자열 "false"면 콘솔의 FileStore 소비 호출(프로필 사진)을 비활성화. | server/fileStoreClient.ts:18 |
4. 문서 라이브러리
문서 보관소는 로컬 파일시스템만 지원한다(오브젝트 스토리지는 FileStore 소유). 컨테이너 배포에서는 경로를 볼륨에 연결해야 재배포 후에도 문서가 남는다(docs/DOCUMENT_LIBRARY_STORAGE.md).
| 변수 | 필수 | 기본값 | 설명 | 사용 위치 |
|---|---|---|---|---|
PORTAL_CONSOLE_DOC_LIBRARY_PATH | 선택 | <cwd>/var/doc-library | 문서 보관 로컬 경로. | server/docLibrary.ts:32 |
PORTAL_CONSOLE_DOC_LIBRARY_PROVIDER | 선택 | 파일시스템 | r2로 설정하면 사전조건 오류(더 이상 지원하지 않음). | server/docLibrary.ts:29 |
PORTAL_CONSOLE_LIBRARY_PUBLISH_TOKEN | 선택 | — | CI·운영 도구가 문서를 게시할 때 쓰는 전용 토큰(POST /api/library/v1/documents). 관리자 키를 CI에 주지 않기 위한 좁은 권한. | server/libraryRoutes.ts:9 |
PORTAL_CONSOLE_LIBRARY_PUBLISH_TOKENS | 선택 | — | 위 게시 토큰의 쉼표 구분 다중 값(동시 유효). | server/libraryRoutes.ts:9 |
5. 탐색 · 정책 · 런타임
| 변수 | 필수 | 기본값 | 설명 | 사용 위치 |
|---|---|---|---|---|
PORTAL_EXPLORE_CATALOG_JSON | 선택 | — | 탐색(Agent)·위임 게이트웨이가 볼 서비스 카탈로그 JSON(예: { "<portalId>": { "capabilities": [...], "endpoint": ..., "timeoutMs": ... } }). | server/controlPlaneCatalog.ts:38 |
PORTAL_ADMIN_MENU_JSON | 선택 | 내장 시드(server/portalAdminMenu.ts) | 포털별 공통(FOUNDATION) 관리자 메뉴 override JSON. 없으면 내장 시드, 시드가 없는 포털은 빈 목록(포털이 로컬 시드로 폴백). | server/portalAdminMenu.ts:55,96 |
PORTAL_PROVISIONING_TEMPLATE_REPOSITORY | 선택 | unconfigured | 신규 포털 자동 프로비저닝 템플릿 repo(owner/name 형식). | server/portalProvisioning.ts:357 |
PORTAL_ALLOW_INSECURE_PLATFORM_URL | 선택 | false | true면 플랫폼 서비스 호출에 내부망 http를 허용(기본은 https만). 내부망 전용 배포에서만 켠다. | server/platformLinks.ts:16 |
PORTAL_CONSOLE_GLOSSARY_CACHE_TTL_MS | 선택 | 5000 | 용어(glossary) 읽기 캐시 TTL(ms). 최소 1,000으로 클램프. | server/glossary.ts:10 |
PORTAL_CONSOLE_PUBLIC_URL | 선택 | "" | 콘솔의 공개 주소. 공통 UI 배포 대상 목록에서 콘솔 자신의 baseUrl로 쓰인다. | server/uiDelivery.ts:63 |
PORT | 선택 | 3000 | HTTP 서버 리슨 포트. | server/index.ts:143 |
NODE_ENV | 선택 | — | development면 Vite 개발 미들웨어, 그 외는 정적 서빙. production이면 dist의 마이그레이션 폴더를 쓴다. | server/index.ts:32,125 |
6. 설치 마법사 · 온프렘 compose
| 변수 | 필수 | 기본값 | 설명 | 사용 위치 |
|---|---|---|---|---|
UI_PLATFORM_BASE_URL | 선택 | — | 설치 마법사가 기록하는 UiPlatform 주소(입력 시 environmentValues/environmentKeys에 포함). | server/setupBootstrap.ts:233,264 |
MYSQL_DATABASE | compose 선택 | directory | 온프렘 compose MySQL 데이터베이스 이름. | docker-compose.onprem.yml |
MYSQL_USER | compose 선택 | directory | 온프렘 compose MySQL 사용자. | docker-compose.onprem.yml |
MYSQL_PASSWORD | compose 필수 | — | 온프렘 compose MySQL 비밀번호(없으면 compose가 실패). | docker-compose.onprem.yml |
MYSQL_ROOT_PASSWORD | compose 필수 | — | 온프렘 compose MySQL root 비밀번호(없으면 compose가 실패). | docker-compose.onprem.yml |
PORTAL_CONSOLE_PORT | compose 선택 | 3000 | 온프렘 compose 호스트 포트 매핑(호스트:3000). | docker-compose.onprem.yml |
PORTAL_CONSOLE_DOC_LIBRARY_HOST_PATH | compose 선택 | ./data/doc-library | 문서 라이브러리를 남길 호스트 경로(컨테이너 /app/var/doc-library에 마운트). | docker-compose.onprem.yml |
참고: 예시 파일
.env.onprem.example은 위 값을 한 곳에 모아 둔 배포 템플릿이다.
7. 레거시 별칭
server/envAliases.ts는 이전 접두 이름을 표준 이름으로 복사한다(표준 이름이 이미 값이 있으면 그 값을 우선, 비어 있을 때만 채운다). 이 모듈은 각 서비스 엔트리 최상단에서 import되어 다른 모듈이 환경변수를 읽기 전에 실행된다. 표준 접두는 PORTAL_CONSOLE_* · FILE_STORE_* · UI_PLATFORM_* · RAG_SERVICE_*이며, 규칙은 UiPlatform docs/PLATFORM_NAMING.md를 기준으로 한다. 1릴리스 후 이 파일을 제거할 예정이다.
대표 매핑(전체는 server/envAliases.ts:12):
| 이전 이름(접두) | 표준 이름 | 비고 |
|---|---|---|
DIRECTORY_* | PORTAL_CONSOLE_* | 콘솔 자신의 설정(예: DIRECTORY_SETUP_TOKEN → PORTAL_CONSOLE_SETUP_TOKEN) |
UI_CENTER_* | UI_PLATFORM_* | UiPlatform이 소비 |
RAG_CENTER_* · RAGCENTER_* | RAG_SERVICE_* | RagService가 소비 |
UICENTER_BASE_URL | UI_PLATFORM_BASE_URL | 설치 마법사 기록 값과 동일 이름 |
주의: 별칭 표의 표준 이름 중 일부(PORTAL_CONSOLE_URL · PORTAL_CONSOLE_SYNC_TOKEN · PORTAL_CONSOLE_APP_CONFIG_URL · PORTAL_CONSOLE_ORIGIN · UI_PLATFORM_* · RAG_SERVICE_*)는 다른 서비스나 외부 도구가 읽는 값이라 이 저장소 서버 코드에서는 읽지 않는다.
또한 레거시 이름 DIRECTORY_BASE_URL · DIRECTORY_PORTAL_API_KEY는 envAliases.ts 표에 없지만, 용어 시드 스크립트가 표준 이름의 폴백으로 직접 읽는다(아래 운영 스크립트 입력 참조).
8. 프로비저닝 산출 변수
아래 변수는 이 콘솔이 생성해 넘기기만 하고(자동 프로비저닝) 콘솔 자신은 읽지 않는다. 소비 포털이 자기 환경에 주입받는 값이다(server/portalProvisioning.ts:459).
| 변수 | 용도 |
|---|---|
PORTAL_CONSOLE_URL | 원장(DirectoryService) 주소 |
PORTAL_CONSOLE_PORTAL_ID | 포털 식별자 |
PORTAL_CONSOLE_API_KEY | 포털이 원장을 호출할 API 키 — 전달 이름의 정본(shared/portalDelivery.ts PORTAL_DELIVERY_SECRET_KEY_NAME). 소비 포털들이 이 이름을 먼저 읽는다(ProcessCenter server/directorySyncService.ts·runtimeSettings.ts, GuideCenter server/termLinkDirectory.ts). 옛 이름 PORTAL_CONSOLE_PORTAL_API_KEY 는 각 포털 envAliases 로 함께 받는다 — 기존 배포를 바꾸지 않아도 되고, 새 대상은 정본으로 만든다(2026-10-15) |
PORTAL_CONSOLE_SYNC_ENABLED | 조직·사용자 동기화 on/off |
PORTAL_CONSOLE_SYNC_CRON | 동기화 스케줄 |
PORTAL_CONSOLE_GLOSSARY_ENABLED | 용어 동기화 on/off |
PORTAL_CONSOLE_GLOSSARY_MODE | 용어 동기화 모드(예: real-time) |
PORTAL_THEME_STORAGE_KEY | 테마 저장 키(<portalId>:theme) |
9. 운영 스크립트 입력
서버가 아니라 scripts/ 도구가 읽는 값이다.
| 변수 | 사용 스크립트 | 설명 |
|---|---|---|
PORTAL_CONSOLE_ORIGIN (레거시 DIRECTORY_BASE_URL) | scripts/seed-glossary-terms.mjs | 용어 시드 대상 원장 주소. |
PORTAL_CONSOLE_PORTAL_API_KEY (레거시 DIRECTORY_PORTAL_API_KEY) | scripts/seed-glossary-terms.mjs | 용어 시드 호출용 포털 API 키(glossary:write 스코프). |
관련 문서
docs/ENVIRONMENT_VARIABLES.md— 전체 환경변수 명세(이 문서)docs/COOLIFY_ENV_INVENTORY.md— Coolify 실제 설정 대조 · 이전 체크리스트server/envAliases.ts— 레거시 접두 별칭(제거 예정)docs/deployment-and-reset.md— 배포·리셋 절차docs/DEPLOYMENT_SETUP_TOKEN_GUIDE.md·docs/SETUP_WIZARD_ARCHITECTURE.md— 설치 마법사docs/FILE_STORE_DESK.md·docs/SERVICE_BOUNDARIES.md— FileStore 연동 경계docs/MODEL_GATEWAY_DESK_HANDOFF_2026-09-26.md— ModelGateway 운영 화면docs/envelope-key-rotation.md— 봉투 암호화 키 회전docs/DOCUMENT_LIBRARY_STORAGE.md— 문서 라이브러리 보관docs/central-directory-integration.md·docs/delegation-token-contract.md— 포털 API 키·위임 토큰.env.onprem.example— 온프렘 배포 예시