Skip to content

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을 열 수만 있고 머지하지 않는다
D2Production 마이그레이션 적용release 워크플로가 자동 적용. 단 staging-applied 게이트: release diff의 모든 마이그레이션이 staging 장부에 이미 적용돼 있어야 진행
D3staging Supabase기존 프로젝트 ajqddlglezvxzsawquku (Pro, MICRO) 사용
D4staging 접속 주소Vercel 자동 도메인. DNS 작업 없음
D5Production 직접 push금지. Production은 release 워크플로만 만진다 (전환 시점은 HQ가 전 트랙에 방송)
D6PR 프리뷰가 보는 DBstaging
D7staging 기존 데이터폐기 가능 → 재베이스라인

링크 규칙 (모든 단계에 우선)

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가 아니면 멈춘다.
bash
cat supabase/.temp/project-ref

순서 게이트

txt
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 Supabaseref kobxeylancdimqhfkbnl · https://kobxeylancdimqhfkbnl.supabase.co
staging Supabaseref 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). 없으면 세션에 요청.

bash
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 --linked CLI가 프로젝트 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/PASSWORD secret으로 등록. 오너 본인 리뷰용 계정도 같은 방법으로 하나 더(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 마이그레이션 랜딩이 끝난 창을 통보하면, 아래를 한 번에 한다. 이 문서의 후속 개정에서 체크리스트로 확장한다.

  1. [오너] deploy.yml + vercel.json 두 줄 + 문서 PR(세션이 draft로 준비해 둠)을 머지한다. 이 순간부터 main 머지는 staging으로 간다(Vercel git 통합의 main 빌드는 멈춤).
  2. [오너] Vercel → Settings → Git → Production Branch를 production으로. Settings → Environments → staging의 Branch tracking을 main으로.
  3. [오너] GitHub ruleset(0-5의 예고 항목)과 PROD_SUPABASE_DB_PASSWORD secret.
  4. [세션] production 브랜치 생성 = 그 시점의 main (git push origin main:production). 브랜치 생성 푸시는 deploy.yml을 돌리지 않는다.
  5. [오너] Actions → Deploy → Run workflow → branch production, environment production. 코드 변경 없는 첫 Production 실행이자 유일한 Production 접촉이고, 이 클릭이 오너의 명시 승인이다. 전 단계 초록(dry-run "up to date" · remote-schema · 함수 프로브 · Vercel 배포 · smoke)을 세션이 확인해 보고한다.

이 시점부터 D5가 발효된다: 본체 체크아웃에서의 db push --linked는 금지되고, 각 트랙은 main 머지(= staging 자동 반영)로 바뀐다. HQ가 전 트랙에 방송한다.