본문으로 건너뛰기
← 블로그 목록으로
테크

Vercel 배포 용량 초과로 사이트가 멈췄습니다

공유

9월 17일 아침, 이 블로그를 포함한 사이트 전체가 열리지 않았습니다. 첫 화면도, 글도, 스튜디오 안내 페이지도 모두 404였고 화면에 찍힌 오류 이름은 DEPLOYMENT_NOT_FOUND였습니다.

해킹도 서버 고장도 아니었습니다. 원인은 블로그 사진을 어디에 보관하고 있었느냐였습니다. 같은 방식으로 사이트를 운영하는 분이 같은 일을 겪지 않도록, 경위와 그 뒤에 바꾼 것을 정리합니다.

노트북 뒤로 사진과 상자가 천장까지 위태롭게 쌓인 책상
노트북 뒤로 사진과 상자가 천장까지 위태롭게 쌓인 책상

무슨 일이 있었나

이 사이트는 Next.js로 만들어 Vercel 무료 요금제(Hobby)로 배포합니다. 글은 데이터베이스에 저장되지만, 사진 일부는 사이트 코드 저장소 안의 사진 폴더에 들어 있었습니다. 예전 워드프레스 블로그에서 옮겨 온 사진이 그대로 쌓여 약 1.5GB였습니다.

문제는 Vercel이 배포할 때마다 이 폴더를 통째로 새 배포본에 복사한다는 점이었습니다. 배포 한 번에 약 1.5GB가 새로 쌓이는 구조였습니다.

