mason
mason-log.

GitHub 로그인 중

AWS 배포, 한 번에 정리하기.
mason

masonfe-hyunsu

✏️ 1. 개요.

  • 프론트엔드 결과물을 AWS에 올릴 때, 서비스 이름이 많아서 처음엔 역할이 헷갈리기 쉽다.

  • 실무에서 자주 보는 건 대략 이 네 가지다.

    • S3: 정적 파일 보관

    • CloudFront: 사용자 진입점 + 캐시

    • EC2: 서버 한 대

    • ECS: 서버를 서비스처럼 운영

  • 이 포스팅에서는 설정 매뉴얼보다, 프론트 관점에서 언제 무엇을 쓰는지를 흐름으로 정리해 본다.


🤔 2. 전체 그림 먼저.

  • 배포 구조는 하나로 고정되지 않는다.

  • 프로젝트 성격에 따라 자주 쓰는 패턴만 먼저 보면 이해가 빠르다.

  • 정적 사이트: 사용자 → CloudFront → S3

  • 정적 + API 분리: CloudFront → S3 + API 도메인 → EC2/ECS

  • SSR/동적 렌더링: 사용자 → CloudFront → EC2/ECS

  • 내부/테스트: CloudFront 없이 서버 도메인으로 바로 접근하기도 한다.

정적 / 정적+API / SSR 배포 구조 비교
  • 정적: 빌드 결과물(HTML, CSS, JS)만 전달하면 되는 경우

  • 정적 + API: 화면은 S3, 데이터는 별도 서버

  • SSR: 서버가 HTML을 만들어 주는 경우


🗂️ 3. S3 : 파일 보관함.

  • S3는 프론트 빌드 결과물을 올려두는 정적 파일 저장소다.

  • 쉽게 말하면, 코드를 실행하는 곳이 아니라 보관하는 곳이다.

하는 일:

  • HTML, CSS, JS, 이미지 저장

  • 정적 파일 전용

  • 서버처럼 로직을 돌리진 않음

프론트에서 알아둘 점:

  • npm run build 결과물을 올리는 곳이 보통 S3다.

  • 올렸다고 끝이 아니다. CloudFront 캐시 때문에 화면이 안 바뀌는 이슈가 자주 따라온다.


🌍 4. CloudFront : 앞단 입장권.

  • CloudFront는 사용자 요청이 가장 먼저 닿는 프론트 도메인 진입점이다.

  • CDN이라서, 사용자와 가까운 위치에서 파일을 빠르게 내려준다.

요청 흐름은 대략 이렇다.

유저 요청 → CloudFront

(캐시 있음)
→ 바로 응답

(캐시 없음)
→ S3/서버에서 가져와 캐싱 후 응답
  • 캐시가 있으면 CloudFront가 바로 응답한다.

  • 없으면 뒤(S3 또는 서버)에서 가져와 다시 캐시에 넣는다.

CloudFront 캐시 hit/miss 흐름

프론트에서 알아둘 점:

  • "배포했는데 화면이 그대로"면, 코드 문제보다 캐시 문제를 먼저 의한다.

  • index.html과 해시 붙은 JS/CSS의 캐시 정책을 다르게 두는 경우가 많다.


⚡ 5. CloudFront Functions : 요청 살짝 가로채기.

  • CloudFront Functions는 요청이 S3/서버로 가기 전에 엣지에서 도는 작은 로직이다.

  • 무겁고 복잡한 서버 대신, 가벼운 분기용으로 쓴다.

자주 쓰는 용도:

  • URL 리다이렉트

  • 헤더 수정

  • 간단한 인증/분기

  • A/B 테스트

예시:

/ko → /ko/index.html
모바일 요청이면 다른 경로로 보내기

프론트에서 알아둘 점:

  • 라우팅 규칙을 앱 코드가 아니라 엣지에서 처리할 수도 있다.

  • 클라이언트 코드를 안 고쳐도 요청 규칙을 빠르게 바꿀 수 있다.


🖥️ 6. EC2 : 서버 한 대.

  • EC2는 가장 기본적인 서버(가상 머신)다.

  • Node 서버, API, SSR처럼 무언가 실행해야 할 때 쓴다.

이런 경우에 많이 본다:

  • Node 서버 실행

  • API 서버

  • SSR 페이지 응답

프론트에서 알아둘 점:

  • 정적 배포(S3 + CloudFront)와 난이도가 다르다.

  • 배포, 모니터링, 장애 대응까지 운영 책임이 커진다.

  • 혼자 쓰는 서비스, 트래픽이 크지 않은 시작 단계에서는 여전히 현실적인 선택이다.


