Intro
React로 만든 웹사이트를 로컬에서 완성했더라도,
사용자가 언제 어디서나 빠르고 안정적으로 접속하려면 배포가 필요합니다.
배포 플랫폼은 다양하지만, 이번 글에서는 AWS S3 + CloudFront 조합을 사용합니다.
왜 S3 + CloudFront일까요?
- S3: HTML, CSS, JS 등 정적 파일을 안전하게 저장하고 웹으로 제공하는 안정적인 스토리지
- CloudFront: AWS의 글로벌 CDN으로 전 세계 사용자에게 빠른 응답 속도와 HTTPS 보안을 제공
- 조합의 장점: 안정성, 속도, 보안을 모두 확보 가능
물론 더 간편한 방법도 있습니다.
예를 들어 Vercel은 GitHub 연동만으로 자동 빌드·배포가 가능하지만, 무료 요금제에서는 빌드 시간·대역폭 제한이 있고 인프라를 직접 제어하기 어렵습니다.
반면 S3 + CloudFront는 인프라를 직접 구성·관리할 수 있어, 대규모 트래픽 대응부터 캐시 정책·라우팅·보안 설정까지 세밀하게 조정할 수 있습니다.
이번 글에서는 React 웹을 AWS S3 + CloudFront로 배포하는 과정을 단계별로 안내합니다.
순서대로 따라 하면 AWS 인프라 위에서 안정적인 서비스를 운영할 수 있습니다.
다음 편에서는 여기에 나만의 도메인 연결과 HTTPS 적용까지 이어갈 예정입니다.
AWS S3 + CloudFront 개요
React 웹을 배포할 때 S3와 CloudFront는 서로를 보완하며 작동합니다.
각 서비스를 이해하면, 이 조합이 배포에서 자주 쓰이는 이유를 바로 알 수 있습니다.
1. S3 (Amazon Simple Storage Service)
-
정적 파일 저장소HTML, CSS, JavaScript, 이미지 등 정적 파일을 안전하게 저장
-
정적 웹 호스팅 지원별도의 서버 없이도 웹 페이지 제공 가능
-
저렴하고 확장성 높음트래픽 증가 시 자동 확장, 사용량 기반 과금
2. CloudFront
-
CDN(Content Delivery Network)전 세계 엣지 로케이션에 콘텐츠를 캐싱해, 사용자와 가까운 서버에서 전달
-
HTTPS 지원무료 SSL 인증서 제공으로 안전한 통신 가능
-
세부 제어 가능캐시 기간, 접근 권한, 헤더 설정 등 세밀한 정책 적용 가능
3. S3와 CloudFront를 함께 쓰는 이유
-
속도 향상S3 단독 호스팅보다 전 세계 어디서나 더 빠른 로딩 속도 제공
-
보안 강화Origin Access Control(OAC)로 S3를 비공개로 유지하면서 CloudFront만 접근 허용
-
안정적인 확장성대규모 트래픽 상황에서도 안정적 서비스 가능
-
세밀한 설정캐시 무효화, SPA 라우팅, 보안 헤더 추가 등 정밀 제어 가능
S3 버킷 생성하기
일반 구성

- AWS 리전: 현재 로그인한 콘솔의 기본 리전이 자동으로 선택됩니다. 저는 배포 위치를 한국 사용자에게 최적화하기 위해 아시아 태평양(서울) 리전을 선택했습니다.
- 버킷 이름: 전 세계적으로 고유해야 하며, 소문자·숫자·하이픈만 사용할 수 있습니다.
- 기존 버킷에서 설정 복사: 다른 버킷의 설정값만 가져오는 기능입니다. 객체(파일)는 복사되지 않고, 접근 권한, 버전 관리, 암호화 같은 설정만 복사됩니다.
이번 배포에서는 Baro 프로젝트의 클라이언트 사이트를 올릴 예정이기 때문에, 프로젝트 이름을 반영한
baro-client
라는 버킷 이름을 사용했습니다. 이렇게 하면 추후 여러 프로젝트를 구분하기에도 좋습니다.객체 소유권 및 퍼블릭 설정

