This project runs the backend with Docker and the frontend locally without Docker.
- Removed Docker from the frontend (deleted
frontend/Dockerfileand removedfrontendservice fromdocker-compose.yml). - Updated
frontend/script.jsto usehttp://localhost:5000/apiforAPI_BASE. - Kept the backend containerized and exposed on port 5000.
- Verified Docker CLI/Compose were installed:
docker --versiondocker compose version
- The error on
docker compose upshowed the Docker engine wasn’t running. - Started Docker Desktop (Windows):
- Launch "Docker Desktop" from Start menu or run:
Start-Process "C:\\Program Files\\Docker\\Docker\\Docker Desktop.exe"
- Launch "Docker Desktop" from Start menu or run:
- Confirmed the engine was running with
docker info. - Simplified compose to backend-only by removing the
frontendservice fromdocker-compose.yml. - Rebuilt and started backend:
docker compose build --no-cache backenddocker compose up -d backend
- Verified backend health from the host:
curl http://localhost:5000/api/message- Expected response:
{ "message": "Hello from backend!" }
- Updated the frontend to call the backend via localhost (no Docker) by setting
API_BASEinfrontend/script.jstohttp://localhost:5000/api.
- Build and start:
docker compose up -d --build backend
- Logs:
docker compose logs -f backend
- Health check:
curl http://localhost:5000/api/message
- Open
frontend/index.htmlin a browser, or serve thefrontendfolder with a static server.- Example (PowerShell):
python -m http.server 8080insidefrontend/ - Then browse
http://localhost:8080
- Example (PowerShell):
- The frontend is configured to call the backend at
http://localhost:5000/api.
- Ensure Docker Desktop is running before using Docker commands on Windows.
- If port 5000 is busy, change the host port in
docker-compose.ymlunder thebackendserviceportsmapping (left side ofhost:container).
Yes, you can absolutely deploy the frontend to AWS S3 static hosting with CloudFront for CDN and SSL termination!
- S3: Hosts your static files (HTML, CSS, JS)
- CloudFront: Provides CDN, SSL/TLS termination, and custom domain support
- Backend: Remains on your server (e.g., EC2, ECS, EKS, or Application Load Balancer)
-
Update API Configuration:
- Before deploying, update
frontend/config.js:window.API_BASE_URL = 'https://your-backend-api-domain.com/api';
- Before deploying, update
-
Prepare Frontend Files:
- Upload all files from
frontend/directory to S3:index.htmlscript.jsconfig.jsstyles.css
- Upload all files from
-
Configure S3 Bucket:
- Enable static website hosting
- Set
index.htmlas the index document - Configure bucket policy for public read access (or restrict via CloudFront)
-
Create CloudFront Distribution:
- Origin: Point to your S3 bucket (use S3 website endpoint or REST API endpoint)
- Default root object:
index.html - SSL Certificate: Request or import an ACM certificate for your domain
- Behavior: Cache static assets, but configure cache behavior for
index.htmlto avoid stale content
-
Configure CORS on Backend:
- Your backend already has CORS enabled via
flask-cors - Ensure your backend allows requests from your CloudFront domain:
# In app.py, you may need to specify allowed origins: CORS(app, origins=["https://your-frontend-domain.com"])
- Your backend already has CORS enabled via
-
DNS Configuration:
- Create a DNS A record (or CNAME) pointing to your CloudFront distribution
- ✅ Global CDN for faster content delivery
- ✅ Free SSL/TLS certificates via CloudFront
- ✅ Low-cost static hosting (S3 + CloudFront)
- ✅ Custom domain support
- ✅ Separation of concerns (static frontend, dynamic backend)
- CORS: Your backend already has CORS enabled, which is required for S3-hosted frontend to call your API
- API Endpoint: Update
config.jswith your production backend URL before deployment - Cache Invalidation: After deploying updates, invalidate CloudFront cache for
/index.htmland/config.jsto ensure users get the latest version - Backend Deployment: Your backend needs to be publicly accessible and configured to allow requests from your CloudFront domain
NOTE: Don't forgrt to add the user of docker hub as collabarator before pushing image in docker hub if you are using it. Thats a stupid mistake.