[DevOps 삽질일지] Vercel Hobby + Private Repo로 모노레포 배포하기

2025. 7. 7. 10:20·devops
728x90
반응형

배경 설명

뜨도록 프로젝트 처음 셋팅 시 프론트 개발자분이 next를 선택하셨고, 익숙하게 vercel hobby플랜에 public repo로 연결하여 배포해주시던 상황이었다.
하지만 프로젝트를 진행하면서 해당 repo를 private으로 돌려야할 일이 발생해 CLI + GitHub Actions 방식으로 갈아타게 되었다.
같은 상황의 소규모 프로젝트(특히 모노레포)에게 도움 되길 바라며 삽질 과정을 남긴다.


Vercel 쪽 준비

현재 프론트쪽은 모노레포 구조에 2개의 프로젝트로 구성되어있다.
각각 따로 배포되어야 하므로 프로젝트를 2개 생성해 진행한다.

할 일 실전 메모
프로젝트 2개 생성 dddorok-web, dddorok-admin (모노레포라 app 디렉터리별 분리)
GitHub 연동 끊기 Settings ▸ Git ▸ Disconnect – 깔끔하게 연결 해제
Personal Token 발급 Profile ▸ Settings ▸ Tokens → VERCEL_TOKEN 으로 GitHub Secret 등록
Root Directory 지정 대시보드 Settings ▸ Build and Deployment
apps/web, apps/admin 입력 후 Include files outside… 토글 ON

토글 ON 을 켜두면 설정한 루트의 바깥쪽 파일, 즉 package.json, pnpm-lock.yaml 등을 같이 가져가 빌드에서 의존성 누락을 방지한다.


Vercel CLI로 프로젝트 연결 & 첫 배포

1. 아직 CLI를 안 깔았다면:

npm i -g vercel

2. 로그인 (한 번만)

vercel login         # 이메일 인증링크 클릭

깃허브 연동 되어있어 github 선택

3. 프로젝트 루트에서 링크

cd <프론트엔드 레포>
vercel link          # 질문 3개:
                     #  ① 어떤 스코프(team/personal)? → 선택
                     #  ② Existing 프로젝트 찾을 건지? → Yes
                     #  ③ 목록에서 dddorok-frontend-web 선택

내경우 팀 선택 후 프로젝트가 보이지 않아 dddorok-web 를 수동으로 입력해 주었다.

.vercel/project.json 에 orgId, projectId 가 자동 저장된다.

4. 로컬에서 첫 배포(선택)

vercel --prod        # 1회 배포해두면 대시보드에 Production 카드 생성

CLI 배포는 내부에서 같은 vercel --prod --token … 명령을 쓰기 때문에,
GitHub Action 이 호출할 로직을 미리 테스트하는 셈.


Gibhub Action & Workflow

Secret 준비

시크릿 이름 값 비고
VERCEL_TOKEN Vercel 대시보드에서 발급한 Personal Token 팀 Owner 계정으로 발급한 토큰을 그대로 사용
VERCEL_ORG_ID .vercel/project.json의 orgId 웹 앱 및 어드민
VERCEL_PROJECT_ID_WEB 같은 파일의 projectId 웹 앱 전용
VERCEL_PROJECT_ID_ADMIN projectId 어드민 전용

두 프로젝트 모두 같은 팀(Org)소속이라 VERCEL_ORG_ID 하나만 등록하였다.
추후 QA → Staging → Prod 등 한 액션에서 여러 프로젝트에 연속 배포할 때 vercel deploy --prod --project $QA_ID, --project $PROD_ID 식으로 두 번 호출해도 구조 그대로 사용 가능

Workflow 작성 (deploy.yaml)

워크플로우 작성 내용:

  • ➖ workflow_dispatch : web/admin/all 선택형 수동배포
  • ➖ push@development : 디렉터리 변경 감지 후 자동배포
  • ➖ dorny/paths-filter : apps/web/, apps/admin/ 만 체크
  • ➖ vercel pull → build --prod → deploy --prebuilt
  • ➖ Slack Webhook 로 성공 / 실패 알림

루트 디렉터리 삽질 포인트

삽질 증상 / 오류 해결
CLI 를 apps/web 에서 실행 vercel build → 또다시 apps/web/apps/web 경로 탐색 → 빌드 실패 루트에서 실행 하되 .vercel/project.json 의 "rootDirectory": "apps/web" 값으로 빌드 경로가 자동 보정된다.
Include files outside… OFF 빌드 단계에서 모노레포 최상단 pnpm-workspace.yaml 를 못 찾아 의존성 오류 토글 ON 으로 해결
--cwd apps/web 강제 지정 Pre-built 결과는 ok인데 vercel deploy . 시 정적 파일 경로가 꼬임 rootDirectory 가 이미 있으므로 --cwd 옵션은 사용하지 않는다.

각 스텝 및 vercel 명령어의 실행 위치 (이것만 자세히 알고있어도 삽질포인트가 줄어든다 🥲)

Key Point:
GitHub Actions 의 step 위치 ↔ Vercel CLI 의 rootDirectory ↔ UI Root Directory_ 설정이 모두 일치해야 삽질을 피한다.

