Vercel 배포하다가 빌드 터졌을 때: OOM부터 504 타임아웃까지 실전 해결법
Dev
마지막 업데이트

Vercel 배포하다가 빌드 터졌을 때: OOM부터 504 타임아웃까지 실전 해결법


“분명 내 컴퓨터(localhost)에서는 아무 문제 없이 잘 돌았는데, Vercel에 푸시하자마자 빨간 불이 켜지면서 배포가 실패했다.”

프론트엔드나 풀스택 개발자라면 누구나 한 번쯤 겪어봤을 답답한 순간입니다. 로컬 머신과 클라우드 서버리스 환경은 생각보다 차이가 큽니다. 메모리 한도도 다르고, 실행 시간 제한도 있으며, 환경 변수 주입 타이밍도 제각각이기 때문이죠.

이번 글에서는 Astro나 Next.js 프로젝트를 Vercel에 배포할 때 가장 자주 마주치는 4대 빌드/런타임 장애 유형과, 실제로 유효했던 해결 방안들을 깔끔하게 정리해 보겠습니다.


1. 정적 배포(Static) vs 서버 배포(SSR): 프로젝트 성격부터 확인하기

Vercel에 올리기 전에, 우리 프로젝트가 정적 사이트(SSG)인지 서버 사이드 렌더링(SSR)인지 명확히 짚고 넘어가야 합니다.

  • 정적 배포 (Static / SSG): 별도의 서버리스 어댑터 없이 HTML/CSS/JS 빌드 결과물을 Vercel의 글로벌 CDN 엣지 네트워크에 그대로 배포합니다. 서버 비용이 들지 않고 속도도 가장 빠릅니다. 블로그나 회사 소개 페이지에 최적입니다.
  • 서버 배포 (SSR / Hybrid): 요청마다 실시간 데이터를 가져오거나, 세션/쿠키 기반 인증, 동적 API 라우트가 필요하다면 서버리스 어댑터를 붙여야 합니다.
    # Astro 기준 Vercel 어댑터 추가
    npx astro add vercel
    이 설정을 거치면 빌드 결과물이 Vercel의 Serverless Function 규격에 맞춰 패키징됩니다.

2. 생각보다 자주 터지는 환경 변수(Env) 누락 실수

로컬의 .env에선 다 돌아갔는데 Vercel에선 런타임 에러가 난다면, 십중팔구 환경 변수 문제입니다.

클라이언트 노출 변수 접두사 확인

  • 브라우저 클라이언트 코드에서 읽어야 하는 변수(예: Google AdSense ID, 공개 Supabase Key 등)는 반드시 프레임워크 규칙에 맞는 접두사(NEXT_PUBLIC_, PUBLIC_)가 붙어 있어야 빌드 시점에 번들에 포함됩니다.
  • 보안이 중요한 시크릿 키는 절대 PUBLIC_을 붙이지 말고 서버 전용 환경 변수로 등록해야 합니다.

CLI로 로컬과 클라우드 환경 변수 동기화하기

Vercel 대시보드에서 일일이 변수를 복사해 오지 말고, 공식 CLI를 쓰면 실수를 원천 차단할 수 있습니다.

# 1. Vercel 프로젝트와 로컬 저장소 연결
vercel link

# 2. Vercel에 등록된 개발 환경 변수를 로컬로 한 번에 당겨오기
vercel env pull .env.development.local

3. 실전 트러블슈팅: 자주 터지는 2대 빌드/런타임 에러

💡 1. 빌드 메모리 초과 (OOM: Out of Memory)

블로그에 고해상도 이미지가 많아지거나, TypeScript 타입 검사 대상 파일이 수백 개로 늘어나면 빌드 도중 갑자기 프로세스가 뻗어버립니다.

  • 원인: Vercel 빌드 컨테이너의 기본 Node.js 힙 메모리 제한(기본 1.4GB~2GB 내외)에 도달했기 때문입니다.
  • 해결책: Vercel 대시보드의 Settings > Environment Variables에 아래 환경 변수를 추가해 가비지 컬렉터 힙 한도를 올려주면 거짓말처럼 해결됩니다.
    NODE_OPTIONS = --max-old-space-size=4096

💡 2. 504 Gateway Timeout (서버리스 함수 실행 지연)

배포는 성공했는데, 특정 API를 호출하면 10초 뒤 504 Gateway Timeout이 떨어집니다.

  • 원인: Vercel 무료(Hobby) 플랜의 Serverless Function 최대 실행 시간은 10초로 엄격히 제한되어 있습니다. 외부 API 응답이 늦어지거나 무거운 데이터 처리를 동기적으로 돌리면 게이트웨이가 커넥션을 강제로 끊어버립니다.
  • 해결책:
    1. 무거운 작업(예: 대량 메일 발송, AI 모델 추론, 이미지 가공)은 비동기 큐(Upstash, QStash 등)로 넘기고 클라이언트에는 202 Accepted를 즉시 반환하도록 아키텍처를 변경합니다.
    2. Pro 플랜을 사용 중이라면 vercel.json에서 maxDuration을 명시적으로 늘려줍니다.
    {
      "functions": {
        "api/**/*.ts": {
          "maxDuration": 30
        }
      }
    }

4. 도메인 설정과 초고속 롤백 파이프라인

Apex 도메인과 www 리다이렉트 깔끔하게 잡기

myblog.comwww.myblog.com을 둘 다 Vercel 프로젝트에 추가하세요. 그리고 Vercel 도메인 설정에서 한쪽(보통 www)을 다른 한쪽으로 301 영구 리다이렉트 걸어두어야 구글 검색엔진에서 중복 콘텐츠로 감점당하지 않습니다.

배포 터졌을 때 10초 만에 롤백하기 (Rollback)

운영 환경에 배포했는데 치명적인 버그가 터졌다면, 당황해서 git revert 치고 다시 빌드 기다릴 필요가 없습니다.

Vercel 대시보드의 Deployments 탭으로 가서 직전 정상 배포 우측의 메뉴를 누르고 Rollback을 누르세요. 재빌드 과정 없이 직전 정상 빌드 인스턴스로 즉각 트래픽이 스위칭되므로 10초 안에 장애를 수습할 수 있습니다. CLI로도 바로 가능합니다.

vercel rollback <정상이었던_deployment_id>

배포 직후 1분 셀프 점검 체크리스트

배포가 완료되었다면 브라우저를 띄우기 전에 터미널에서 아래 2개만 쳐보세요.

# 1. 200 OK 응답 및 HTTPS 보안 인증서 확인
curl -I https://myblog.com/

# 2. 검색 로봇 파일 및 사이트맵 정상 노출 확인
curl -s https://myblog.com/robots.txt
curl -s -I https://myblog.com/sitemap-index.xml

특히 다국어 사이트라면 캐노니컬(rel="canonical") 주소가 Vercel 기본 주소(*.vercel.app)가 아니라 내 커스텀 도메인으로 올바르게 박혀 있는지 크롬 개발자 도구(F12) Elements 탭에서 확인해 두는 것이 안전합니다.

먼저 읽어볼 가이드

검색 유입이 많은 핵심 글부터 이어서 보세요.