Project 1: Deploying a Static React Website on AWS with CI/CD (S3 + CloudFront + CodePipeline)

Table of contents

π Introduction
Deploying a React application might seem simple β until you want it production-ready with a custom domain, HTTPS, and automated CI/CD.
In this blog, Iβll walk you through how I deployed my own React website using AWS S3, CloudFront, CodePipeline, and GitHub β from scratch.
This guide is beginner-friendly, and everything I share here is based on the real steps (and errors π
) I experienced while learning.
Whether you're new to AWS or just looking to automate your frontend deployment β this post will give you everything you need to get your app live, fast, and secure.
β What Weβll Achieve
Host a static React app on AWS S3
Speed it up globally with CloudFront
Automate deployment with CodePipeline + GitHub
π οΈ Tools and Services Used
Purpose | Service |
Hosting | Amazon S3 |
CDN | CloudFront |
CI/CD | CodePipeline, CodeBuild |
Source Control | GitHub |
Build Automation | buildspec.yml |
πΆ Step 1: Clone Repo & React App Build
Clone repository on your machine.
If your GitHub repo has this structure:
project_chat_application/ βββ client/ β React app lives here βββ server/ β (optional) backend βββ README.md
You should run:
cd client npm install
Because your React app (package.json) is inside the
client/
folder β as seen from your earlier error logs.If your react app is in the root (like this):
my-app/ βββ package.json βββ public/ βββ src/
Then just run:
npm install
from the root folder itself.
πΆ Step 2: Build Your React App
npm run build
This will create a build/
folder with production files.
If you get errors like MODULE_NOT_FOUND
, just delete node_modules
and package-lock.json
, then reinstall:
rm -rf node_modules package-lock.json
npm install
npm run build
πΆ Step 3: Setup S3 Bucket for Hosting
Go to AWS S3 β Create Bucket
Name:
my-react-app-bucket
Uncheck "Block all public access"
Enable Static website hosting
- Index document:
index.html
- Index document:
- Set bucket policy for public access:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-react-app-chat/*"
}
]
}
Upload contents of the
build/
folder. (donβt upload whole build folder just upload content inside build folder). Like as shown in the picture below.
πΆ Step 4: Create CloudFront Distribution
Go to CloudFront β Create Distribution
Origin: your S3 website endpoint (Click on use website endpoint)
(Optional) Attach a custom domain and SSL from ACM
Select Do not enable security protection under Website Application Firewall (WAF), as shown in the picture below.
Viewer Protocol Policy: Redirect HTTP to HTTPS
Set Default Root Object to
index.html
Create distribution and copy the domain name it gives (like
d1abc123.cloudfront.net
)
πΆ Step 5: CI/CD with CodePipeline + CodeBuild
A. Start a new pipeline
- Go to AWS CodePipeline β Create pipeline
Select "Build custom pipeline"
Choose GitHub (via GitHub App)
Connect to github & Pick your repo + branch (like
master
)
Follow the steps as shown in below picture.
B. Add build stage:
- Use CodeBuild
Follow the given picture below
If your repo does not contain buildspec.yml file in root then create a buildspec.yml
in root:
version: 0.2
env:
variables:
NODE_OPTIONS: --openssl-legacy-provider
phases:
install:
commands:
- cd client
- npm install
build:
commands:
- npm run build
post_build:
commands:
- aws s3 sync build/ s3://my-react-app-chat --delete
artifacts:
files:
- '**/*'
Then select Use a buildspec file
Now select project under project name that we have create in codebuild.
πΆ Step 6: Test It
- Open the CloudFront domain or your custom domain.
Your React site should load with HTTPS and fast speed!
π Conclusion
What started as a simple goal β hosting a React app β turned into a full learning experience across AWS services.
By connecting S3, CloudFront, CodePipeline, and GitHub, I now have a fully deployed site with CI/CD automation. Along the way, I picked up how to handle errors, configure IAM roles, and make AWS work for frontend projects.
This project gave me a lot of confidence in working with AWS β and I hope it helps you too.
If you're stuck or want help adapting this setup to your own use case, feel free to reach out!
Thanks for reading to the end; I hope you gained some knowledge.β€οΈπ
Subscribe to my newsletter
Read articles from Vishesh Ghule directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Vishesh Ghule
Vishesh Ghule
I'm proficient in a variety of DevOps technologies, including AWS, Linux, Python, Docker, Git/Github, Shell Scripting, Jenkins and Computer Networking. My greatest strength is the ability to learn new things because I believe there is always room for self-development