객체 소유권 설정
-
ACL 비활성화(권장)
를 선택했습니다.이 옵션을 사용하면 버킷과 그 안의 모든 객체의 소유권이 현재 계정으로 통일됩니다. ACL(액세스 제어 목록)은 사용하지 않고, 대신 버킷 정책을 통해 접근 권한을 관리합니다. 이렇게 하면 권한 설정이 단순해지고 보안 관리가 쉬워집니다.
퍼블릭 액세스 차단 설정
-
모든 퍼블릭 액세스 차단을 체크했습니다.기본적으로 S3는 외부에서 함부로 접근할 수 없도록 퍼블릭 액세스를 차단하는 것이 안전합니다.단, 나중에 CloudFront를 연결할 때는 퍼블릭 액세스를 풀지 않고도 접근할 수 있도록 Origin Access Control(OAC)을 사용할 예정입니다.
Tip: React 웹을 직접 S3 정적 웹 호스팅으로만 배포하는 경우엔 퍼블릭 접근 허용이 필요하지만, CloudFront를 거칠 땐 이렇게 차단해도 무방합니다.
이 외

버전 관리
-
비활성화를 선택했습니다.버전 관리는 같은 객체의 여러 버전을 저장하고 복원할 수 있는 기능입니다. 프로젝트에 따라 유용할 수 있지만, 정적 웹 배포에서는 필요하지 않고 저장 공간(비용)을 불필요하게 차지할 수 있습니다.추후 파일 이력 관리가 필요하다면 활성화할 수 있습니다.
태그
-
태그는 버킷에 라벨을 붙여 비용 추적이나 프로젝트 구분을 쉽게 하는 기능입니다.이번 배포에서는 태그 없이 진행하지만, 회사나 팀 단위 프로젝트에서는 프로젝트명·환경(dev/prod) 같은 태그를 지정하면 관리가 편리합니다.
기본 암호화
-
Amazon S3 관리형 키(SSE-S3)
를 선택했습니다.이 옵션은 S3가 자동으로 서버 측에서 객체를 암호화해 저장합니다. 따로 키를 관리할 필요가 없고, 기본 보안이 보장됩니다.AWS KMS를 사용하면 직접 키를 관리할 수 있지만, 비용이 추가되고 설정이 복잡해질 수 있습니다.
React 빌드 파일 업로드
- 로컬에서
npm run build
또는yarn build
실행 →build
폴더 생성 - 폴더 안의 내용물만 선택해 AWS S3 콘솔의 버킷으로 드래그 앤 드롭
Tip:
build
폴더 자체를 업로드하면 경로가 꼬여 CloudFront에서 파일을 찾지 못합니다.정적 웹 사이트 호스팅
S3 버킷 속성 탭 → 페이지 맨 아래 정적 웹 사이트 호스팅 섹션 이동

편집 버튼 클릭 후 아래와 같이 설정

정리하면 다음과 같습니다.
-
S3 버킷으로 이동AWS S3 콘솔에서 방금 생성한 버킷을 클릭한 후, 속성 탭으로 들어갑니다.
-
정적 웹 사이트 호스팅 활성화페이지를 맨 아래까지 스크롤하면 정적 웹 사이트 호스팅 섹션이 보입니다.편집 버튼을 눌러 설정 화면으로 들어갑니다.
-
설정 값 입력
- 호스팅 유형: 정적 웹 사이트 호스팅 활성화 선택
- 인덱스 문서: index.html
CloudFront 배포 생성
Get started 단계

