FileStore 배포 환경변수 정리표
FileStore 서버가 실제로 읽는 이름만 남기는 기준을 정리한다. 다른 서비스(포탈·UiPlatform·ModelGateway)의 환경변수를 FileStore 서비스에 함께 넣어 두면 "설정했는데 동작하지 않는다"가 되어 진단이 어려워진다. 실제로 다음 두 가지 혼동이 배포 장애로 이어졌다.
FILE_STORE_SYNC_TOKEN·FILE_STORE_BASE_URL은 이름은FILE_STORE_*지만 PortalConsole 이 읽는 값이다. FileStore 쪽 이름은PORTAL_CONSOLE_SYNC_TOKEN·FILE_STORE_PUBLIC_URL이다.DIRECTORY_ENVELOPE_MASTER_KEY는 레거시 이름이고 콘솔 키(PORTAL_CONSOLE_ENVELOPE_MASTER_KEY)로 매핑된다. FileStore 가 쓰는 키는FILE_STORE_ENVELOPE_MASTER_KEY다.
1. FileStore 가 읽는 환경변수 (정본)
src/ 전체에서 읽는 이름만 나열한다.
| 변수 | 필요도 | 적용 모드 | 설명 |
|---|---|---|---|
DATABASE_URL | 필수(공유 DB 배포) | — | 설정돼 있으면 설정·계정·정책·자산·자격증명·OAuth 토큰·피드 커서가 모두 file_store_* 테이블을 쓴다(src/server.ts:132~147). |
DATABASE_SSL | 선택 | Postgres | disable 면 SSL 미사용. 없으면 localhost 외 주소에 SSL(검증 완화)을 쓴다. |
DB_POOL_MAX | 선택(기본 5) | Postgres | 커넥션 풀 상한. |
FILE_STORE_SERVICE_TOKEN | production 필수 | — | 서비스 API 인증(src/server.ts:47). 없으면 production 부팅이 실패한다. 포탈·RagService 와 같은 값. |
FILE_STORE_ADMIN_TOKEN | 선택 | — | 레거시 관리자 토큰(쿠키 세션 외 대체 경로). PortalConsole 의 FileStore 데스크가 이 토큰으로 관리 API 를 호출하므로(PortalConsole/server/fileStore.ts:134) 콘솔과 같은 값으로 두는 것이 보통이다. |
FILE_STORE_ENVELOPE_MASTER_KEY | 사실상 필수 | — | 32바이트 Base64. 백엔드 자격증명·refresh token 을 봉투 암호화(AES-256-GCM)하고 연결 테스트 지문(HMAC)을 만든다. 없거나 저장 당시와 다르면 화면에 credentialsError/키 경고 배너가 뜬다. |
FILE_STORE_PUBLIC_URL | 사실상 필수 | — | OAuth 리디렉션 URI·DirectoryService 콜백·LOCAL_VOLUME URL 발급(src/localObjectUrl.ts:28)·OAuth 저장소 전송(src/oauthObjectStorage.ts:85)의 기준. 없으면 요청 헤더로 계산돼 프록시에 따라 흔들린다. 운영에서는 https, 끝 슬래시 없이. |
FILE_STORE_ALLOWED_ORIGINS | 선택(기본 꺼짐) | — | 브라우저가 서명 URL(local-objects/local-uploads)을 직접 내려받도록 허용할 소비 포탈 origin 목록(쉼표 구분, src/corsHeaders.ts). 비면 CORS 헤더를 전혀 내지 않는다 — 소비 포탈은 자기 서버에서 원본을 중계하므로 기본값으로 충분하다. 켜도 *·Access-Control-Allow-Credentials 는 쓰지 않는다(정확한 origin 에코 + Vary: Origin, 쿠키 미전송). |
PORTAL_CONSOLE_URL | 콘솔 연동 시 필수 | — | 소비 포털 목록 조회·R2 자격증명 전달(src/directoryServiceSync.ts). production 에서는 https 여야 한다(아니면 목록이 configured:false 로 저하). |
PORTAL_CONSOLE_SYNC_TOKEN | 위와 함께 | — | 임의의 랜덤 문자열. 콘솔의 FILE_STORE_SYNC_TOKEN 과 완전히 같은 값. |
PORTAL_JWT_SECRET (또는 JWT_SECRET) | DirectoryService 로그인 시 필수 | — | 포탈 SSO 토큰 검증(src/directoryAuth.ts). 콘솔과 같은 값. 두 이름을 함께 두고 값이 다르면 세션 검증이 실패한다. |
FILE_STORE_ADMIN_USERNAME · FILE_STORE_ADMIN_PASSWORD | 최초 부트스트랩만 | 파일 | 관리자 계정이 아직 없을 때만 사용한다(src/adminAuth.ts:41,52). 계정이 있으면 매 부팅 때 읽지 않는다. |
FILE_STORE_ADMIN_AUTH_PATH | 파일 모드 | 파일 | 관리자 계정 파일 경로. DATABASE_URL 이 있으면 무시된다(src/server.ts:146 — 계정은 file_store_admin_accounts). |
FILE_STORE_CONFIG_PATH | 파일 모드 | 파일 | backend·정책 metadata 파일 경로. DATABASE_URL 이 있으면 무시된다(설정은 DB). /healthz 의 configurationPath 표시에만 이름이 쓰인다. |
FILE_STORE_BOOTSTRAP_CONFIG | 선택 | 파일 | 파일 모드 최초 부팅 시 metadata seed. |
FILE_STORE_KAFKA_BROKERS | 선택 | — | Data Feed Kafka sink 의 기본 브로커 목록. |
FILE_STORE_CLIENT_ID · FILE_STORE_PORTAL_ID | 선택 | — | DirectoryService SSO 클라이언트/포털 식별자. 기본값 file-store. |
PORT | 선택(기본 8080) | — | Dockerfile/compose 가 이미 설정한다. |
NODE_ENV | 선택 | — | 이미지가 NODE_ENV=production 을 넣는다. 이 값이 production 이어야 토큰 필수 검사·PORTAL_CONSOLE_URL https 규칙이 적용된다. |
블록에는 값이 아니라 이름만 넣는다. 자격증명(Access Key·Secret·Client Secret)은 관리자 화면에서 입력해 백엔드별로 봉투 암호화 저장하는 것이 기본이고,
secretRef기반 env 는 단일 백엔드 배포를 위한 대체 경로다.
2. 모드에 따라 무시되는 변수 (DATABASE_URL 유무)
| 변수 | DATABASE_URL 있음(Postgres) | 없음(파일) |
|---|---|---|
FILE_STORE_CONFIG_PATH | 무시 — 설정은 DB 테이블 | 사용 — <경로> + .oauth.json·.backend-credentials.json·.backend-checks.json·.feed-cursors.json·.assets.json 파생 |
FILE_STORE_ADMIN_AUTH_PATH | 무시 — 계정은 DB 테이블 | 사용 |
FILE_STORE_BOOTSTRAP_CONFIG | 무시 | 최초 부팅 시 사용 |
즉 Postgres 배포에서는 위 세 개가 죽은 변수이고, 파일 배포에서는 반드시 영속 볼륨 위 경로여야 한다(컨테이너 재생성 시 설정·계정이 사라진다).
3. FileStore 에 두면 죽은 변수 (다른 서비스 소유)
| 변수 | 실제로 읽는 서비스 | 비고 |
|---|---|---|
FILE_STORE_SYNC_TOKEN | PortalConsole | 콘솔이 FileStore 요청을 받을 때 검사하는 토큰(PortalConsole/server/fileStoreRoutes.ts:27). FileStore 쪽 대응 이름은 PORTAL_CONSOLE_SYNC_TOKEN. |
FILE_STORE_BASE_URL | PortalConsole | 콘솔 → FileStore 호출 주소. |
DATABASE_DIALECT | PortalConsole · UiPlatform | FileStore 코드는 읽지 않는다(.env.example 에만 남아 있다). |
PORTAL_CONSOLE_DOC_LIBRARY_PROVIDER · PORTAL_CONSOLE_DOC_LIBRARY_PATH(..._HOST_PATH 는 compose 전용) | PortalConsole | 문서 보관함. |
PORTAL_CONSOLE_LIBRARY_PUBLISH_TOKEN | PortalConsole | 문서 발행. |
PORTAL_EXPLORE_CATALOG_JSON · PORTAL_CONSOLE_REGISTRATION_TOKEN · PORTAL_CONSOLE_TOKEN_CONSUMERS_JSON · PORTAL_ALLOW_INSECURE_PLATFORM_URL | PortalConsole | 포털·플랫폼 연동. |
MODEL_GATEWAY_URL · MODEL_GATEWAY_ADMIN_TOKEN | GuideCenter · DocumentLibrary · RagService · ModelGateway | FileStore 는 ModelGateway 를 호출하지 않는다. |
DIRECTORY_* 레거시 이름 | 별칭 모듈이 새 이름으로 복사 | src/envAliases.ts 가 부팅 때 매핑하고 [env-aliases] … 경고를 남긴다. 그중 DIRECTORY_ENVELOPE_MASTER_KEY 는 콘솔 키로 매핑되므로 FileStore 에 넣어도 효과가 없다. |
4. 서비스 간 값 일치 (틀리면 401·로그인 실패)
| 값 | FileStore 쪽 이름 | 상대 |
|---|---|---|
| 내부 동기화 토큰 | PORTAL_CONSOLE_SYNC_TOKEN | PortalConsole 의 FILE_STORE_SYNC_TOKEN |
| 서비스 API 토큰 | FILE_STORE_SERVICE_TOKEN | 포털·RagService·콘솔이 보내는 값 |
| 관리자(레거시) 토큰 | FILE_STORE_ADMIN_TOKEN | PortalConsole 이 FileStore 관리 API 를 부를 때 쓰는 값 |
| SSO 서명 키 | PORTAL_JWT_SECRET(또는 JWT_SECRET) | PortalConsole 의 PORTAL_JWT_SECRET |
| 봉투 암호화 키 | FILE_STORE_ENVELOPE_MASTER_KEY | FileStore 인스턴스끼리(레플리카·워커) 동일해야 한다. 콘솔의 PORTAL_CONSOLE_ENVELOPE_MASTER_KEY 와는 무관하며, 값을 바꾸면 기존 자격증명·refresh token 은 복호화되지 않는다(재입력 필요). |
토큰은 timingSafeEqual 로 비교하므로 앞뒤 공백(양쪽 trim 은 함) 외에 대소문자·길이까지 같아야 한다. 생성은 openssl rand -hex 32 처럼 + / = 가 없는 hex 를 권장한다.
5. 정리 절차
- 빠진 필수값 추가:
FILE_STORE_PUBLIC_URL=https://<공개주소>→ 재배포 →저장소 → OAuth 백엔드 수정모달의 리디렉션 URI 가 그 주소 기준으로 바뀌는지 확인 → 공급자 콘솔(구글·Azure)에 그 주소를 등록. - 대체 경로 삭제 전 확인:
{secretRef}_ACCESS_KEY_ID·{secretRef}_SECRET_ACCESS_KEY(예:R2_PORTAL_*)는 그 백엔드가 화면 자격증명을 쓰는지에 달렸다. 저장소 탭에서자격증명 설정됨이면 삭제해도 되고,자격증명 미설정이면 삭제 금지(그 순간부터 업로드 실패). - 죽은 변수 제거:
DATABASE_DIALECT, Postgres 모드에서 무시되는FILE_STORE_CONFIG_PATH·FILE_STORE_ADMIN_AUTH_PATH, 그리고 §3 의 다른 서비스 변수. - 부트스트랩 자격 정리:
FILE_STORE_ADMIN_USERNAME·FILE_STORE_ADMIN_PASSWORD는 계정이 생긴 뒤에는 쓰이지 않는다. 다만 계정 저장소(파일 볼륨 또는 DB)를 잃으면 다시 필요하고, 그 상태에서 production 이면 부팅이 실패한다("최초 관리자 계정을 만들려면 FILE_STORE_ADMIN_PASSWORD가 필요합니다") — 지우려면 계정 저장소 백업을 확보한다. - 재배포 후 확인(§6)하고, 이상이 없으면 상대 서비스에서도 같은 방식으로 §3 변수를 정리한다.
6. 확인 체크리스트
- 부팅 로그: 기동 성공,
[env-aliases] …경고 없음(있으면 옛 이름이 남아 있다는 뜻). GET /healthz→"persistence":"postgresql"(공유 DB 배포 기준).저장소탭: 상단에 봉투 암호화 키 경고 배너 없음, 행에자격증명 확인 불가없음.연결 테스트1회 통과 · 파일 업로드 1회 ·소비 포털등록 모달에 ID 선택지 표시.- OAuth 백엔드 모달의 리디렉션 URI 가
FILE_STORE_PUBLIC_URL기준으로 표시.
7. 진단 명령
bash
# 서비스 상태·영속성·backend 수
curl -s https://<filestore>/healthz
# 백엔드·자격증명 상태(envelopeKeyConfigured, credentialsError 포함)
curl -s -H "x-filestore-admin-token: $FILE_STORE_ADMIN_TOKEN" \
https://<filestore>/api/file-store/v1/admin/configuration
# 소비 포털 목록(configured:false + reason 이면 PORTAL_CONSOLE_* 문제)
curl -s -H "x-filestore-admin-token: $FILE_STORE_ADMIN_TOKEN" \
https://<filestore>/api/file-store/v1/admin/portal-directory
# 콘솔 원본 — 200 이면 토큰 일치, 401 이면 불일치
curl -s -o /dev/null -w '%{http_code}\n' -H "Authorization: Bearer $FILE_STORE_SYNC_TOKEN" \
https://<portal-console>/api/internal/file-store/v1/portals