production/staging 환경 분리 런북 — Phase 0 콘솔 준비
2026-09-09 적용 기준: 새 브랜치 매핑은 main=Production, staging=staging이며 릴리스 프로세스가 전환 정본이다. 기존 Supabase 두 프로젝트·secret을 유지하고
DEPLOYMENT_BRANCH_CUTOVER=true활성화와 실제 배포를 별도로 확인한다. 아래 main=staging / production=운영 및 DB 재베이스라인 단계는 2026-08-21 초기 환경 구축의 이력이다. 이번 브랜치 연결 변경의 실행 절차로 사용하지 않으며 데이터 초기화를 반복하지 않는다. 현재도 지킬 프로젝트 링크·데이터 보존 원칙은 유지한다.
main 푸시가 곧 Production인 현재 구조를 main = staging / production 브랜치 = Production으로 나누고, 릴리스를 main → production PR 한 건으로 만드는 트랙의 Phase 0(콘솔 준비) 실행 런북이다. 설계·선택지·결정 근거는 설계서(artifact c0b783a6, v1.2)에 있고, 이 문서는 오너가 콘솔에서 할 일과 그 완료 확인법만 순서대로 적는다.
역할 표기: [오너] = Vercel·Supabase·Kakao·GitHub 콘솔 권한이 필요해 오너가 직접 실행, [세션] = Claude 세션이 실행하고 검증.
확정된 결정 (2026-08-21)
| # | 결정 | 값 |
|---|---|---|
| D1 | 릴리스 트리거 | main → production PR 머지. production 머지는 반드시 오너 승인 — 세션은 release PR을 열 수만 있고 머지하지 않는다 |
| D2 | Production 마이그레이션 적용 | release 워크플로가 자동 적용. 단 staging-applied 게이트: release diff의 모든 마이그레이션이 staging 장부에 이미 적용돼 있어야 진행 |
| D3 | staging Supabase | 기존 프로젝트 ajqddlglezvxzsawquku (Pro, MICRO) 사용 |
| D4 | staging 접속 주소 | Vercel 자동 도메인. DNS 작업 없음 |
| D5 | Production 직접 push | 금지. Production은 release 워크플로만 만진다 (전환 시점은 HQ가 전 트랙에 방송) |
| D6 | PR 프리뷰가 보는 DB | staging |
| D7 | staging 기존 데이터 | 폐기 가능 → 재베이스라인 |
링크 규칙 (모든 단계에 우선)
Supabase CLI의 link는 체크아웃별로 supabase/.temp/project-ref에 저장된다. 본체 체크아웃(D:\LiftGuild-2026\Claude\lift-guild)은 Production에 링크돼 있고 다른 트랙들이 거기서 Production push를 한다. 따라서:
- staging에 대한
link·db reset·db push·migration list는 전용 작업 폴더D:\LiftGuild-2026\Claude\lift-guild-staging-ops에서만 한다(세션이 만들어 둔 git worktree,main추적). 본체 체크아웃의 링크는 바꾸지 않는다. - staging·Production 어느 쪽이든 DB를 건드리는 명령 직전에 아래 한 줄로 링크를 눈으로 확인한다. 출력이 기대한 ref가 아니면 멈춘다.
cat supabase/.temp/project-ref순서 게이트
Phase 0-1 [오너] Vercel: Custom Environment "staging" + staging 환경변수 + 토큰·ID 수집
Phase 0-2 [오너] Supabase staging: DB 비밀번호 · Auth URL · Kakao provider
Phase 0-3 [오너] Kakao 개발자 콘솔: staging 콜백 URI 추가
Phase 0-4 [오너] staging DB 재베이스라인 (전용 폴더에서 link → reset) → [세션] remote-schema 게이트
Phase 0-5 [오너] GitHub: Actions secrets · Environment "production" 가능 여부 확인
Phase 0-6 [오너] Vercel Preview 환경변수 = staging · staging 테스트 계정 → [세션] 프리뷰 실측0-4는 0-2의 비밀번호가 있어야 하고, 0-6은 0-4가 끝난 뒤여야 한다(재베이스라인 전에 프리뷰를 staging으로 돌리면 프리뷰 로그인이 깨진다). 나머지는 순서를 바꿔도 된다.
완주 판정 = 0-4의 check:remote-schema EXIT 0 그리고 0-6에서 프리뷰가 staging을 보는 것을 오너가 확인.
공통 값
| 항목 | 값 |
|---|---|
| Production Supabase | ref kobxeylancdimqhfkbnl · https://kobxeylancdimqhfkbnl.supabase.co |
| staging Supabase | ref ajqddlglezvxzsawquku · https://ajqddlglezvxzsawquku.supabase.co |
| staging OAuth callback (Kakao 등 외부 provider에 등록할 redirect URI) | https://ajqddlglezvxzsawquku.supabase.co/auth/v1/callback |
| staging 접속 주소 | Vercel이 주는 자동 도메인 — 0-1에서 확인해 아래 표의 빈칸에 기록 |
| staging 전용 작업 폴더 | D:\LiftGuild-2026\Claude\lift-guild-staging-ops |
| 브랜치 | main = staging, production = Production (production 브랜치는 Phase 3 전환 창에 만든다) |
기록란(오너가 채움): staging 자동 도메인 = ________________________
Phase 0-1 — Vercel [오너]
Vercel 대시보드 → 프로젝트 barbelic(앱. barbelic-docs가 아님).
- [ ] Custom Environment 생성: Settings → Environments → Create Environment → 이름
staging. Branch tracking은 아직 비워 둔다 —main은 Phase 3 전환 창까지 Production 브랜치여야 하므로, 그때main을 staging 환경에 붙인다. 완료 확인: Environments 목록에 Production / Preview / staging 세 줄. - [ ] staging 환경변수(환경 = staging 하나만 체크): -
VITE_SUPABASE_URL=https://ajqddlglezvxzsawquku.supabase.co-VITE_SUPABASE_PUBLISHABLE_KEY= staging 프로젝트의 publishable key (Supabase staging → Project Settings → API Keys) -SUPABASE_URL= 위와 같은 URL,SUPABASE_PUBLISHABLE_KEY= 위와 같은 키 (api/서버리스가 읽음) -SUPABASE_SERVICE_ROLE_KEY= staging의 service role key —api/admin기능을 staging에서 쓸 때만. 모르면 비워 둔다. Production 환경에는 아무것도 넣지 않아도 된다. production 대상 빌드는deployment-targets.json의 Production 값을 쓰고, 넣는다면 같은 값이어야 빌드가 통과한다. staging 환경에서 이 두 변수를 빠뜨리면 빌드가 실패한다 — 값이 없다고 Production을 바라보게 두지 않는다(이슈 #1332, 빌드·배포 대상 표). - [ ] Deployment Protection 확인: Settings → Deployment Protection. Pro는 Preview· 커스텀 환경에 "Vercel Authentication"이 기본으로 걸려 있을 수 있다. 팀원만 볼 거면 그대로, 외부 테스터에게 열 거면 staging 환경(또는 Preview)의 보호를 끈다. 완료 확인은 0-6에서 로그아웃한 브라우저로 staging 주소를 열어 본다.
- [ ] 토큰·ID 수집(0-5의 GitHub secrets 재료. 비밀 관리자에 보관): -
VERCEL_TOKEN: Account Settings → Tokens → Create. 이름github-actions-deploy, 범위는 이 계정/팀, 만료는 1년. -VERCEL_PROJECT_ID: 프로젝트 Settings → General → Project ID. -VERCEL_ORG_ID: 팀이면 Team Settings → General → Team ID, 개인 계정이면 Account Settings → General의 User ID. - [ ] staging 자동 도메인을 위 기록란에 적는다(Environments → staging → Domains에 보이는
*.vercel.app. 아직 배포가 없으면 Phase 2 첫 배포 뒤에 기록).
Phase 0-2 — Supabase staging [오너]
Supabase 대시보드 → 프로젝트 Barbelic Staging(URL에 ajqddlglezvxzsawquku가 보이는지 확인. Production 프로젝트에서 아래를 하면 안 된다).
- [ ] DB 비밀번호: Project Settings → Database → Database password → Reset. 새 값을 비밀 관리자에 보관. 0-4의
link와 0-5의 secret에 쓴다. (Production 비밀번호는 건드리지 않는다.) - [ ] Auth URL: Authentication → URL Configuration. - Site URL = staging 자동 도메인(0-1 기록란). 아직 없으면
http://127.0.0.1:5173으로 두고 Phase 2 뒤에 바꾼다. - Redirect URLs에 추가:https://<staging 자동 도메인>/**·http://127.0.0.1:5173/**·barbelic://auth/callback**· (PR 프리뷰 로그인까지 허용하려면)https://*-<vercel 팀 슬러그>.vercel.app/** - [ ] Kakao provider: Authentication → Providers → Kakao → Enable. REST API Key와 Client Secret은 Production 프로젝트의 Kakao provider 화면에 있는 값을 그대로 복사한다(같은 Kakao 앱을 공유). 저장 뒤 화면에 보이는 Callback URL이 공통 값 표의 staging OAuth callback과 같은지 확인.
- [ ] (소셜 트랙이 Apple·Google을 Production에 켤 때 staging도 같은 화면에서 같이 켠다 — 지금은 하지 않는다.)
Phase 0-3 — Kakao 개발자 콘솔 [오너]
- [ ] 내 애플리케이션 → Barbelic 앱 → 카카오 로그인 → Redirect URI → 추가:
https://ajqddlglezvxzsawquku.supabase.co/auth/v1/callback. 기존 Production URI는 그대로 둔다. 완료 확인: Redirect URI 목록에 Production·staging 두 줄.
Phase 0-4 — staging DB 재베이스라인 [오너 실행 → 세션 검증]
staging 프로젝트의 마이그레이션 장부는 2026-07-24 exercise_uuid_identity_cutover 에서 멈춰 있다(베이스라인 v2 스쿼시 이전 역사). 현재 레포는 20260821000000_baseline_v2부터 시작하는 한 벌이라 그대로 db push하면 맞지 않는다. D7(데이터 폐기 가능)에 따라 비우고 처음부터 적용한다. HQ 실측(08-21)으로 이 프로젝트에 장부를 밀던 트랙은 없다.
전용 작업 폴더에서만 실행한다. 세션이 미리 만들어 둔다(git worktree, main 추적, node_modules는 본체로 junction). 없으면 세션에 요청.
cd D:\LiftGuild-2026\Claude\lift-guild-staging-ops
git pull --ff-only origin main- [ ] 링크(비밀번호 프롬프트에 0-2의 새 값):
bash npx supabase@latest link --project-ref ajqddlglezvxzsawquku cat supabase/.temp/project-ref완료 확인: 출력이ajqddlglezvxzsawquku. 다른 값이면 멈춘다. - [ ] 현재 장부 확인(이게 staging이라는 두 번째 증거):
bash npx supabase@latest migration list --linked완료 확인: Remote 열이 07-24 이전 버전들로만 차 있고20260821000000이 없다. 만약20260821…버전이 이미 보이면 Production이거나 누가 먼저 밀었다는 뜻 — 멈추고 세션에 알린다. - [ ] 리셋 + 전체 적용(staging의 데이터·스키마를 전부 지우고 로컬 마이그레이션을 처음부터 적용한다. 되돌릴 수 없으니 위 두 확인 뒤에만):
bash npx supabase@latest db reset --linkedCLI가 프로젝트 ref 입력으로 재확인을 요구하면ajqddlglezvxzsawquku를 입력. - [ ] 적용 결과 확인:
bash npx supabase@latest migration list --linked완료 확인: Local과 Remote 열이 같고, 마지막 줄이 레포의 가장 최신 마이그레이션 (ls supabase/migrations | tail -1의 타임스탬프)이다. - [ ] 세션에 "재베이스라인 완료"라고 알린다.
[세션] 전용 폴더에서 npm run check:remote-schema → EXIT 0(장부 전량 적용·이름 충돌 없음·RPC 계약 일치)을 HQ와 오너에게 보고한다. 이 게이트는 Management API를 쓰므로 세션이 비밀번호를 알 필요가 없다.
Phase 0-5 — GitHub [오너]
저장소 dekerd/Barbelic → Settings.
[ ] Actions secrets(Secrets and variables → Actions → New repository secret):
| 이름 | 값 | 출처 | |---|---|---| | `SUPABASE_ACCESS_TOKEN` | 개인 액세스 토큰 | Supabase → Account → Access Tokens → Generate(이름 `github-actions`) | | `STAGING_SUPABASE_PROJECT_REF` | `ajqddlglezvxzsawquku` | 공통 값 | | `STAGING_SUPABASE_DB_PASSWORD` | 0-2에서 만든 값 | 비밀 관리자 | | `STAGING_SUPABASE_ANON_KEY` | staging publishable key (0-1의 `VITE_SUPABASE_PUBLISHABLE_KEY`와 같은 값) | Supabase staging → Project Settings → API Keys | | `PROD_SUPABASE_PROJECT_REF` | `kobxeylancdimqhfkbnl` | 공통 값 | | `VERCEL_TOKEN` · `VERCEL_ORG_ID` · `VERCEL_PROJECT_ID` | 0-1에서 수집 | 비밀 관리자 | | `STAGING_SMOKE_EMAIL` · `STAGING_SMOKE_PASSWORD` | 0-6에서 만든 계정 | 0-6 뒤에 추가 | | `PROD_SUPABASE_URL` | `https://kobxeylancdimqhfkbnl.supabase.co` | 공통 값 (기존 prod-smoke 몫으로 이미 있으면 그대로) | | `PROD_SUPABASE_ANON_KEY` | Production publishable key | Supabase Production → Project Settings → API Keys (기존재 시 그대로) | | `PROD_SMOKE_EMAIL` · `PROD_SMOKE_PASSWORD` | Production 스모크 계정 | 기존 prod-smoke 몫으로 이미 있으면 그대로 | `PROD_SUPABASE_DB_PASSWORD`는 **Phase 3 전환 창에** 넣는다. 모르는 값이면 그때 재설정하는데, 재설정은 그 비밀번호를 쓰는 모든 곳(각 체크아웃의 저장된 자격증명)에 영향을 주므로 HQ가 전환 창을 잡은 뒤에만 한다. 이미 쓰는 값이 있으면 그걸 쓴다. service role key는 워크플로에 필요 없다.[ ] Environment "production" 가능 여부 확인: Settings → Environments. 새 환경을 만들 수 있고 "Required reviewers" 항목이 보이면(GitHub Pro/Team) 환경
production을 만들고 Required reviewers에 오너 본인을 넣는다 — release 워크플로의 Production 잡이 여기서 멈춰 오너의 "Approve and deploy" 클릭을 기다리게 된다(D1 "오너 승인"의 기계적 보장). 메뉴가 없으면(Free 플랜 private 레포) 세션에 "Environments 없음"이라고 알린다 — 그러면 D1은 "세션은 release PR을 열기만, 머지는 오너만" 운영 규칙 +production브랜치 ruleset(PR 필수·직접 푸시 금지)으로 대체한다.[ ] (Phase 3 전환 창에 할 일, 미리 만들어도 무방) Rules → Rulesets → New branch ruleset: 대상
production, 규칙 = Require a pull request before merging · Block force pushes · Restrict deletions · Require status checks(verify).
Phase 0-6 — 프리뷰를 staging으로 [오너 → 세션 실측]
0-4가 끝난 뒤에만.
- [ ] staging 테스트 계정: Supabase staging → Authentication → Users → Add user → 이메일/비밀번호(자동 확인 체크). 값을 0-5의
STAGING_SMOKE_EMAIL/PASSWORDsecret으로 등록. 오너 본인 리뷰용 계정도 같은 방법으로 하나 더(Production 이메일과 구분되게+staging별칭 권장). - [ ] Vercel Preview 환경변수: 0-1의 staging 변수 다섯 개를 환경 = Preview에도 같은 값으로 추가한다. 이 순간부터 새로 만들어지는 모든 PR 프리뷰(디자인 딜리버리
claude/ui-*포함)는 staging을 본다. Production 환경은 여전히 비워 둔다. - [ ] 세션에 "Preview 변수 설정 완료"라고 알린다.
[세션] Vercel 프리뷰가 붙는 브랜치(예: claude/ui-*)에 빈 커밋을 올려 프리뷰를 만들고, 프리뷰 URL을 오너에게 전달한다. [오너] 그 프리뷰를 열어 로그인 → 기록이 비어 있고 (Production 기록이 보이지 않고) 브라우저 개발자 도구 Network 탭의 요청 호스트가 ajqddlglezvxzsawquku.supabase.co이면 성공. 세션은 결과를 HQ에 보고하고 Phase 0을 닫는다.
Phase 2~3 전환 창에 할 콘솔 작업 (예고)
HQ가 다른 트랙의 Production 마이그레이션 랜딩이 끝난 창을 통보하면, 아래를 한 번에 한다. 이 문서의 후속 개정에서 체크리스트로 확장한다.
- [오너]
deploy.yml+vercel.json두 줄 + 문서 PR(세션이 draft로 준비해 둠)을 머지한다. 이 순간부터main머지는 staging으로 간다(Vercel git 통합의 main 빌드는 멈춤). - [오너] Vercel → Settings → Git → Production Branch를
production으로. Settings → Environments → staging의 Branch tracking을main으로. - [오너] GitHub ruleset(0-5의 예고 항목)과
PROD_SUPABASE_DB_PASSWORDsecret. - [세션]
production브랜치 생성 = 그 시점의main(git push origin main:production). 브랜치 생성 푸시는 deploy.yml을 돌리지 않는다. - [오너] Actions → Deploy → Run workflow → branch
production, environmentproduction. 코드 변경 없는 첫 Production 실행이자 유일한 Production 접촉이고, 이 클릭이 오너의 명시 승인이다. 전 단계 초록(dry-run "up to date" · remote-schema · 함수 프로브 · Vercel 배포 · smoke)을 세션이 확인해 보고한다.
이 시점부터 D5가 발효된다: 본체 체크아웃에서의 db push --linked는 금지되고, 각 트랙은 main 머지(= staging 자동 반영)로 바뀐다. HQ가 전 트랙에 방송한다.