A production-ready Todo App with React frontend and FastAPI backend, deployable on Azure Linux VMs using either public IP or private IP via NGINX proxy. Perfect for DevOps learners deploying fullstack apps to the cloud.
Depending on your working style, pick one of the two:
- Code, build & run everything inside the VMs.
- No file transfer needed.
π Go to: π VM-Based Setup
- Develop and build React frontend locally.
- Copy
build/output to frontend VM.
π Go to: π Local Build + VM Deploy
todo-frontend/
βββ public/
βββ src/
β βββ TodoApp.js # Frontend logic + backend API URL config
βββ build/ # Created after `npm run build`
βββ package.json
βββ README.md
On VM or Local, ensure:
- β Node.js (v16.x)
- β npm
- β Python 3.8+
- β pip
To install Node.js on Ubuntu:
curl -s https://deb.nodesource.com/setup_16.x | sudo bash
sudo apt install nodejs -yssh username@<vm-public-ip>git clone https://github.com/Riteshatri/todoFrontendReactMonolithic.git
cd todoFrontendReactMonolithicβ‘οΈ Open the frontend config file and update the backend API URL.
nano src/TodoApp.jsThen update:
const API_BASE_URL = 'http://<backend-vm-public-ip>:8000/api';const API_BASE_URL = 'http://<frontend-vm-public-ip>/api';sudo su
sudo apt update
sudo apt install nginx -y
systemctl enable nginx
systemctl start nginxnpm install
npm run buildpip install fastapi uvicorn mysql-connector-python
uvicorn main:app --host 0.0.0.0 --port 8000sudo apt update
sudo apt install nginx -y
sudo nano /etc/nginx/sites-available/defaultπ Add this block just above the line root /var/www/html;:
location /api {
proxy_pass http://<PrivateIP-of-backend-vm>:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}Then restart:
sudo service nginx restartsudo rm -rf /var/www/html/*
sudo cp -r build/* /var/www/html/
sudo service nginx restartgit clone https://github.com/Riteshatri/todoFrontendReactMonolithic.git
cd todoFrontendReactMonolithicβ‘οΈ Open the frontend config file and update the backend API URL.
Edit API in src/TodoApp.js as explained below: -
- Open the
src/TodoApp.jsfile in VS Code, Notepad++, or any text editor. - Find the line where
API_BASE_URLis defined.
Then update:
const API_BASE_URL = 'http://<backend-vm-public-ip>:8000/api';sudo apt update
sudo apt install nginx -y
sudo nano /etc/nginx/sites-available/defaultconst API_BASE_URL = 'http://<frontend-vm-public-ip>/api';These all steps should be followed into our vm...
sudo su
apt update
apt install nginx -y
systemctl enable nginx
systemctl start nginxπ Add this block just above the line root /var/www/html;:
location /api {
proxy_pass http://<PrivateIP-of-backend-vm>:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}Then restart:
sudo service nginx restartnpm install
npm run buildscp -r build/* username@<frontend-vm-ip>:/home/username/ssh username@<frontend-vm-ip>
sudo apt update && sudo apt install nginx -ysudo rm -rf /var/www/html/*
sudo cp -r /home/username/* /var/www/html/
sudo service nginx restartπ Azure SQL Firewall Rule (When infrastructure/Code is made/written in terraform , instead of azure portal)
Follows these steps to connect backend to Azure SQL:
- Go to Azure Portal
- Find your SQL Server β Networking
- Add a firewall rule:
- Name:
backend-vm-access - Start IP = End IP =
<backend-vm-public-ip>
- Name:
- Click Save
| You Build Where | Backend Communication | Needed Setup | Access App At |
|---|---|---|---|
| VM | Public IP | FastAPI only | http://backend-ip:8000/api |
| VM | Private IP + NGINX | NGINX proxy + FastAPI | http://frontend-ip/api |
| Local | Public IP | SCP + NGINX (simple) | http://frontend-ip |
| Local | Private IP + NGINX | SCP + NGINX proxy setup | http://frontend-ip/api |
- β
Run
uvicornand check if backend is listening on 8000. - β
Visit
http://<frontend-ip>in your browser. - β
Check browser DevTools β Network β API calls hitting
/api/todos
Pull requests are welcome. For major changes, please open an issue first.
MIT License
Ritesh Sharma
π LinkedIn