This content originally appeared on DEV Community and was authored by Yash Sonawane
“What if every time you push to GitHub, your website updated itself within minutes?”
Welcome to the world of automated deployments! In this post, weβll build a CI/CD pipeline that deploys a React app to Amazon S3 and serves it globally via CloudFront, all powered by GitHub Actions.
Perfect for developers who want to move fast, stay lean, and look like pros.
What Weβll Cover
- Build and host a React app on S3
- Connect CloudFront for global delivery
- Use GitHub Actions to auto-deploy on every push
- Add cache invalidation so users always get the latest version
Think of this like a pizza shop that bakes, boxes, and delivers your app every time you update the ingredients (code)!
Prerequisites
- AWS account with access to S3, CloudFront, and IAM
- React project (Create with
npx create-react-app my-app
) - GitHub repo with your React app
- Basic familiarity with GitHub Actions and AWS CLI
Step 1: Create an S3 Bucket for Static Hosting
- Go to the AWS S3 Console
- Create a new bucket:
my-react-app-bucket
- Uncheck “Block all public access” (for static hosting)
- Enable Static Website Hosting
- Note the bucket URL (youβll need it later)
Bucket policy example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-react-app-bucket/*"
}
]
}
Step 2: Set Up CloudFront
- Go to the CloudFront Console
- Create a new distribution:
- Origin: Your S3 bucket website endpoint
- Viewer Protocol Policy: Redirect HTTP to HTTPS
- Cache Behavior: Set TTLs, enable compression
- Optional: Add a custom domain with ACM SSL
Save the CloudFront domain (e.g.
d1234xyz.cloudfront.net
)
Step 3: Create IAM User for GitHub Actions
- Go to IAM β Create user
github-deploy-user
- Attach permissions:
AmazonS3FullAccess
-
CloudFrontFullAccess
- Download Access Key ID & Secret
Store these as GitHub Secrets:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
-
DISTRIBUTION_ID
(CloudFront ID) -
S3_BUCKET_NAME
(your bucket)
Step 4: Add GitHub Actions Workflow
Create .github/workflows/deploy.yml
in your repo:
name: Deploy React App to S3 + CloudFront
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Build app
run: npm run build
- name: Sync to S3
run: |
aws s3 sync build/ s3://$S3_BUCKET_NAME --delete
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: us-east-1
- name: Invalidate CloudFront cache
run: |
aws cloudfront create-invalidation --distribution-id $DISTRIBUTION_ID --paths "/*"
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: us-east-1
Bonus: Speed Tips
- Add a custom domain with Route 53
- Use S3 lifecycle rules to manage stale assets
- Enable gzip + Brotli in CloudFront for performance
Done! Push & Deploy
Now, every time you git push
, your app:
- Builds
- Uploads to S3
- Invalidates the CloudFront cache
- Goes live globally
Zero manual steps. Just speed and satisfaction.
What Will You Build Next?
Will you use this pipeline for:
- Your portfolio site?
- A React landing page for your startup?
- A client dashboard?
Share your use case, tips, or questions below!
If you loved this, smash that and share with someone building React apps.
Letβs deploy smart, fast, and like pros.
This content originally appeared on DEV Community and was authored by Yash Sonawane