- Distribution name
- CloudFront 배포 이름. 관리 편의를 위해 S3 버킷명과 동일하게 설정
- 저는 S3 버킷 이름과 동일하게
baro-client
로 입력했습니다.
- Description (optional)
- 배포에 대한 간단한 설명을 추가할 수 있습니다.
- 필수는 아니므로 필요할 때만 입력합니다.
- Distribution type
- Single website or app: 하나의 웹사이트 또는 애플리케이션을 배포할 때 선택합니다.
- Multi-tenant architecture: 여러 도메인에서 동일한 설정을 공유해야 하는 SaaS 환경에 적합합니다.
- 저는 React 웹앱 단일 배포이므로
Single website or app
을 선택했습니다.
Specify origin 단계

S3 origin
- baro-client.s3.ap-northeast-2.amazonaws.com
- CloudFront가 가져올 콘텐츠의 원본(오리진) 주소입니다.
- 여기서는 방금 만든 S3 버킷이 오리진이 됩니다.
Origin path (optional)
- 오리진 내부의 특정 하위 폴더만 지정해서 CloudFront가 가져오도록 하는 옵션입니다.
- 예를 들어 S3 버킷 안에
/build
폴더만 배포하고 싶다면/build
를 입력하면 됩니다. - 비워두면 S3 버킷 전체를 대상으로 합니다.
- 저는 build 폴더 안에 파일들을 올렸기때문에 비워두었습니다.

Allow private S3 bucket access to CloudFront
- 체크하면 CloudFront가 OAC(Origin Access Control)를 통해 S3 버킷에 접근할 수 있도록 권한을 자동 부여합니다.
- Public Access를 열지 않고도 CloudFront에서만 S3를 읽을 수 있게 하므로 보안상 권장됩니다.
Origin settings
- Use recommended origin settings: AWS가 권장하는 기본값을 사용 (대부분의 경우 이걸 선택)
- Customize origin settings: 캐시 동작, 요청 정책 등을 직접 설정
Cache settings
- CloudFront가 콘텐츠를 얼마나 오래 캐싱할지, 어떤 조건에서 원본에서 다시 가져올지를 결정
- 기본적으로 S3에 최적화된 캐시 정책이 적용됩니다.
저는 Settings 부분은 기본 값으로 뒀습니다.
Enable security 단계

AWS WAF란
AWS WAF는 웹 애플리케이션 방화벽으로, 웹 애플리케이션을 공격이나 취약점으로부터 보호하는 서비스입니다.
예를 들어 다음과 같은 공격을 방어합니다.
- SQL Injection
- Cross-Site Scripting (XSS)
- 악성 봇 트래픽
- 특정 국가/지역 또는 IP 주소 차단
저는 비활성화를 선택했습니다.
이후 설정들
배포한 CloudFront에 들어가서 배포 도메인으로 사이트에 접속을 해보면

해당 화면과 비슷한 화면이 나올것입니다. 일단 여기까지 왔으면 거의 다 된겁니다.
일반에서 설정 편집을 들어가면 밑과 같은 화면이 나올텐데.

Default root object를
index.html
로 설정합니다.CloudFront는
/
경로 요청 시 지정한 기본 파일을 반환합니다.기본 파일을 지정하지 않으면 403 또는 404 오류가 발생할 수 있습니다.
React, Vue, Angular 같은 SPA는 모든 라우팅을 클라이언트에서 처리하므로,
서버는 모든 경로에 대해
index.html
을 반환해야 합니다.이후 자바스크립트 라우터가 알맞은 페이지를 렌더링합니다.
마지막으로, 오류 페이지 설정에서 403/404 상태 코드에 대해
index.html
을 반환하도록 지정하면 배포가 완료됩니다.

Outro
이제 CloudFront 배포 도메인에 접속하면, 방금 업로드한 React 웹사이트가 정상적으로 표시됩니다.

여기까지 완료했다면 AWS S3 + CloudFront를 활용한 기본 배포 과정이 끝났습니다.
다음 단계에서는 맞춤 도메인 연결과 HTTPS 적용을 통해, 더 전문적이고 신뢰성 있는 서비스 환경을 구축하는 방법을 알아보겠습니다.