구분 작동기준 디렉터리 핵심 인자·플래그 이중 중첩/주의 포인트
1. checkout actions/checkout@v4 레포 루트 (없음) 이후 모든 step 의 기준점
2. pnpm install 레포 루트 --frozen-lockfile 모노레포 루트의 pnpm-workspace.yaml 필수
3. vercel pull 레포 루트 --environment=production --yes --token=$VERCEL_TOKEN .vercel/project.json의 "rootDirectory": "apps/web" 확인 후 apps/web 안으로 env 파일 다운로드
4. vercel build 레포 루트 → 자동 apps/web --prod --token=… .vercel/project.json의 rootDirectory 읽고 내부적으로 디렉터리 이동 → apps/web/.vercel/output 생성
5. vercel deploy 레포 루트 --prebuilt --prod --yes --token=… 이미 빌드된 .vercel/output 그대로 업로드 → 추가 cd 필요 없음 ❌ cd apps/web 하거나 --cwd apps/web 주면 **apps/web/apps/web** 이중 중첩 발생
6. Slack 알림 레포 루트 (curl, jq) 빌드 산출물과 경로 무관

🛠️ 내 상황 & 해결 과정

1. 초기 세팅

  • Vercel 프로젝트의 Root Directory 를 /(루트)로 그대로 뒀다.
  • “큰일 없겠지?” 싶었지만, 모노레포라 빌드 경로가 계속 꼬이기 시작…
     
    2. 온갖 cwd·상대/절대경로 삽질
  • cd apps/web, vercel build --cwd …, vercel deploy ./apps/web 등 시도
  • 결과는 apps/web/apps/web 같은 이중 중첩 & 정적 파일 404 파티 🤯
     
    3. Root Directory를 apps/web으로 수정
  • Vercel 대시보드 → Settings ▸ General → Root Directory 필드에 apps/web 입력
     
    4. 최종 워크플로 수정 → 정상 작동
- run: npx vercel pull --yes --environment=production --token="$VERCEL_TOKEN"
- run: |
    npx vercel build --prod --token="$VERCEL_TOKEN"
    ls -al .vercel/output
# Deploy
- id: deploy
  run: |
    DEPLOY_URL=$(npx vercel deploy . --prebuilt --prod --yes --token="$VERCEL_TOKEN" | tail -1)
    echo "url=$DEPLOY_URL" >> "$GITHUB_OUTPUT"

✅ 마무리 – 루트 디렉터리 일관성의 교훈

  • - rootDirectory 값을 딱 한 곳(Vercel UI)에서만 정의하고,
    CLI·GitHub Actions 모두 레포 루트(.) 기준으로만 동작하게 만들면
    (1) 빌드 캐시가 한 군데에 쌓이고, (2) 경로 관련 버그가 싹 사라진다.
     
  • - 반대로 UI·CLI·Action 중 하나라도 서로 다른 디렉터리를 바라보면?
    • 1. Vercel 빌드는 apps/web 으로,
    • 2. CLI 는 apps/web/apps/web 으로,
    • 3. Next.js 로더는 또 상대경로가 어긋나서
      정적 자산 404 → ISR 오류 → 배포 실패의 무한 루프가 시작된다.
       
  • -나도 처음엔 “그냥 cd 해서 빌드하면 되겠지?” 싶어 몇 시간 동안
    apps/web/apps/web/apps/web… 로 진입하거나 파일을 찾을 수 없다는 로그를 구경했다....
     
  • - 해결책은 단순하다.
    • 1) UI에서 rootDirectory 지정 → 2) Include files outside… ON →
    • 3) 모든 CLI 호출은 <path> = ..
      이렇게 3단계만 지키면 모노레포 + Private Repo + Hobby 플랜 조합도
      스무스하게 돌아간다.
       

      “rootDirectory를 UI·CLI·Action 세 군데 중 하나라도 다르게 쓰면,
      빌드 로그가 아닌 ‘미궁 속 중첩 디렉터리’와 씨름하게 된다(맞출 생각은 크게 하지말자). – 내가 다 해봤다 😇”

728x90
반응형

'devops' 카테고리의 다른 글

[GitHub Actions으로 AWS환경에 배포] EC2 SSH 접속 → Docker 이미지 전송 → 슬랙 알림까지  (7) 2025.05.22
'devops' 카테고리의 다른 글
  • [GitHub Actions으로 AWS환경에 배포] EC2 SSH 접속 → Docker 이미지 전송 → 슬랙 알림까지
highgarden
highgarden
커밋 하나하나가 쌓여 커다란 정원이 되는 중입니다. 하루하루 정성껏 심어가는 중 https://github.com/highgarden7
  • highgarden
    커밋심는 정원
    highgarden
  • 전체
    오늘
    어제
    • 분류 전체보기 (37)
      • ai (1)
      • devops (2)
      • Nest.js (14)
      • linux (14)
      • 네트워크 (6)
      • git (0)
      • aws (0)
      • docker (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • github
  • 공지사항

  • 인기 글

  • 태그

    Linux
    nestjs
    Chat GPT
    E2E
    Java
    vercel
    네트워크
    springboot
    IP
    githib action
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
highgarden
[DevOps 삽질일지] Vercel Hobby + Private Repo로 모노레포 배포하기
상단으로

티스토리툴바