21장. (심화) 프론트를 Vercel로 분리 배포
여기까지 온 것을 축하합니다. 14장에서 ALB 주소로 접속되는 기본 완성을
만들었고, 3부에서 자동 배포와 무중단 배포, 롤백까지 손에 넣었습니다.
그런데 지금 우리 서비스 주소를 친구에게 보내려고 보면 두 가지가 걸립니다.
주소가 http://vote-alb-1234567890.ap-northeast-2.elb.amazonaws.com처럼
길고, 앞이 https가 아니라 http입니다. 브라우저가 "안전하지 않음"이라고
표시하기도 하죠.
이 장은 심화(보너스) 입니다. 지금까지 만든 기본 구조(ECS + ALB)를
없애거나 바꾸지 않습니다. 그 위에, 실무에서 아주 흔히 쓰는 방식 하나를
더 얹습니다. 프론트(화면)만 떼어 내 Vercel이라는 곳에 올리고, 짧은
HTTPS 주소로 접속하게 만드는 것입니다. API와 DB는 지금 그대로 ECS와
RDS를 씁니다. 다 끝내면 https://vote-app.vercel.app 같은 주소로 접속해
투표가 됩니다. 한 단계씩 천천히 따라오세요.
[지금 여기]
우리는 22단계를 거쳐 "라이브 투표 서비스"를 직접 만들고, 컨테이너에 담아, AWS 클라우드에 배포했습니다. 아래가 그 전체 여정 지도입니다. 지금은 21단계, 기본 완성 위에 실무 패턴 하나를 더 얹는 심화 자리에 있습니다.
- 1장개발 환경 준비 (터미널 / Node.js / Git / GitHub / VS Code / Claude Code)
- 2장Claude Code 사용법 익히기
- 3장무엇을 만들지 기획 (라이브 투표 서비스)
- 4장로컬에서 서비스 만들기 (React + Express + PostgreSQL)
- 5장Docker 개념
- 6장Dockerfile 작성
- 7장컨테이너 빌드·실행
- 8장AWS 시작 (계정 / IAM / 리전 / 비용)
- 9장이미지 태깅
- 10장ECR에 이미지 올리기
- 11장VPC 네트워크 구성
- 12장RDS 데이터베이스 생성
- 13장SSM 터널로 RDS 초기화
- 14장ECS Fargate + ALB로 배포 (기본 완성)
- 15장CI/CD (GitHub Actions)
- 16장IaC (Terraform)
- 17장배포 자동화 연결
- 18장현업 운영 구조 이해
- 19장무중단 배포
- 20장신규 버전 배포 & 롤백
- 21장(심화) 프론트를 Vercel로 분리 배포
- 22장마무리 (회고 + 리소스 삭제)
- 방금 끝낸 것: 20장에서 새 버전을 배포해 보고, 문제가 생겼을 때 이전 태스크 정의 리비전으로 롤백하는 것까지 익혔습니다. 이제 ECS와 ALB 위에서 우리 서비스를 자유롭게 올렸다 되돌렸다 할 수 있습니다.
- 이번 장에서 하는 것: 프론트(React 화면)만 떼어 Vercel에 분리
배포하고,
vercel.json의 rewrites로/api요청을 지금의 ALB로 넘겨, 짧은 HTTPS 주소로 접속하면 투표가 되게 만듭니다.
이번 장에서 완성되는 것
한 문장으로: https://...vercel.app 형태의 짧은 HTTPS 주소로 접속하면,
14장에서 만든 API·DB(ECS·RDS)를 그대로 쓰면서 투표가 동작합니다.
이렇게 되면 성공입니다: Vercel이 준 HTTPS 주소로 접속해 설문이 뜨고 투표가
되며, 브라우저 개발자 도구의 Network 탭에서 /api 요청이 Vercel 도메인
(https) 으로 나가는 것이 보입니다. 이때 사용자의 브라우저는 오직 HTTPS
Vercel하고만 통신하므로, 4장에서 겪었던 CORS나 "안전하지 않은 콘텐츠(혼합
콘텐츠)" 경고가 생기지 않습니다.
전체 흐름을 그림으로 그리면 이렇게 됩니다.
기본 완성은 그대로 둡니다 이 장은 14장의 ALB 주소 접속을 없애지 않습니다. 그 주소도 계속 살아 있습니다. 우리는 그 앞에 "화면 전용 배포"를 하나 더 얹어, 짧은 HTTPS 주소를 얻는 것뿐입니다. 두 주소가 동시에 살아 있어도 괜찮습니다.
사전 조건
이 장은 1~20장의 결과물 위에서 시작합니다. 아래가 갖춰져 있어야 합니다. 하나라도 빠지면 중간에 막히니 먼저 확인하세요.
- 14장 기본 완성이 살아 있다. ALB 기본 DNS 주소(예:
http://vote-alb-1234567890.ap-northeast-2.elb.amazonaws.com)로 접속하면 지금도 투표 화면이 뜨고 투표가 됩니다. 이 장에서 API로 계속 쓸 대상입니다.- [주의] 만약 실습을 쉬면서 22장의 안내로 ALB나 ECS를 지웠다면, 이 장은 진행할 수 없습니다. ALB가 살아 있어야 Vercel이 그쪽으로 API 요청을 넘길 수 있습니다. 지웠다면 14장으로 돌아가 다시 띄운 뒤 진행하세요.
- ALB DNS 주소를 손에 갖고 있다. 14.4에서 복사해 메모장에 붙여 둔 그
주소입니다. 없으면 EC2 콘솔 → 로드밸런서 →
vote-alb의 DNS 이름(DNS name) 에서 다시 복사합니다. 이 장 21.5에서 그대로 씁니다. - 프론트 코드가 GitHub 비공개 저장소
vote-app에 올라가 있다 (4장). 그 안frontend폴더가 React(Vite) 프론트이고, API를 상대 경로/api로 부릅니다. (4.3~4.5에서 그렇게 만들어 뒀습니다. 이 습관이 이 장에서 결정적으로 쓰입니다.) - GitHub 로그인이 되어 있다 (1장). Vercel은 GitHub 계정으로 로그인합니다.
도메인은 사지 않습니다
짧은 HTTPS 주소를 얻으려고 도메인을 따로 구매하지 않습니다. Vercel은
배포할 때마다 xxx.vercel.app 형태의 기본 주소를 무료 HTTPS로 자동
발급해 줍니다. 이 장은 그 기본 주소만으로 끝까지 갑니다.
21.1 정적 호스팅과 CDN — 화면은 왜 컨테이너 밖에 둘까
지금 우리 프론트는 web 컨테이너(Nginx)가 서빙합니다. 즉 화면 파일들이 ECS 컨테이너 안에 들어 있습니다. 잘 도는데, 왜 굳이 밖으로 뺄까요? 먼저 개념부터 정리합시다.
정적 파일(Static Files)
React를 빌드하면 나오는 결과물은 index.html, 자바스크립트 묶음(.js),
스타일(.css), 이미지 같은 "이미 완성돼 바뀌지 않는 파일"들입니다. 서버가
매번 계산해서 만들어 내는 게 아니라, 그냥 그대로 내려 주기만 하면 되는
파일이라 "정적(static)"이라고 부릅니다. 우리 프론트가 바로 이겁니다.
정적 호스팅(Static Hosting) 이런 정적 파일들을 올려 두면, 접속하는 사람에게 그대로 내려 주는 전용 서비스입니다. 서버를 직접 돌보지 않아도 되고, 파일만 올리면 됩니다. Vercel, Netlify, GitHub Pages, AWS S3+CloudFront 등이 여기에 해당합니다.
CDN(Content Delivery Network) 전 세계 곳곳에 파일 사본을 미리 복제해 두는 배달망입니다. 서울 사용자는 서울 근처 서버에서, 뉴욕 사용자는 뉴욕 근처 서버에서 화면 파일을 받아, 어디서 접속하든 빠릅니다. 정적 호스팅 서비스는 대부분 이 CDN을 기본으로 깔고 있습니다.
Vercel(버셀)
정적 프론트(그리고 일부 서버 기능)를 GitHub 저장소와 연결해 손쉽게
배포해 주는 클라우드 서비스입니다. GitHub에 코드를 올리면 자동으로
빌드해서 CDN에 올리고, xxx.vercel.app 주소와 무료 HTTPS를 붙여 줍니다.
React를 만든 Meta처럼, Vercel은 Next.js를 만든 회사이기도 합니다.
[활용 사례] 정적 호스팅과 Vercel은 실무에서 어디에 쓰이나
화면을 컨테이너나 서버가 아니라 이런 정적 호스팅에 두는 방식은, 요즘 웹 서비스에서 아주 흔한 표준입니다.
- 프론트만 Vercel/Netlify에 올리기: 화면(React/Vue 등)은 Vercel에, API 서버는 별도(AWS 등)에 두는 "프론트-백엔드 분리 배포"가 스타트업부터 대기업까지 널리 쓰입니다. 화면 배포와 서버 배포를 서로 독립적으로 할 수 있어 편합니다.
- 전 세계 어디서나 빠른 로딩(CDN): 화면 파일이 CDN에 복제돼 있어, 해외 사용자도 가까운 서버에서 빠르게 받습니다. 이미지·글꼴 같은 무거운 정적 자원일수록 효과가 큽니다.
- git push만 하면 자동 배포: 코드를 GitHub에 올리면 Vercel이 알아서 다시 빌드해 배포합니다. 우리가 3부에서 GitHub Actions로 만든 자동 배포와 같은 발상이, 프론트에서는 설정 없이 기본으로 제공됩니다.
- 무료 HTTPS와 짧은 주소: 도메인을 안 사도
xxx.vercel.app주소와 자물쇠(HTTPS)가 자동으로 붙습니다. 개인 프로젝트나 데모를 남에게 보여 줄 때 특히 편합니다. 이것이 바로 우리가 이 장에서 노리는 점입니다.
[맛보기] 아주 작은 정적 HTML 하나를 Vercel에 올려 보기
우리 프로젝트를 건드리기 전에, "정적 파일을 올리면 HTTPS 주소가 생긴다"를 아주 작은 예로 먼저 손으로 느껴 봅시다. 이 맛보기는 우리 투표 서비스와 완전히 분리된, 버리는 연습입니다. HTML 딱 한 장을 Vercel에 올려 봅니다.
먼저 연습용 파일을 만듭니다. VS Code에서 vote-app 폴더를 열고, 터미널
(vote-app에서)에서 claude를 실행한 뒤 아래 프롬프트를 그대로 넣으세요.
우리 프로젝트 폴더와 섞이지 않게, 문서 폴더 안에 별도 폴더로 만듭니다.
Claude Code가 폴더와 index.html을 만들고, hello-vercel이라는 새 저장소로
올려 줍니다. 중간에 승인을 물으면 내용을 보고 승인하세요. 이제 이걸
Vercel에 올립니다. (계정이 없다면 바로 다음 21.2에서 만드는 계정으로 하면
됩니다. 계정을 먼저 만들고 이 맛보기로 돌아와도 됩니다.)
- 웹브라우저에서
https://vercel.com에 접속해, GitHub 계정으로 로그인 합니다. (계정 만들기·GitHub 연결은 21.2에서 자세히 다룹니다.) - 로그인 후 나오는 대시보드에서 Add New…(새로 추가) → Project(프로젝트) 를 누릅니다.
- GitHub 저장소 목록에서 방금 만든
hello-vercel을 찾아 그 옆의 Import(가져오기) 를 누릅니다.- [참고] 목록에 안 보이면, 목록 위의 Adjust GitHub App Permissions(GitHub 권한 조정) 같은 링크를 눌러 Vercel이 이 저장소를 볼 수 있게 허용해 줍니다. (21.3에서 다시 설명합니다.)
- 설정 화면이 나오면 아무것도 바꾸지 말고 그대로 Deploy(배포) 를 누릅니다. (HTML 한 장이라 특별한 설정이 필요 없습니다.)
- 잠시 기다리면 축하 화면과 함께
https://hello-vercel-xxxx.vercel.app같은 주소가 나옵니다. 그 주소를 눌러 열면, "안녕하세요, 첫 Vercel 배포입니다" 화면이 https(자물쇠 표시) 로 뜹니다.
방금 여러분은 정적 파일을 Vercel에 올려, 무료 HTTPS 주소로 여는 것을 직접
해 봤습니다. 이게 이 장에서 우리 프론트에 할 일의 축소판입니다. 이 연습용
hello-vercel은 이제 필요 없으니, 나중에 지워도 되고 그냥 둬도 됩니다.
21.2 Vercel 계정 만들기
이제 본격적으로 시작합니다. 먼저 Vercel 계정을 만듭니다. 우리 코드가 GitHub에 있으니, GitHub로 로그인하는 것이 가장 매끄럽습니다.
- 웹브라우저에서
https://vercel.com에 접속합니다. - 오른쪽 위 Sign Up(가입) 을 누릅니다. (이미 계정이 있으면 Log In 으로 로그인하고 이 절을 건너뜁니다.)
- 가입 방식 선택 화면에서 Continue with GitHub(GitHub로 계속) 를 누릅니다. 1장에서 만든 그 GitHub 계정을 씁니다.
- GitHub 로그인 창이 뜨면 로그인하고, Vercel이 GitHub에 접근하는 것을 허용(Authorize)합니다.
- 이름·용도 같은 걸 물으면 개인용(Hobby / Personal)으로 진행합니다. 이 실습은 무료(Hobby) 플랜으로 충분하니, 카드 정보를 넣으라는 화면이 나와도 유료로 넘어가지 않아도 됩니다.
로그인이 끝나면 Vercel 대시보드(Dashboard) 화면이 보입니다. 화면 오른쪽 위에 내 계정 아이콘이 있으면 로그인된 상태입니다. 아직 프로젝트가 없으면 목록이 비어 있는데, 정상입니다.
Vercel과 GitHub를 연결한다는 것 GitHub로 로그인하면, Vercel이 "내 GitHub 저장소를 읽고 배포할 수 있는" 권한을 받습니다. 그래서 다음 절에서 저장소 목록이 Vercel 안에 바로 나타납니다. 어떤 저장소까지 보여 줄지는 21.3에서 고를 수 있습니다.
21.3 우리 프론트를 Vercel에 배포하기
이제 vote-app 저장소의 frontend 폴더를 Vercel에 올립니다. 핵심은
Root Directory(루트 디렉터리)를 frontend로 지정하는 것 하나입니다.
우리 저장소는 frontend와 backend가 한 저장소에 같이 있으므로, "이 중
frontend만 배포 대상"이라고 알려 줘야 하기 때문입니다.
[콘솔] 1단계: 저장소 가져오기(Import)
- Vercel 대시보드에서 Add New…(새로 추가) → Project(프로젝트) 를 누릅니다.
- Import Git Repository(깃 저장소 가져오기) 목록에서
vote-app을 찾습니다.- [주의] 목록에
vote-app이 안 보이면 — 우리 저장소는 비공개라, Vercel에 아직 볼 권한을 안 줬을 수 있습니다. 목록 근처의 Adjust GitHub App Permissions(또는 "Configure GitHub App", "GitHub 권한 조정") 링크를 누르고, 열린 GitHub 화면에서 All repositories(모든 저장소) 또는 Only select repositories →vote-app선택 을 골라 저장(Save) 합니다. 그러면 Vercel 목록에vote-app이 나타납니다.
- [주의] 목록에
vote-app옆 Import(가져오기) 를 누릅니다.
[콘솔] 2단계: Root Directory를 frontend로 지정하고 배포
가져오면 프로젝트 설정 화면이 나옵니다. 여기서 딱 한 곳을 바꿉니다.
- Root Directory(루트 디렉터리) 항목을 찾아 Edit(편집) 를 누릅니다.
- 폴더 목록에서
frontend를 선택합니다. (Root Directory 값이frontend로 바뀝니다.)- [주의] 여기를 지정하지 않으면 Vercel이 저장소 맨 바깥(
backend가 섞인 곳)을 빌드하려다 실패합니다. 반드시frontend로 지정하세요. 이 장에서 가장 많이 틀리는 지점입니다.
- [주의] 여기를 지정하지 않으면 Vercel이 저장소 맨 바깥(
- Framework Preset(프레임워크 프리셋) 을 확인합니다.
frontend가 Vite로 만든 React 프로젝트이므로, Vercel이 자동으로 Vite 로 감지해 놓았을 겁니다. 그대로 둡니다. (빌드 명령·출력 폴더도 Vite 기본값으로 자동으로 채워집니다. 직접 건드릴 필요 없습니다.)- [참고] 자동 감지가
Vite가 아니라Other로 잡혀 있으면, 드롭다운에서 Vite 를 직접 골라 줍니다.
- [참고] 자동 감지가
- Environment Variables(환경 변수) 는 지금은 건드리지 않습니다. 우리
프론트는 API를 상대 경로
/api로 부르므로, 화면 쪽에 넣을 비밀값이 없습니다. (API 연결은 다음 절 rewrites로 합니다.) - Deploy(배포) 를 누릅니다. 빌드 로그가 흐르고, 1~2분 뒤 축하 화면과
함께
https://vote-app-xxxx.vercel.app같은 주소가 나옵니다.
나온 주소를 눌러 열어 보세요. 투표 화면 자체는 HTTPS로
뜹니다. 다만 지금은 아직 투표가 되지 않거나 설문이 안 불러와질 수
있습니다. 정상입니다. 화면(/)은 Vercel이 서빙하지만, 데이터
(/api/...)를 어디로 보낼지 아직 안 알려 줬기 때문입니다. 그 연결을
다음 절에서 vercel.json으로 합니다.
21.4 rewrites — Vercel이 대신 ALB로 넘겨 준다
화면은 떴는데 데이터가 안 옵니다. 프론트가 /api/polls 같은 요청을
보내면, 지금은 Vercel 자기 자신에게 물어보는 꼴이라 그런 데이터가 없다고
나옵니다. 이 /api 요청을 우리 ALB로 넘겨 줘야 합니다. 이때 쓰는
것이 Vercel의 rewrites입니다.
rewrites(리라이트) — 서버측 프록시 "이 경로로 오는 요청은 내가 대신 저쪽으로 넘겨서 받아다 줄게"라고 Vercel에게 시키는 규칙입니다. 브라우저가 직접 저쪽(ALB)으로 가는 게 아니라, Vercel 서버가 대신 저쪽에 요청을 보내 응답을 받아 브라우저에 돌려줍니다. 브라우저 입장에서는 계속 Vercel 주소하고만 대화합니다.
이 발상, 사실 여러분은 두 번이나 봤습니다.
- 4장의 Vite 개발 프록시: 개발 중
/api요청을 Vite가 몰래 3000번 API 서버로 넘겨 줬습니다. 브라우저는 5173번하고만 대화했죠. - 14장의 Nginx 프록시: 배포 시 web 컨테이너의 Nginx가
/api를 옆의 api 컨테이너로 넘겨 줬습니다.
Vercel rewrites는 같은 아이디어의 배포판입니다. 이번엔 Vercel 서버가
/api를 우리 ALB로 넘겨 줍니다. 그래서 화면 코드는 4장에서 정한 대로
/api만 부르면 되고, 한 줄도 안 고쳐도 됩니다.
왜 이게 CORS·혼합 콘텐츠를 피하나. 두 용어를 다시 짚고 갑니다.
CORS (교차 출처 요청 차단) — 4장 복습 브라우저의 보안 규칙입니다. 화면 주소(Vercel, https)와 데이터 요청 주소가 서로 다른 출처면 브라우저가 요청을 막습니다. 만약 프론트가 브라우저에서 직접 ALB로 요청했다면 출처가 달라 CORS에 걸립니다.
혼합 콘텐츠(Mixed Content) HTTPS(자물쇠) 페이지 안에서 HTTP(자물쇠 없는) 주소로 요청을 보내면, 브라우저가 "안전한 페이지가 안전하지 않은 걸 부른다"며 그 요청을 막거나 경고합니다. 우리 ALB는 HTTP라, 만약 브라우저가 직접 ALB(http)를 불렀다면 이 혼합 콘텐츠 문제에 걸립니다.
rewrites는 이 둘을 한 번에 피합니다. 브라우저는 오직 Vercel(https, 같은 출처)하고만 통신합니다. ALB(http)로의 요청은 브라우저가 아니라 Vercel 서버가 뒤에서 대신 보냅니다. 브라우저는 그 HTTP 통신을 보지도 못하므로, CORS도 혼합 콘텐츠도 생길 수가 없습니다.
[활용 사례] rewrites(리라이트 프록시)는 실무에서 어디에 쓰이나
- 프론트-백엔드 분리 배포의 연결: 우리처럼 화면은 Vercel, API는 다른
곳(AWS 등)에 둘 때,
/api를 rewrites로 백엔드에 넘겨 한 주소처럼 보이게 합니다. 가장 흔한 용도입니다. - 레거시/외부 API를 내 도메인 아래로: 다른 팀이나 외부 업체의 API를
/api/...경로로 감싸, 사용자에게는 전부 내 도메인 한 곳에서 나오는 것처럼 보이게 합니다. - 점진적 이전: 옛 시스템 일부 경로만 새 서비스로 넘기고 나머지는 그대로 두는 식으로, 주소를 바꾸지 않고 뒤를 조금씩 옮길 때도 씁니다.
[우리 프로젝트] vercel.json에 rewrites 넣기
이제 frontend 폴더에 vercel.json 파일을 만들어, /api로 오는 요청을
우리 ALB로 넘기는 규칙을 씁니다. 이 파일도 Claude Code에게 맡깁니다.
먼저 내 ALB DNS 주소를 손에 준비하세요(사전 조건에서 확인한 값). 예를
들어 vote-alb-1234567890.ap-northeast-2.elb.amazonaws.com 라고 합시다.
여러분의 실제 주소로 바꿔서 쓰면 됩니다.
VS Code에서 vote-app 폴더를 연 상태로, 터미널(vote-app)에서 claude를
실행한 뒤 아래 프롬프트를 넣으세요. 꺾쇠(<>) 부분을 내 실제 ALB DNS
주소로 바꾸는 것을 잊지 마세요.
Claude Code가 만들어 줄 frontend/vercel.json은 아래와 같은 모습이어야
합니다. 여러분의 ALB 주소가 destination에 정확히 들어갔는지 눈으로
확인하세요.
{
"rewrites": [
{
"source": "/api/:path*",
"destination": "http://vote-alb-1234567890.ap-northeast-2.elb.amazonaws.com/api/:path*"
}
]
}
source: 프론트에서 이 경로(/api/로 시작하는 모든 요청)로 나가면destination: Vercel 서버가 대신 이 주소(우리 ALB의 같은 경로)로 넘긴다:path*:/api/뒤에 오는 나머지 경로 전체를 그대로 옮겨 붙이라는 뜻 (예:/api/polls/3/vote→.../api/polls/3/vote)
destination이 http://인데 괜찮은가요?
괜찮습니다. 이 HTTP 요청은 Vercel 서버가 뒤에서 보내는 것이라,
브라우저의 혼합 콘텐츠 규칙과 무관합니다. 브라우저는 여전히 HTTPS
Vercel하고만 통신합니다. destination에는 우리 ALB가 HTTP만 열려
있으니 http://가 맞습니다. 뒤에 슬래시나 경로를 빠뜨리지 말고,
.../api/:path* 까지 정확히 넣으세요.
ALB 주소 오타를 조심하세요
destination의 주소에 오타가 하나라도 있으면 /api 요청이 엉뚱한 곳으로
가 투표가 안 됩니다. 14장에서 복사해 둔 주소를 그대로 붙여넣는 게
안전합니다. 앞에 http://가 붙어 있는지, 끝이 /api/:path*인지 확인하세요.
21.5 git push로 자동 재배포하기
vercel.json을 방금 GitHub에 push했습니다. 그러면 Vercel이 알아서 다시
배포합니다. 21.3에서 저장소를 연결해 둔 순간부터, 이 저장소(정확히는
frontend)에 코드가 올라올 때마다 Vercel이 자동으로 새로 빌드해 올리기
때문입니다. 우리가 3부에서 GitHub Actions로 만든 자동 배포와 같은 일이,
프론트에서는 설정 없이 기본으로 일어납니다.
- 웹브라우저에서 Vercel 대시보드 → 우리 프로젝트(
vote-app)로 들어갑니다. - Deployments(배포 내역) 탭을 보면, 방금 push로 새 배포가 Building
(빌드 중) → Ready(준비됨) 로 바뀌는 것이 보입니다. 1~2분이면 끝납니다.
- [참고] 자동으로 안 도는 것 같으면, 21.4의 프롬프트에서 push가
실제로 됐는지 확인하세요. GitHub의
vote-app저장소frontend폴더에vercel.json이 올라와 있어야 합니다. 없으면 Claude Code에게 "frontend의 vercel.json을 커밋하고 push해 줘"라고 다시 요청합니다.
- [참고] 자동으로 안 도는 것 같으면, 21.4의 프롬프트에서 push가
실제로 됐는지 확인하세요. GitHub의
- 배포가 Ready가 되면, 프로젝트 화면 위쪽의 Domains(도메인) 또는
Visit(방문) 버튼에 있는
https://vote-app-xxxx.vercel.app주소를 눌러 엽니다.
이제 그 HTTPS 주소에서 설문이 뜨고 투표가 되면, 뒤에서 이런 일이 벌어진
것입니다: 브라우저가 Vercel(https)에서 화면을 받고, 투표할 때 보낸
/api 요청을 Vercel 서버가 rewrite로 우리 ALB(http)에 대신 넘겼고,
ALB → ECS(api 컨테이너) → RDS로 이어져 결과가 돌아왔습니다.
[확인]
이번 장이 제대로 끝났는지 눈으로 확인합니다.
- Vercel이 준
https://...vercel.app주소로 접속하면, 주소창에 자물쇠(HTTPS) 가 보이고 투표 화면이 뜬다. - 14장에서 심어 둔 설문(예: "점심 뭐 먹지?")이 보이고, 선택지를 눌러 투표하면 득표수가 늘어난다. (14장과 같은 RDS 데이터를 쓰므로 같은 설문이 보입니다.)
- 브라우저에서 개발자 도구 → Network(네트워크) 탭을 연 채 투표를 한
번 해 봅니다.
/api/...요청이 목록에 뜨는데, 그 요청의 도메인이 내 Vercel 주소(https) 로 나갑니다. (ALB의 http 주소가 브라우저에 직접 보이지 않아야 정상입니다. ALB로의 연결은 Vercel 서버 뒤에서 일어나기 때문입니다.) - 콘솔(Console) 탭에 CORS나 Mixed Content(혼합 콘텐츠) 오류가 없다.
이 네 가지가 보이면, 프론트를 Vercel로 분리해 HTTPS로 배포하고 API는 기존 ECS·RDS를 그대로 쓰는 심화 완성에 도착한 것입니다. 이 짧은 HTTPS 주소를 친구에게 보내 보세요.
개발자 도구 여는 법
크롬·엣지에서 화면 위 아무 곳이나 마우스 오른쪽 클릭 → 검사(Inspect),
또는 F12(macOS는 Command + Option + I)를 누르면 개발자 도구가 열립니다.
위 탭에서 Network를 고른 뒤 페이지를 새로고침하고 투표해 보세요.
막히면
이 장에서 자주 나는 오류와 대처법입니다.
-
Vercel 빌드가 실패한다(빌드 로그가 빨갛게 끝난다). Root Directory를
frontend로 지정하지 않았을 때가 가장 많습니다. 저장소 바깥(backend가 섞인 곳)을 빌드하려다 깨집니다. Vercel 프로젝트 → Settings(설정) → Build & Development → Root Directory 를frontend로 바꾸고, Deployments 탭에서 Redeploy(재배포) 하세요. Framework가Vite로 잡혀 있는지도 함께 확인합니다. -
화면은 뜨는데 설문이 안 뜨고 투표가 안 된다.
/api가 ALB로 안 넘어가는 상태입니다.frontend/vercel.json이 GitHub에 올라가 있는지, 그 안destination의 ALB 주소에 오타가 없는지(앞에http://, 끝에/api/:path*) 확인하세요. 고쳤으면 git push하면 자동으로 다시 배포됩니다. 개발자 도구 Network에서/api요청의 응답 코드가 404면 경로가, 502/504면 ALB 주소나 ALB 상태가 의심됩니다. -
/api요청이 404로 나온다.source/destination의 경로가 실제 API 경로와 어긋난 경우입니다. 우리 API는/api로 시작하므로source가/api/:path*,destination이.../api/:path*여야 합니다(양쪽 다/api포함). 4장·14장에서 프론트가 정말/api를 부르는지도 확인하세요. -
/api요청이 502·504·타임아웃이 난다. Vercel 서버가 ALB에 닿지 못하는 상태입니다. (1) ALB DNS 주소 오타, (2) 14장 기본 완성이 지금도 살아 있는지(ALB 주소로 직접 접속해 확인), (3) ALB 보안 그룹(vote-alb-sg)이 인터넷(0.0.0.0/0)에서 80 포트를 허용하는지 확인하세요. Vercel 서버가 인터넷을 통해 ALB로 오므로, ALB는 지금처럼 누구나 접속 가능해야 합니다. (14.4에서 그렇게 열어 뒀습니다.) -
브라우저 콘솔에 Mixed Content나 CORS 오류가 보인다. 프론트가
/api상대 경로가 아니라 ALB의http://...절대 주소를 직접 부르고 있을 가능성이 큽니다(그러면 브라우저가 직접 http로 나가 혼합 콘텐츠에 걸립니다). Claude Code에게 "프론트의 API 호출이 절대 주소가 아니라 상대 경로/api로 나가는지 확인하고, 그렇게 고쳐 줘"라고 요청하세요(4.3~4.5 방식). 고친 뒤 push하면 Vercel이 다시 배포합니다. -
Vercel 저장소 목록에
vote-app이 안 보인다. 비공개 저장소라 Vercel에 권한이 없어서입니다. Import 화면의 Adjust GitHub App Permissions 링크로 GitHub에 가서,vote-app을 Vercel이 볼 수 있게 허용(All repositories 또는 select repositories에 추가)한 뒤 돌아옵니다. (21.3 참고.) -
git push했는데 Vercel이 다시 배포하지 않는다. push가 실제로 됐는지 GitHub
vote-app저장소에서frontend/vercel.json이 보이는지 확인하세요. 올라가 있는데도 안 돌면, Vercel 프로젝트 → Deployments 에서 오른쪽 위 Redeploy 로 수동 재배포하고, Settings → Git 에서 저장소 연결이 살아 있는지 확인합니다.
[체크리스트]
아래가 모두 됐는지 확인해 보세요. 하나라도 안 됐다면 해당 절로 돌아가 다시 진행합니다.
- □ 정적 호스팅·CDN·Vercel·rewrites가 무엇인지 한 줄로 설명할 수 있다 (21.1, 21.4)
- □ 연습용 정적 HTML 하나를 Vercel에 올려 HTTPS 주소로 열어 봤다 (21.1 맛보기)
- □ GitHub 계정으로 Vercel에 로그인했다 (21.2)
- □
vote-app을 Import하고 Root Directory를frontend로 지정해 배포했다 (21.3) - □ Framework가 Vite 로 감지된 것을 확인했다 (21.3)
- □
frontend/vercel.json에/api/:path*→http://<내 ALB DNS>/api/:path*rewrites를 넣고 push했다 (21.4) - □ git push로 Vercel이 자동 재배포되는 것을 Deployments 탭에서 봤다 (21.5)
- □ Vercel HTTPS 주소로 접속해 설문이 뜨고 투표가 된다 (21.5, 확인)
- □ 개발자 도구 Network에서
/api요청이 Vercel 도메인(https) 으로 나가고, 콘솔에 CORS·혼합 콘텐츠 오류가 없다 (확인)
모두 체크됐다면, 기본 완성(ECS+ALB) 위에 실무에서 흔한 "프론트 분리 배포 + HTTPS"까지 얹은 것입니다. 14장의 ALB 주소와 이번 Vercel 주소가 둘 다 살아 있고, 둘 다 같은 API·DB를 씁니다. (전체 여정에서 지금 어디쯤인지는 맨 앞 [지금 여기] 지도로 확인하세요.)