Connecting S3-hosted React app with EC2 Django backend on AWS - CORS and communication issues

I built a task management app with a React frontend and Django REST backend that works perfectly on my local machine. Now I’m trying to deploy it on AWS’s free tier, but I’m having trouble getting the frontend and backend to communicate.

Current setup:

  • Frontend: React app hosted on an S3 bucket
  • Backend: Django REST API running on an EC2 instance
  • Local development worked fine with localhost.

Django settings.py configuration:

ALLOWED_HOSTS = ['*']
CORS_ALLOWED_ORIGINS = ['http://my-frontend-domain:3000']

React package.json proxy setting:

"proxy": "http://my-backend-ip:8000"

API calls in React:

fetch('/api/tasks/')
  .then(response => response.json())
  .then(data => console.log(data));

I thought switching from localhost to the actual IP addresses would solve it, but the frontend can’t reach the backend. I’ve opened all HTTP and HTTPS ports in security groups and have added an elastic IP to the EC2 instance.

Do I need a load balancer? Are SSL certificates required for cross-domain requests? Should the React app be configured differently when hosted on S3 versus local development?

Any guidance on the proper AWS deployment architecture would be helpful.

hmm interesting issue! quick question - when you say you’re using the proxy setting in package.json, that actually only works in development mode. once you build and deploy to s3, that proxy is gone. are you making api calls to the full ec2 url in your production build? also curious what error messages you’re seeing in browser devtools?

yep, the proxy thing is just for dev like climbingmonkey mentioned. make sure your api calls point to the full ec2 url, not just the relative paths. also, update cors_allowed_origins with your s3 bucket url. check if django’s really on port 8000 and accessible from outside, maybe try hitting the api directly.

Your proxy configuration is indeed the main culprit here. When React builds for production, the package.json proxy becomes irrelevant. I encountered this exact scenario when deploying my first full-stack application on AWS. You need to replace all relative API calls with absolute URLs pointing to your EC2 instance. Instead of fetch(‘/api/tasks/’), use fetch(‘http://your-ec2-elastic-ip:8000/api/tasks/’). Additionally, your CORS configuration should include your S3 bucket’s URL, not the development port. Set it to something like CORS_ALLOWED_ORIGINS = [‘https://your-bucket-name.s3.amazonaws.com’]. Make sure Django is actually listening on 0.0.0.0:8000, not just 127.0.0.1, otherwise external requests will be rejected regardless of security group settings.