여기에 자동화가 속도를 붙였습니다.

  • 9월 1일 — 블로그 자동화를 개편하면서 발행 절차를 새로 적었는데, 그 안에 "사진을 사이트 폴더에 복사해 올린다"는 줄이 들어갔습니다. 그전에는 사진을 별도 이미지 저장소에 올리는 절차였습니다.
  • 9월 1일~17일 — 사진을 함께 올린 커밋이 26번, 배포가 41번 쌓였습니다. 8월 한 달 동안 사진 커밋은 4번이었습니다.
  • 배포 보관 용량(Deployment Storage) — 무료 한도 10GB의 아홉 배인 91GB까지 올라갔습니다. 돌아보면 8월 20일에 이미 38GB였는데, 그 숫자를 보는 사람이 없었습니다.
  • 9월 16일 — Vercel이 무료 요금제 정책을 바꿔, 보관 용량이 10GB를 넘으면 공간을 비울 때까지 배포를 막을 수 있게 했습니다. 몇 달 동안 숨어 있던 구조 문제가 이날 드러났습니다.
  • 9월 16~17일 — 용량을 줄이려고 옛 배포를 정리하는 과정에서 운영 중이던 배포까지 지워졌고, 17일 아침에는 사이트 전체가 내려가 있었습니다.
  • 복구에서 걸린 두 가지

    하나. 지워도 숫자가 바로 줄지 않습니다. 배포 80개를 지웠는데도 용량 그래프는 9월 15일 93.02GB, 16일 91.58GB, 17일 85.51GB로 거의 그대로였습니다. 지운 배포는 '최근 삭제됨'에 약 30일 동안 남아 복원할 수 있는 상태로 있고, 그동안 용량에 계속 잡혔습니다. 영구 삭제 버튼도 없었습니다. "지우면 바로 풀린다"는 가정이 틀렸습니다.

    둘. 복원했다고 사이트가 살아나지 않습니다. 지워진 운영 배포를 복원했지만 사이트는 계속 404였습니다. 배포는 돌아왔는데, 그 배포에 붙어 있던 도메인 연결(www 주소, 기본 주소 등 4개)은 다시 붙지 않았기 때문입니다. 도메인 4개를 운영 배포에 다시 연결하자 그날 밤 10시 36분에 바로 열렸습니다. 새로 배포한 것이 아니라 연결만 다시 한 것이라 용량 차단과는 상관이 없었습니다.

    그래서 지금은 배포를 정리하거나 복원한 직후에 반드시 실제 주소로 접속해 확인합니다. 관리 화면에 "복원됨"이 떠도, 방문자가 보는 주소가 열리는지는 따로 봐야 합니다.

    다시 생기지 않도록 바꾼 세 가지

    지침 한 줄을 고치는 것으로는 부족하다고 판단했습니다. 이번 일의 출발점이 바로 지침 한 줄이었기 때문입니다. 그래서 세 겹으로 막았습니다.

    1. 절차 — 사진은 이미지 저장소에만 올립니다. 블로그와 SNS에 쓰는 사진은 Cloudflare R2라는 이미지 저장소에 올리고, 글에는 그 주소를 씁니다. 업로드는 도구 하나로 통일했습니다. 같은 이름의 파일이 이미 있으면 덮어쓰지 않고 멈추고, 올린 뒤에는 공개 주소가 실제로 열리는지와 파일 크기가 같은지까지 확인합니다.

    2. 장치 — 실수해도 기계가 막습니다. 사이트 코드 저장소에 사진 폴더를 커밋하려 하면 거부되는 장치를 걸었습니다. 그리고 매주 금요일 자동 점검에 사진 폴더 크기, 그 주의 사진 커밋 수, 그 주의 전체 커밋 수를 넣어 하나라도 이상하면 알림이 오게 했습니다. 8월 20일의 38GB처럼 "숫자는 있었는데 아무도 안 본" 상황을 줄이기 위해서입니다.

    3. 구조 — 사진 폴더를 사이트에서 뺐습니다. 9월 29일, 사진 폴더를 저장소에서 통째로 뺐습니다.

  • 글이 실제로 쓰고 있는 사진 703개는 이미지 저장소로 같은 경로 그대로 옮겼습니다.
  • 쓰지 않는 2,693개(워드프레스가 자동으로 만든 크기별 사본, 미디어 보관함 파일 등)는 지웠습니다.
  • 옛 글 본문에 적힌 사진 주소는 하나도 고치지 않았습니다. 대신 사이트 설정에서 /uploads/로 시작하는 주소를 이미지 저장소로 넘겨주도록 했습니다. 사진 주소가 들어 있는 80편이 넘는 옛 글을 하나씩 고치는 것보다 안전했습니다.
  • 옮기기 전후로 419개 페이지의 사진을 대조했고, 새로 깨진 사진은 0개였습니다.
  • 지금 사이트 코드의 공개 파일 폴더는 약 27MB입니다. 배포 한 번의 부담이 1.5GB에서 수십 MB로 줄었습니다.

    같은 구조로 운영한다면 확인할 다섯 가지

    사진과 영상이 사이트 코드와 같은 곳에 있는가. 배포할 때마다 사이트 파일 전체를 새로 묶어 보관하는 방식이라면, 사진이 그 안에 있는 한 배포 횟수만큼 사진도 복제됩니다. 처음엔 작아도 글이 쌓이면 커집니다.

    자동화가 배포 횟수를 얼마나 늘렸는가. 사람이 손으로 올릴 때는 일주일에 몇 번이던 배포가, 자동화를 붙이면 하루에 여러 번이 될 수 있습니다. 구조가 같아도 횟수가 늘면 결과가 달라집니다.

    결과물이 아니라 부산물을 숫자로 보는가. "오늘 글이 올라갔나"는 매일 확인하기 쉽습니다. 그런데 그 글과 함께 무엇이 쌓였는지, 보관 용량과 배포 횟수와 요금은 일부러 보지 않으면 보이지 않습니다. 주 1회, 숫자 세 개면 충분합니다.

    무료 요금제의 규칙이 바뀌는 것을 알 수 있는가. 이번에는 사이트가 변한 게 아니라 규칙이 변한 날 문제가 터졌습니다. 쓰는 서비스의 변경 공지를 받아 보는 경로 하나는 열어 두는 편이 좋습니다.

    정리할 때 지우면 안 되는 것을 먼저 표시했는가. 용량을 비우는 작업은 급하게 하게 됩니다. 시작하기 전에 운영 중인 배포처럼 절대 건드리면 안 되는 것을 먼저 적어 두고, 끝난 뒤에는 실제 주소로 들어가 확인합니다.

    정리

    자동화는 지시문을 그대로 반복합니다. 이번에는 발행 절차의 한 줄이 17일 동안 41번의 배포를 만들었습니다. 그 뒤로 자동화를 점검할 때는 "결과물이 나왔나"와 함께 "무엇이 같이 쌓였나"를 봅니다.

    발행한 글이 실제 화면에 제대로 보이는지 확인하는 기준은 공개 결과까지 확인하는 4단계에, 어떤 자동화를 남기고 어떤 것을 껐는지는 자동화를 끄면서 배운 것에 적어 두었습니다.

    보통리가 만드는 서비스

    Vercel 배포 용량 초과로 사이트가 멈춘 이유와 해결 | 보통리