app-configの階層とマージ結果の予測
한국어 원문으로 표시합니다.
목표
Backstage 설정을 여러 장으로 나누어 쓰고, 그 장들이 겹쳤을 때 무엇이 남는지를 손으로 예측해 봅니다. 마지막에는 운영 설정을 쿠버네티스 오브젝트로 옮겨 실제 배포에서 값이 어디서 오는지를 확인합니다.
왜 중요한가
설정 계층은 CBA 에서 가장 자주 틀리는 자리입니다. 규칙 자체는 두 줄인데 결과가 직관과 어긋나기 때문입니다. 매핑은 키 단위로 깊게 합쳐지지만 리스트는 합쳐지지 않고 통째로 교체됩니다. 기본 파일에 카탈로그 진입점을 세 건 적어 두고 오버라이드에 한 건만 적으면, 결과는 네 건이 아니라 한 건이고 아무 경고도 나오지 않습니다. 값의 종류가 바뀔 때도 마찬가지입니다. 문자열이던 자리에 매핑이 오면 문자열은 사라집니다. 그리고 자격증명은 어느 파일에도 값으로 적으면 안 됩니다. 설정 파일은 저장소에 커밋되고 이미지에 구워지기 때문입니다. Backstage 자체는 이 환경에 없으므로 채점은 파일과 클러스터 오브젝트를 읽어서 합니다.
단계
/root/cba-config/app-config.yaml에 기본 설정을 쓰세요 —app.title아무 값,app.baseUrl: http://localhost:3000,organization.name아무 값,backend.baseUrl: http://localhost:7007,backend.listen.port: 7007,backend.cors.origin: http://localhost:3000,backend.database.client: better-sqlite3,backend.database.connection: /tmp/portal.sqlite.- 같은 파일에 통합과 프록시를 이어 쓰세요 —
integrations.github첫 항목의host: github.com과token(GITHUB 이 들어간 환경변수 치환 형식),proxy.endpoints아래/argocd/api키에target(https 로 시작하는 주소),changeOrigin: true,headers.Cookie(환경변수 치환 형식). - 같은 파일에 카탈로그 설정을 이어 쓰세요 —
catalog.import.entityFilename: catalog-info.yaml,catalog.rules첫 항목의allow에 Component, API, Resource, System, Domain, Group, User, Location, Template 아홉 종류,catalog.locations두 건(첫째는type: file이고 target 이entities.yaml로 끝남, 둘째는type: url이고 target 이 github.com 주소),catalog.providers.github.labhubOrg에organization: labhub,catalogPath: /catalog-info.yaml,schedule.frequency.minutes: 30,schedule.timeout.minutes: 3. /root/cba-config/app-config.local.yaml에 오버라이드를 쓰세요 —app.baseUrl: http://portal.labhub.test,backend.baseUrl: http://portal.labhub.test:7007,backend.database.client: pg,backend.database.connection아래host·port·user·database를 전부 환경변수 치환 형식으로,catalog.locations는type: url한 건만.backend.listen.port는 적지 마세요./root/cba-config/merged.yaml에 1~3 단계의 파일 위에 4 단계 파일을 겹쳤을 때 남는 값을 그대로 쓰세요. 매핑은 깊게 합쳐지고 리스트는 통째로 교체됩니다./root/cba-config/app-config.production.yaml에 운영 설정을 쓰세요 —app.baseUrl과backend.baseUrl둘 다https://portal.labhub.io,backend.listen.host: 0.0.0.0,backend.database.client: pg,auth.environment: production,auth.providers.github.production의clientId와clientSecret은 환경변수 치환 형식, 같은 자리의signIn.resolvers첫 항목resolver는 카탈로그 User 엔티티에 맞추는 리졸버 이름,techdocs.builder: external,techdocs.publisher.type은 local 이 아닌 외부 저장소 종류./root/cba-config/env-names.txt에 세 설정 파일이 참조하는 환경변수 이름을 중괄호 없이 한 줄에 하나씩, 중복 없이 정렬해 적으세요.- 운영 설정을 클러스터에 올리세요. 네임스페이스
cba-config를 만들고, 그 안에 ConfigMapportal-app-config를 6 단계 파일에서 만드세요(키 이름이app-config.production.yaml이 되어야 합니다). 그리고 Deploymentportal을 만드세요 — 이미지node:22-alpine,containerPort: 7007, 그 ConfigMap 을 볼륨으로 물리고, 환경변수APP_CONFIG_app_baseUrl의 값이 6 단계 파일의app.baseUrl과 정확히 같아야 합니다.
참고
- 병합 규칙은 두 줄입니다. 매핑은 키 단위로 깊게, 리스트는 통째로 교체입니다.
- 환경변수 치환은
${NAME}형식이고, 이 형식으로 쓰면 값이 파일에 남지 않습니다. - 흔한 실수 1: 오버라이드에 바꾸지 않을 값까지 복사해 두는 것. 기본 파일이 움직여도 이쪽만 옛 값으로 남습니다.
- 흔한 실수 2: 리스트가 합쳐질 것이라 기대하는 것. 기본 파일의 나머지 항목은 조용히 사라집니다.
- 흔한 실수 3:
backend.listen.host를 기본값으로 두고 컨테이너에 올리는 것. 루프백에만 리슨하면 서비스가 파드에 닿지 못합니다.
기본 app-config
/root/cba-config/app-config.yaml 에 기본 설정을 쓰세요 — app.title 아무 값, app.baseUrl: http://localhost:3000, organization.name 아무 값, backend.baseUrl: http://localhost:7007, backend.listen.port: 7007, backend.cors.origin: http://localhost:3000, backend.database.client: better-sqlite3, backend.database.connection: /tmp/portal.sqlite.
프런트엔드와 백엔드는 서로 다른 포트에 뜹니다. CORS 의 origin 은 브라우저가 오는 쪽, 즉 프런트엔드 주소입니다.
통합과 프록시
같은 파일에 통합과 프록시를 이어 쓰세요 — integrations.github 첫 항목의 host: github.com 과 token (GITHUB 이 들어간 환경변수 치환 형식), proxy.endpoints 아래 /argocd/api 키에 target (https 로 시작하는 주소), changeOrigin: true, headers.Cookie (환경변수 치환 형식).
자격증명 자리에 값을 직접 쓰면 그 비밀은 git 이력과 이미지 레이어에 남습니다. 기동할 때 환경변수로 치환되는 형식을 쓰세요.
카탈로그 규칙과 디스커버리
같은 파일에 카탈로그 설정을 이어 쓰세요 — catalog.import.entityFilename: catalog-info.yaml, catalog.rules 첫 항목의 allow 에 Component, API, Resource, System, Domain, Group, User, Location, Template 아홉 종류, catalog.locations 두 건(첫째는 type: file 이고 target 이 entities.yaml 로 끝남, 둘째는 type: url 이고 target 이 github.com 주소), catalog.providers.github.labhubOrg 에 organization: labhub, catalogPath: /catalog-info.yaml, schedule.frequency.minutes: 30, schedule.timeout.minutes: 3.
rules 는 허용 목록이라 여기 없는 kind 는 등록이 거부됩니다. Template 을 빠뜨리면 스캐폴더가 통째로 비어 보입니다.
로컬 오버라이드
/root/cba-config/app-config.local.yaml 에 오버라이드를 쓰세요 — app.baseUrl: http://portal.labhub.test, backend.baseUrl: http://portal.labhub.test:7007, backend.database.client: pg, backend.database.connection 아래 host·port·user·database 를 전부 환경변수 치환 형식으로, catalog.locations 는 type: url 한 건만. backend.listen.port 는 적지 마세요.
오버라이드 파일에는 바꿀 값만 적습니다. 바꾸지 않을 값까지 복사해 두면 기본 파일이 움직였을 때 이쪽만 옛 값으로 남습니다.
병합 결과 예측
/root/cba-config/merged.yaml 에 1~3 단계의 파일 위에 4 단계 파일을 겹쳤을 때 남는 값을 그대로 쓰세요. 매핑은 깊게 합쳐지고 리스트는 통째로 교체됩니다.
매핑은 키 단위로 깊게 합쳐지고 리스트는 통째로 교체됩니다. 오버라이드가 건드리지 않은 키는 기본 파일 값이 그대로 남습니다.
운영 설정
/root/cba-config/app-config.production.yaml 에 운영 설정을 쓰세요 — app.baseUrl 과 backend.baseUrl 둘 다 https://portal.labhub.io, backend.listen.host: 0.0.0.0, backend.database.client: pg, auth.environment: production, auth.providers.github.production 의 clientId 와 clientSecret 은 환경변수 치환 형식, 같은 자리의 signIn.resolvers 첫 항목 resolver 는 카탈로그 User 엔티티에 맞추는 리졸버 이름, techdocs.builder: external, techdocs.publisher.type 은 local 이 아닌 외부 저장소 종류.
컨테이너 안에서 루프백에만 리슨하면 서비스가 파드에 닿지 못합니다. 그리고 인증은 로그인 제공자와 신원 결정 두 단계로 나뉩니다.
환경변수 참조 목록
/root/cba-config/env-names.txt 에 세 설정 파일이 참조하는 환경변수 이름을 중괄호 없이 한 줄에 하나씩, 중복 없이 정렬해 적으세요.
세 설정 파일 전부가 대상입니다. 이 목록이 곧 배포 매니페스트에 채워 넣어야 할 시크릿 키 목록이 됩니다.
설정을 클러스터로
운영 설정을 클러스터에 올리세요. 네임스페이스 cba-config 를 만들고, 그 안에 ConfigMap portal-app-config 를 6 단계 파일에서 만드세요(키 이름이 app-config.production.yaml 이 되어야 합니다). 그리고 Deployment portal 을 만드세요 — 이미지 node:22-alpine, containerPort: 7007, 그 ConfigMap 을 볼륨으로 물리고, 환경변수 APP_CONFIG_app_baseUrl 의 값이 6 단계 파일의 app.baseUrl 과 정확히 같아야 합니다.
ConfigMap 을 파일에서 만들면 파일 이름이 그대로 키가 됩니다. 그리고 설정 경로의 점을 밑줄로 바꾼 이름의 환경변수가 그 한 줄을 덮습니다.