앱 하나 배포는 명령 하나. 수십 개를 하나씩 지켜보지 않고 배포하는 건 작은 시스템입니다.
병렬화하되 배치로
vercel --prod를 단순 직렬 루프로 돌리면 타임아웃 납니다 — 빌드 큐엔 기본 명령 타임아웃이 너무 짧습니다. 백그라운드로 몇 개씩 돌립니다:
for a in "${apps[@]:0:6}"; do ( cd "$a" && vercel --prod --yes >"$a.log" 2>&1 ) & done
wait6개씩 백그라운드, 배치 사이 wait. 툴 타임아웃을 크게(600s) 올리지 않으면 러너가 빌드 도중 배치를 죽입니다.
vercel.json 함정
vercel project add로 만든 프로젝트는 framework가 "Other"라, 첫 배포가 "No Output Directory named public"으로 실패합니다. 해결은 커밋 한 줄:
{ "framework": "nextjs" }이게 없으면 새 프로젝트 첫 배포가 매번 엎어집니다.
stale .next/types 오탐
로컬 tsc --noEmit이 가끔 삭제한 라우트를 참조하는 TS2307 무더기를 뱉는데 — 제 코드가 아니라 .next/types가 stale해서입니다. rm -rf .next && tsc --noEmit이면 깨끗합니다. Vercel은 어차피 클린 빌드라 배포엔 영향 없고, 흔들린 건 제 확신뿐이었습니다.
솔직한 부분
레버리지는 화려한 CI가 아닙니다. 앱별 반복 가능한 deploy.sh, 타임아웃을 존중하는 배치 병렬, 그리고 함정 두세 개(framework 줄, stale types, zsh가 unquoted 변수를 단어분할 안 하니 배치 리스트는 리터럴로)를 아는 것. 영리한 건 없습니다. 전부 "앱 하나 배포"와 "34개를 계속 살리기"의 차이일 뿐입니다.