10 KiB
Q&A production 배포 파이프라인
배포 대상과 실행 방식
| 항목 | 운영 값 |
|---|---|
| Workflow | .gitea/workflows/deploy-production.yml |
| Actions 표시 이름 | Deploy EG-BIM QA Production |
| 실행 | Gitea Actions에서 main을 선택해 수동 실행 |
| Worker | baron-qa-gateway-prod |
| Custom Domain | https://qa.baroncs.co.kr |
| Cloudflare account ID | 81fa2d48964d31dd0da9558f9ce601d1 |
| 정적 파일 R2 bucket | baron-qa-write |
| R2 binding 이름 | QA_BUCKET |
| 정적 파일 저장 경로 | releases/<전체 커밋 SHA>/egbim/..., releases/<전체 커밋 SHA>/assets/... |
운영 Worker와 도메인 연결, 버킷 생성은 사용자가 Cloudflare 대시보드에서 완료했다. 실제 Q&A 코드 배포는 이 workflow로 수행한다. main push는 기존 스테이징 workflow를 실행하며, 운영 workflow는 수동 실행만 지원한다. 운영 실행도 main의 선택된 커밋과 checkout 결과가 같아야 진행한다.
배포 파일은 wrangler.production.toml을 사용한다. 운영 세션 쿠키·source namespace는 별도로 지정했고 workers.dev와 preview URL은 비활성화한다. 운영 접속 주소는 qa.baroncs.co.kr이다. 이미 연결한 custom domain은 Cloudflare 대시보드에서 관리한다. Wrangler 설정에는 route와 routes를 지정하지 않아 배포 시 기존 도메인 연결을 유지하며 zone 라우팅을 변경하지 않는다.
Gitea에 등록할 Secrets
저장소 Settings → Actions → Secrets에 등록한다. 기존 기본 Secret이나 STAGING_* 값을 자동으로 가져오지 않는다. 기존 키가 운영 리소스에도 권한이 있다면 값은 재사용할 수 있지만, 아래 운영 설정 이름으로 등록해야 한다. SESSION_SECRET은 운영 전용 값을 사용한다.
| 이름 | 값 |
|---|---|
PROD_CLOUDFLARE_API_TOKEN |
기존 운영 Worker를 배포하고 R2 파일을 업로드할 수 있는 Cloudflare token |
PROD_SESSION_SECRET |
최소 32자 운영 세션 서명키. 예: openssl rand -hex 32로 생성한 값 |
PROD_ABC_API_KEY |
등록 보류: 관리페이지 서버 확정 후 운영 ABC project/channel API key 등록 |
PROD_ORG_CONTEXT_KEY_ID |
운영 조직 컨텍스트 연동 Key ID |
PROD_ORG_CONTEXT_KEY_SECRET |
운영 조직 컨텍스트 연동 Key Secret |
Cloudflare 프로필 API Tokens → Create Token → Create Custom Token에서 운영 배포 token을 생성하거나 기존 token의 권한을 확인한다.
| 범위 | 권한 | 수준 | 용도 |
|---|---|---|---|
| Account / Workers product | Workers | Editor | 기존 Worker 코드·Secret·binding 배포. 레거시 Workers Scripts Edit도 허용 |
| Account | Workers R2 Storage | Edit / Write | 정적 파일을 R2에 업로드 |
| Account | Account Settings | Read | Wrangler 계정 정보 조회 |
Account Resources는 바른기술개발센터 계정으로 지정한다. 생성한 token 값은 PROD_CLOUDFLARE_API_TOKEN Secret에 넣는다. 도메인 연결은 대시보드에서 이미 완료했으므로 운영 배포 token에는 Workers Routes Write와 Zone Read를 요구하지 않는다. 현재 파이프라인은 Wrangler의 Cloudflare REST API를 사용하므로 R2 S3 Access Key ID / Secret Access Key는 필요하지 않다.
R2 권한은 계정 범위의 Workers R2 Storage Write/Edit를 선택한다. R2 → baron-qa-write 범위의 Workers R2 Storage Bucket Item Read/Write는 S3 객체 접근용이므로 현재 Wrangler REST 업로드에 필요한 권한을 대신하지 않는다. 운영 배포에는 Zone Write 정책도 필요하지 않다.
근거: Workers 권한, R2 token 권한, 대시보드에서 route를 관리하는 Wrangler 설정.
Gitea에 등록할 Variables
저장소 Settings → Actions → Variables에 등록한다.
| 이름 | 필수 | 값 |
|---|---|---|
PROD_AUTH_CLIENT_ID |
필수 | 운영 callback URI가 허용된 SSO client ID |
PROD_ABC_API_BASE_URL |
필수 / 등록 보류 | 관리페이지 서버 확정 후 운영 ABC HTTPS origin 등록. /api 경로를 붙이지 않는다. |
PROD_ABC_PROJECT_ID |
필수 / 등록 보류 | 관리페이지 서버 확정 후 운영 ABC project UUID 등록 |
PROD_ABC_CHANNEL_ID |
필수 / 등록 보류 | 관리페이지 서버 확정 후 운영 ABC channel UUID 등록 |
PROD_ORG_CONTEXT_ENABLED |
필수 | true |
PROD_ORG_CONTEXT_TENANT_IDS |
필수 | 기준 tenant UUID JSON 배열. 예: ["tenant-UUID"] |
PROD_ORG_CONTEXT_API_URL |
선택 | 기본 https://sadmin.hmac.kr/api/v1/integrations/org-context |
PROD_ORG_CONTEXT_SCOPE_MODE |
선택 | 기본 SCOPED |
PROD_ORG_CONTEXT_EXPOSURE |
선택 | 기본 identifiers |
PROD_ORG_CONTEXT_CACHE_TTL_SECONDS |
선택 | 기본 300, 허용 범위 1~3600 |
SSO에는 https://qa.baroncs.co.kr/auth/callback을 허용하고, 로그아웃 후 이동 URI로 https://qa.baroncs.co.kr/을 확인한다. 등록된 SSO client나 ABC project/channel이 운영 대상인지 확정한 후 배포한다.
지금 준비할 Variables는 PROD_AUTH_CLIENT_ID와 PROD_ORG_CONTEXT_* 6개다. PROD_AUTH_CLIENT_ID의 참고값은 기존 스테이징 client e16898a7-acd2-420a-a224-cdcd89ff66cd이며, 이 client에 운영 callback이 허용된 경우에만 운영에서도 재사용한다. 별도 운영 client를 만들었다면 그 ID를 등록한다. 기준 tenant UUID와 조직 연동 키는 실제 발급받은 값을 사용한다. 기존 STAGING_* 등록은 PROD_* 등록으로 간주하지 않는다.
회사·부서 조회용 sadmin 조직 컨텍스트 API 설정은 ABC 관리페이지 연동 설정과 별개다. 조직 API 주소·기준 tenant·키의 운영 사용이 확정된 경우 미리 등록할 수 있다. Secret 값이나 테스트 fixture UUID를 실제 설정값으로 문서에 기록하지 않는다.
Worker runtime에는 PROD_를 제거한 이름으로 주입한다. DEPLOY_COMMIT_SHA는 workflow가 선택된 커밋에서 자동으로 전달하므로 Gitea에 따로 등록하지 않는다.
Workflow 순서
- 소스를 checkout하고
main브랜치·커밋 일치를 확인한다. - 운영 필수 설정, UUID, 조직 API 설정과 세션 서명키 길이를 검사한다. 누락 시 배포 전에 중단한다.
npm ci로 고정된 의존성을 설치한다.npm run check와npm test를 실행한다.npm run org:verify로 실제 운영 조직 API의 인증·범위·구성원 응답을 검증한다.npm run deploy:production -- --dry-run으로 Worker 번들을 만든다. 이 단계는 Cloudflare 리소스를 변경하지 않는다.- 해당 커밋의 정적 파일을
baron-qa-write/releases/<SHA>/...에 올린다. npm run deploy:production으로 코드·runtime 변수·Secret을 같은 Worker 배포에 반영한다.npm run production:verify로 익명 세션, CSS 응답·커밋 일치, 비로그인 글쓰기 redirect를 확인한다. 전파 지연에 대비해 최대 5회 확인한다.
Secret 파일은 임시 디렉터리에 접근 권한 0600으로 만들고 배포 명령 종료 후 삭제한다. Secret 값은 CLI 인자나 로그로 출력하지 않는다.
첫 운영 배포 실행
현재 PROD_ABC_API_KEY, PROD_ABC_API_BASE_URL, PROD_ABC_PROJECT_ID, PROD_ABC_CHANNEL_ID 등록은 관리페이지 서버 확정까지 보류한다. 이 값들이 없으면 필수 설정 검증에서 배포를 중단한다. SSO·조직 컨텍스트·Cloudflare·세션 서명키 설정은 먼저 준비할 수 있다.
- 관리페이지 연동
PROD_ABC_*4개를 제외한 운영 Secrets와 Variables 등록을 완료했다. 사용자 보고 기준이며 실제 값·권한 검증은 아직 수행하지 않았다. - 관리페이지 서버 확정 후
PROD_ABC_API_KEY,PROD_ABC_API_BASE_URL,PROD_ABC_PROJECT_ID,PROD_ABC_CHANNEL_ID를 등록한다. - 운영 SSO callback과 관련 변수 등록을 완료했다. 사용자 완료 보고 기준이다.
- ABC project/channel과 조직 API의 실제 접근 권한을 확인한다.
- 이 변경을
main에 반영한다. - Gitea Actions → Deploy EG-BIM QA Production → Run workflow에서
main을 선택한다. - 설정 검증·조직 API 검증·정적 파일 업로드·Worker 배포·HTTP 확인이 모두 성공하는지 확인한다.
- 실제 계정으로 로그인하고 문의·첨부·댓글 기능과 저장된 회사·부서를 확인한다. 자동 HTTP 확인은 로그인 이후의 실제 사용자 작업까지 검증하지 않는다.
실패와 롤백
- 설정·조직 API·빌드 검증 실패는 운영 정적 파일 업로드와 Worker 배포 전에 중단된다.
- 정적 파일 업로드가 실패해도 기존 Worker는 이전 커밋 경로를 계속 읽는다. 다시 실행하면 같은 커밋 경로로 업로드한다.
- Worker 배포 후 HTTP 확인이 실패하면 workflow는 실패로 표시되지만 이미 반영한 배포를 자동으로 되돌리지는 않는다. 마지막 정상 Worker 버전으로 명시적으로 롤백한다.
- Cloudflare의
baron-qa-gateway-prodDeployments에서 마지막 정상 버전으로 rollback하면 해당 버전의QA_ASSET_PREFIX와 정적 파일을 다시 사용한다. 이전 release 경로는 보관한다. - 첫 배포의 이전 버전은 기본 Hello World일 수 있다. 첫 배포 실패 시에는 설정을 수정해 다시 실행하고, 필요하면 기본 버전으로 되돌릴 수 있다.
- R2 release 파일 정리 시 활성 버전과 롤백에 필요한 버전의 prefix를 삭제하지 않는다. 정적 파일 롤백은 ABC에 저장된 문의·댓글 데이터를 되돌리지 않는다.
로컬 확인
npm run check
npm test
node scripts/deploy-production.mjs --validate-only
npm run deploy:production -- --dry-run
마지막 두 명령은 위 runtime 이름의 운영 설정과 DEPLOY_COMMIT_SHA가 실행 환경에 필요하다. --validate-only는 설정 형식만 확인하고, --dry-run은 로컬 번들만 확인한다. 실제 자격증명과 API의 유효성은 Gitea workflow의 조직 API 검증과 실제 배포에서 확인한다.