🐳 7. ECS : 서버를 서비스처럼 운영.

  • ECS는 컨테이너(Docker)를 단위로 서비스를 돌리는 관리 계층이다.

  • 한 줄로 비교하면 이렇다.

    • EC2: 서버 한 대

    • ECS: 서버 여러 대를 자동으로 관리

ECS가 해주는 일:

  • Docker 컨테이너 실행

  • 트래픽 늘면 확장

  • 장애 나면 재시작

프론트에서 알아둘 점:

  • SSR/API 트래픽이 커지고 자동 복구, 확장이 필요하면 EC2 한 대보다 ECS가 운영 선택지에 가까워진다.

  • "서버에 배포한다"에서 "서비스로 운영한다"로 넘어가는 단계라고 보면 된다.


🔗 8. 프론트에서 자주 보는 구조.

(1) 정적 사이트. (가장 흔함)

User → CloudFront → S3
  • 예: React SPA, 정적 export한 Next, 랜딩, 블로그

  • 운영 포인트는 서버보다 캐시 무효화, 파일 버전 관리다.

(2) 정적 + API.

User
 ├→ CloudFront → S3 (화면)
 └→ API 도메인 → EC2 / ECS (데이터)
  • 화면과 API를 나눠 운영하는 구조다.

  • 프론트 배포와 API 배포 주기가 달라져도 서로 덜 묶인다.

(3) SSR / 동적 페이지.

User → CloudFront → ECS(or EC2)
                 ↘ Functions (리다이렉트/헤더)
  • 로그인 상태별 HTML, SEO, 공유 미리보기처럼 서버에서 화면을 만들 때 쓴다.

세 가지 배포 패턴 한눈에 보기
  • 위 세 패턴만 구분해도, 대부분의 프론트 배포 대화를 따라가기 쉽다.


📦 9. Docker 배포는 어디에 붙나.

  • 정적 파일만이면 S3 + CloudFront로 끝이다.

  • SSR/API가 있으면 실행 환경이 필요하다.

실무에서 자주 보는 흐름:

코드 변경
→ Docker 이미지 빌드
→ ECR에 push
→ ECS(or EC2)에 배포

역할만 보면:

  • Docker: 실행 환경을 이미지로 묶는다

  • ECR: 그 이미지를 저장하는 창고

  • ECS/EC2: 이미지를 실제로 실행

S3/CloudFront = 정적 전달 경로
Docker + ECR + ECS(EC2) = 서버 실행 경로


🎯 10. 고르기 전에 스스로 묻는 질문.

  • 이 화면은 정적 파일인가, 서버 렌더링인가?

  • 배포 후 안 바뀌면 코드 문제인가, 캐시 문제인가?

  • 리다이렉트는 앱 코드에서 하나, CloudFront Functions에서 하나?

  • API/SSR이 있다면 EC2 한 대로 충분한가, ECS가 필요한가?

React / Next로 바꿔 보면.

React SPA. (CSR)

  • SEO 비중이 낮고 로그인 이후 화면 중심이면 S3 + CloudFront가 가장 단순하다.

SSR / 동적 응답이 필요할 때.

  • 초기 HTML이 중요하거나, 서버에서 화면을 만들어야 하면 런타임이 필요하다.

  • 초기 단순성이 중요하면 EC2, 확장과 복구 자동화가 중요하면 ECS를 검토한다.

Next.js App Router.

  • output: "export"처럼 정적 export면 S3 + CloudFront로 충분한 경우가 많다.

  • route.ts, 서버 액션, 동적 렌더링을 쓰면 런타임이 필요해서 ECS(또는 서버리스) 쪽을 본다.

  • App Router 자체보다, 서버 기능을 얼마나 쓰느냐가 핵심이다.


💡 11. 정리.

S3         = 정적 파일 보관
CloudFront = 진입점 + CDN + 캐시
Functions  = 요청 전처리
EC2        = 서버 한 대
ECS        = 서버 운영 자동화

실무에서 빠르게 보는 순서:

  1. 정적 파일인가? → S3

  2. 사용자 진입점, 캐시는? → CloudFront

  3. 서버 실행이 필요한가? → EC2 또는 ECS

  4. 요청 분기/전처리가 필요한가? → Functions

결국 AWS 서비스 이름을 외우는 일보다, 지금 필요한 게 보관인지, 캐시인지, 실행인지를 먼저 가르는 편이 덜 헷갈렸다.


🔗 12. 참고 자료.

이전 글
Next.js App Router.

댓글

불러오는 중...
목록으로