1 Connect to Backend VM
SSH into your Ubuntu virtual machine to begin the deployment process.
# SSH into your Ubuntu VM
ssh user@your-backend-vm-ip
# Example:
# ssh ritesh@20.123.45.67
2 Install System Dependencies
Install all required system packages including Python 3.12, build tools, and database drivers.
# Update package list
sudo apt update
# Install required packages
sudo apt install -y build-essential python3.12 python3.12-venv python3-pip unixodbc-dev git
# Verify Python version
python3.12 --version
# Should show: Python 3.12.x
3 Transfer Backend Code to VM
Choose one of the following methods to transfer your code:
Option A: Using SCP
From your Windows PowerShell:
scp -r "E:\path\to\backend" user@vm-ip:"~/"
Option B: Using Git
On your Ubuntu VM:
cd /home/user
git clone <your-repo-url>
cd your-repo/backend
4 Create Virtual Environment
Set up an isolated Python environment for your dependencies.
# Navigate to backend folder
cd /home/user/backend
# Create virtual environment
python3 -m venv venv
# Activate it
source venv/bin/activate
# You should see (venv) in prompt
(venv) at the beginning of your terminal prompt.
5 Install Python Dependencies
Install all required Python packages from requirements.txt.
# Make sure (venv) is active!
pip install --upgrade pip
pip install -r requirements.txt
6 Create Environment Configuration
Set up your environment variables with database credentials and configuration.
# Create environment file
sudo nano .env
Add this content:
AZURE_SQL_SERVER=ritserver.database.windows.net
AZURE_SQL_DATABASE=ritserver
AZURE_SQL_USERNAME=ritserver
AZURE_SQL_PASSWORD=Ritesh@12345
SECRET_KEY=1f7abb32c57632c35cbf57657f20ca104d88e18dd3cb17050649b10664cd743f
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30
CORS_ORIGINS=["*"]
FRONTEND_URL=http://4.245.193.71:5000
7 Test Backend Manually First
Before creating a service, verify that your backend runs correctly.
# Make sure you're in backend folder with venv active
source venv/bin/activate
python run.py
INFO: Uvicorn running on http://0.0.0.0:8000 ✅ Server configured for: ritserver.database.windows.net ✅ Protected admin user created: ritesh@apka.bhai INFO: Application startup complete.
Test it in another terminal:
curl http://localhost:8000/health
# Should return: {"status":"healthy"}
8 Create Systemd Service
Set up auto-start service for production deployment.
# Create service file
sudo nano /etc/systemd/system/resource-backend.service
Add this content:
[Unit]
Description=Resource Management Backend API
After=network.target
[Service]
Type=notify
User=ritesh
WorkingDirectory=/home/ritesh/
Environment="PATH=/home/ritesh/venv/bin"
EnvironmentFile=~/.env
ExecStart=/home/ritesh/venv/bin/gunicorn app.main:app --workers 3 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000 --timeout 120
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
ritesh with your actual username! Update paths accordingly.
9 Install Gunicorn
Install the production-grade WSGI server.
source venv/bin/activate
pip install gunicorn
10 Start and Enable Service
Activate your backend service and enable auto-start on boot.
# Reload systemd
sudo systemctl daemon-reload
# Enable service (start on boot)
sudo systemctl enable resource-backend
# Start service
sudo systemctl start resource-backend
# Check status
sudo systemctl status resource-backend
● resource-backend.service - Resource Management Backend API Loaded: loaded (/etc/systemd/system/resource-backend.service; enabled) Active: active (running) since ...
11 Configure Firewall Optional
Allow incoming connections on port 8000.
# Allow port 8000
sudo ufw allow 8000/tcp
# Check firewall status
sudo ufw status
12 Test External Access
Verify your backend is accessible from outside the VM.
# From your Windows laptop:
curl http://YOUR-BACKEND-VM-IP:8000/health
# Should return: {"status":"healthy"}
🔥 What is Systemd Service?
Systemd Service = Your backend app running permanently in the background
Just like Windows has "Services" (Service Manager → keeps apps running even when no user is logged in, restarts automatically, survives reboots)… ✅ Linux uses systemd services to do the same job.
❓ Why Do You Need a Systemd Service?
If you run your backend manually like this:
uvicorn app.main:app --host 0.0.0.0 --port 8000
# or
python run.py
Then these problems occur:
- ❌ Closing SSH → the app stops
- ❌ Closing the terminal → the app stops
- ❌ VM reboot → the app stops
- ❌ App crashes → the app stops
✔ What Systemd Gives You
A systemd service ensures:
✓ Background Execution
Your app runs in daemon mode, independent of your SSH session.
✓ Auto-start on Boot
App starts automatically when VM restarts.
✓ Auto-restart on Crash
If the app crashes, systemd restarts it automatically.
✓ Proper Logging
You get structured logs using journalctl.
✓ Easy Management
Start/stop/restart like any Linux service.
✓ Production Ready
Works exactly like Windows Services.
🧠 Service Management Commands
Essential commands to control your backend service:
# Start the service
sudo systemctl start resource-backend
# Stop the service
sudo systemctl stop resource-backend
# Restart the service
sudo systemctl restart resource-backend
# Check service status
sudo systemctl status resource-backend
# Enable auto-start on boot
sudo systemctl enable resource-backend
# Disable auto-start
sudo systemctl disable resource-backend
# View service logs
sudo journalctl -u resource-backend -f
📁 Service File Location
To run your backend as a service, create a file at:
/etc/systemd/system/resource-backend.service
This is the Linux equivalent of Windows Services — simple and powerful.
🔍 Service Not Starting
Check service status and logs:
sudo systemctl status resource-backend
sudo journalctl -u resource-backend -n 50
🔍 Permission Errors
Verify file permissions and ownership:
# Check ownership
ls -la /home/ritesh/backend
# Fix ownership if needed
sudo chown -R ritesh:ritesh /home/ritesh/backend
🔍 Database Connection Issues
Test database connectivity:
# Check if .env file exists and has correct values
cat ~/.env
# Test database connection
source venv/bin/activate
python -c "from app.database import engine; print(engine.connect())"
🔍 Port Already in Use
Check what's using port 8000:
# Find process using port 8000
sudo lsof -i :8000
# Kill the process if needed
sudo kill -9 <PID>
🔍 View Live Logs
Monitor your application in real-time:
# Follow logs in real-time
sudo journalctl -u resource-backend -f
# View last 100 lines
sudo journalctl -u resource-backend -n 100
🔍 Restart After Config Changes
Apply changes to service file:
# After editing service file
sudo systemctl daemon-reload
sudo systemctl restart resource-backend
sudo systemctl status resource-backend
Service Management
sudo systemctl start resource-backend
sudo systemctl stop resource-backend
sudo systemctl restart resource-backend
sudo systemctl status resource-backend
View Logs
sudo journalctl -u resource-backend -f
sudo journalctl -u resource-backend -n 100
Check Health
curl http://localhost:8000/health
curl http://YOUR-VM-IP:8000/health
Edit Service File
sudo nano /etc/systemd/system/resource-backend.service
sudo systemctl daemon-reload
Virtual Environment
source venv/bin/activate
deactivate
pip list
Firewall
sudo ufw allow 8000/tcp
sudo ufw status
sudo ufw enable