How to Host a Node.js or Python Web App on Your Cloud Server

Use Cases 3 min read Updated May 2026

This guide walks you through deploying a Node.js or Python web application to a cloud server and keeping it running reliably using a process manager and Nginx as a reverse proxy.

Prerequisites

Part A: Deploying a Node.js App

Step 1: Install Node.js

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
apt install nodejs -y
node -v
npm -v

Step 2: Upload Your App

From your local machine:

scp -r ./my-app yourname@YOUR_SERVER_IP:/home/yourname/

Or clone from Git:

git clone https://github.com/yourusername/my-app.git
cd my-app

Step 3: Install Dependencies and Test

cd /home/yourname/my-app
npm install
node app.js
# Confirm it runs, then stop with Ctrl+C

Step 4: Install PM2 (Process Manager)

PM2 keeps your app running and restarts it automatically on crashes or reboots:

npm install -g pm2
pm2 start app.js --name my-app
pm2 save
pm2 startup

Run the command PM2 outputs (it looks like sudo env PATH=... pm2 startup ...).

Step 5: Configure Nginx as a Reverse Proxy

Your Node app runs on a port like 3000. Nginx forwards web traffic to it:

nano /etc/nginx/sites-available/my-app
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

Enable and reload:

ln -s /etc/nginx/sites-available/my-app /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx

Part B: Deploying a Python (Flask/Django) App

Step 1: Install Python and pip

apt install python3 python3-pip python3-venv -y

Step 2: Upload and Set Up the App

cd /home/yourname
git clone https://github.com/yourusername/my-python-app.git
cd my-python-app
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Step 3: Install Gunicorn

Gunicorn is a WSGI server that runs Python apps in production:

pip install gunicorn

Test it:

# For Flask (app.py with `app` as the Flask instance):
gunicorn --bind 0.0.0.0:5000 app:app

# For Django:
gunicorn --bind 0.0.0.0:8000 myproject.wsgi

Step 4: Create a systemd Service

nano /etc/systemd/system/my-python-app.service
[Unit]
Description=My Python App
After=network.target

[Service]
User=yourname
WorkingDirectory=/home/yourname/my-python-app
Environment="PATH=/home/yourname/my-python-app/venv/bin"
ExecStart=/home/yourname/my-python-app/venv/bin/gunicorn --workers 3 --bind unix:/home/yourname/my-python-app/app.sock app:app
Restart=always

[Install]
WantedBy=multi-user.target

Enable and start:

systemctl daemon-reload
systemctl enable my-python-app
systemctl start my-python-app

Step 5: Configure Nginx for Python App

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/yourname/my-python-app/app.sock;
    }
}

Step 6: Add HTTPS (Both Node.js and Python)

apt install certbot python3-certbot-nginx -y
certbot --nginx -d yourdomain.com -d www.yourdomain.com

Useful Commands

Task Node.js (PM2) Python (systemd)
Start app pm2 start app.js systemctl start my-python-app
Stop app pm2 stop my-app systemctl stop my-python-app
Restart app pm2 restart my-app systemctl restart my-python-app
View logs pm2 logs my-app journalctl -u my-python-app
Auto-start on boot pm2 startup && pm2 save systemctl enable my-python-app

Questions? Email us at [email protected] - we reply in under 2 hours, 7 days a week.

Top up in crypto.
Be root in a minute.

No cards. No KYC. Uninterrupted service since 2014. For people who'd rather not explain why they need a server.

Deploy a server →