VPS पर Gunicorn और Nginx से Python ऐप कैसे चलाएँ
Ubuntu पर Flask या FastAPI एप्लिकेशन virtualenv, Gunicorn systemd सेवा, Nginx रिवर्स प्रॉक्सी, TLS, पर्यावरण फ़ाइलें, लॉगिंग, और 502 त्रुटियों व वर्कर आकार की जाँच सूची के साथ डिप्लॉय करें।

अंतर्निहित Flask सर्वर और uvicorn --reload विकास के लिए हैं। सार्वजनिक VPS पर ऐसा प्रक्रिया प्रबंधक चाहिए जो वर्कर रीस्टार्ट करे, localhost से बाँधे, और TLS व धीमे क्लाइंट संभालने वाले रिवर्स प्रॉक्सी के पीछे बैठे। Gunicorn Flask और Django के लिए आम WSGI चुनाव है। FastAPI Uvicorn वर्कर वर्ग के साथ Gunicorn के नीचे चल सकता है। Nginx (या Caddy) HTTPS समाप्त करता है और 127.0.0.1:8000 पर आगे भेजता है।
यह गाइड रीबूट से बचने वाला लेआउट चलाती है: प्रोजेक्ट /srv/app में, virtualenv, सीक्रेट वाला .env, gunicorn.service यूनिट, Nginx सर्वर ब्लॉक, Let's Encrypt, और लॉग फ़ाइलें जिन पर सचमुच grep कर सकें। हम वर्कर संख्या, टाइमआउट, और क्यों 502 Bad Gateway लगभग कभी ‘Nginx टूटा’ नहीं है इस पर भी बात करेंगे — लगभग हमेशा Gunicorn नहीं चल रहा, गलत सॉकेट से बंधा, या इंपोर्ट पर क्रैश हो रहा है। उदाहरण Flask इस्तेमाल करता है, जहाँ कमांड भिन्न हो वहाँ FastAPI नोट के साथ।
यह स्टैक क्यों
Gunicorn वर्कर प्रक्रियाओं को पहले से fork करता है। अलग वर्कर वर्ग न इस्तेमाल करें तो हर वर्कर एक समय में एक अनुरोध संभालता है। Nginx धीमे क्लाइंट बफर करता है ताकि वर्कर मोबाइल नेटवर्क पर बाइट भेजते अटकें नहीं। systemd ऐप मर जाए तो रीस्टार्ट करता है। साथ में यह उबाऊ है, जो रात 3 बजे चाहिए।
- Gunicorn: स्थिर WSGI/ASGI प्रक्रिया मॉडल
- systemd: बूट पर शुरू, क्रैश पर रीस्टार्ट, journald लॉग
- Nginx: TLS, स्थिर फ़ाइलें, अनुरोध आकार सीमा, gzip
- venv: सिस्टम Python साफ रहता है
- localhost बाइंड: ऐप Nginx के अलावा पहुँच योग्य नहीं
आवश्यकताएँ
Ubuntu 22.04/24.04 पर Python 3.10+ ठीक है। pip को root से सिस्टम site-packages में न चलाएँ। TLS के लिए डोमेन चाहिए। प्रॉक्सी के रूप में Caddy पसंद करें तो इस लेख की Gunicorn यूनिट वही रहती है — केवल फ्रंट-एंड कॉन्फ़िग बदलता है (Caddy लेख देखें)।
- Ubuntu 22.04 या 24.04 VPS
- requirements.txt या समकक्ष वाला आपका एप्लिकेशन
- WSGI एंट्रीपॉइंट (Flask के लिए: app:app) या ASGI (FastAPI के लिए: uvicorn वर्कर के साथ app:app)
- HTTPS के लिए डोमेन A रिकॉर्ड
चरण 1: सिस्टम पैकेज, उपयोगकर्ता और प्रोजेक्ट निर्देशिका
ऐसा सिस्टम उपयोगकर्ता बनाएँ जो इंटरैक्टिव लॉगिन न कर सके, कोड का मालिक हो, और Gunicorn चलाए। python3-venv और बिल्ड टूल इंस्टॉल करना उन पैकेज पर pip विफलता से बचाता है जो अभी C एक्सटेंशन कंपाइल करते हैं।
ssh root@YOUR_VPS_IP
apt update && apt -y upgrade
apt -y install python3 python3-venv python3-pip python3-dev build-essential nginx curl
adduser --system --group --home /srv/app appuser
mkdir -p /srv/app
chown appuser:appuser /srv/app
# Copy your code (example):
# rsync -a --delete ./myproject/ appuser@YOUR_VPS_IP:/srv/app/चरण 2: Virtualenv और निर्भरताएँ
फ़ाइल स्वामित्व सही हो इसके लिए venv appuser के रूप में बनाएँ। उत्पादन में संस्करण पिन करें। इंस्टॉल के बाद पुष्टि करें कि एकबारगी gunicorn --check-config या Python इंपोर्ट में ऐप इंपोर्ट हो सकता है। यहाँ की इंपोर्ट त्रुटियाँ वही हैं जो बाद में 502 बनती हैं।
sudo -u appuser -H bash -lc '
cd /srv/app
python3 -m venv /srv/app/venv
/srv/app/venv/bin/pip install --upgrade pip
/srv/app/venv/bin/pip install -r /srv/app/requirements.txt gunicorn
'
# Flask example check:
sudo -u appuser -H /srv/app/venv/bin/python -c "from app import app; print('import ok')"चरण 3: पर्यावरण फ़ाइल
SECRET_KEY या डेटाबेस URL को systemd यूनिट में इस तरह हार्डकोड न करें कि विश्व-पठनीय git में पहुँच जाए। EnvironmentFile इस्तेमाल करें। chmod 640, मालिक root, समूह appuser (या पसंद हो तो मालिक appuser)।
cat >/srv/app/.env <<'EOF'
FLASK_ENV=production
SECRET_KEY=replace-with-openssl-rand-hex-32
DATABASE_URL=postgresql://app:password@127.0.0.1:5432/app
EOF
chown appuser:appuser /srv/app/.env
chmod 600 /srv/app/.envचरण 4: Gunicorn systemd सेवा
Nginx छोड़ने का कारण न हो तो 0.0.0.0 नहीं 127.0.0.1:8000 से बाँधें। सिंक वर्कर के लिए वर्कर संख्या अक्सर (2 × CPU) + 1 है; 2 vCPU VPS पर यह 5 है, जो हर वर्कर भारी ML मॉडल लोड करे तो ज्यादा हो सकता है — तब 2–3 इस्तेमाल करें। FastAPI के लिए --worker-class uvicorn.workers.UvicornWorker सेट करें और uvicorn इंस्टॉल करें। टाइमआउट सबसे धीमे ईमानदार अनुरोध से अधिक होने चाहिए, 2-मिनट निर्यात हों तो 30 सेकंड नहीं।
cat >/etc/systemd/system/gunicorn.service <<'EOF'
[Unit]
Description=Gunicorn for the web app
After=network.target
[Service]
User=appuser
Group=appuser
WorkingDirectory=/srv/app
EnvironmentFile=/srv/app/.env
ExecStart=/srv/app/venv/bin/gunicorn --workers 3 --bind 127.0.0.1:8000 --timeout 60 --access-logfile - --error-logfile - app:app
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now gunicorn
systemctl status gunicorn --no-pager
ss -tulpn | grep 8000चरण 5: Nginx रिवर्स प्रॉक्सी और TLS
Nginx 80/443 पर सुनता है और Gunicorn को प्रॉक्सी करता है। अपलोड के लिए client_max_body_size मायने रखता है। proxy_read_timeout Gunicorn टाइमआउट से मेल खाना या अधिक होना चाहिए। सर्वर ब्लॉक HTTP पर काम करे तो Certbot से प्रमाणपत्र जारी करें (या फ्रंट Caddy पर बदलें)। नीचे का स्निपेट परीक्षण के लिए केवल HTTP है; फिर फ़ाइल संपादित कर सकने वाला Certbot चलाएँ।
cat >/etc/nginx/sites-available/app <<'EOF'
server {
listen 80;
server_name app.example.com;
client_max_body_size 20m;
location /static/ {
alias /srv/app/static/;
}
location / {
proxy_pass http://127.0.0.1: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;
proxy_read_timeout 90s;
}
}
EOF
ln -sf /etc/nginx/sites-available/app /etc/nginx/sites-enabled/app
nginx -t && systemctl reload nginx
ufw allow OpenSSH
ufw allow 'Nginx Full'
ufw enable
apt -y install certbot python3-certbot-nginx
certbot --nginx -d app.example.comचरण 6: स्थिर फ़ाइलें, अनुमतियाँ और Flask/FastAPI विवरण
सकें तो Nginx स्थिर फ़ाइलें सर्व करे; Gunicorn से तेज़ है। Django collectstatic, छोटे ऐप के लिए Flask send_from_directory, या बाद में CDN। appuser को पेड़ पढ़ना आना चाहिए। FastAPI इस्तेमाल करें तो venv में uvicorn[standard] इंस्टॉल करें और ExecStart को UvicornWorker इस्तेमाल करने दें। TCP की जगह Unix सॉकेट इस्तेमाल करें तो proxy_pass सॉकेट पर इंगित करें और अनुमति मिलाएँ ताकि www-data लिख सके।
# FastAPI ExecStart example:
# ExecStart=/srv/app/venv/bin/gunicorn -k uvicorn.workers.UvicornWorker --workers 2 --bind 127.0.0.1:8000 app:app
# Unix socket variant:
# --bind unix:/run/gunicorn/app.sock
# Nginx: proxy_pass http://unix:/run/gunicorn/app.sock:
chown -R appuser:appuser /srv/appवर्कर, मेमोरी और शून्य-डाउनटाइम रीलोड
सिंक Gunicorn वर्कर सरल हैं और CPU-हल्के अनुरोध/प्रतिक्रिया API के लिए काफ़ी हैं। कई समवर्ती धीमी I/O प्रतीक्षा चाहिए तो gevent या ASGI वर्कर सोचें — मापें, अनुमान न लगाएँ। हर वर्कर आपका ऐप लोड करता है; RAM ~= वर्कर गुणा ऐप RSS। 300 MB ऐप के 8 वर्कर वाला 2 GB VPS स्वैप करेगा और ‘यादृच्छिक धीमा’ लगेगा। फ़ाइलें जगह पर डिप्लॉय की हों तो systemctl reload gunicorn (HUP) नए कोड से वर्कर रीस्टार्ट कर सकता है; निर्भरताएँ बदलें तो पूरा रीस्टार्ट साफ है।
# After git pull / rsync of new code:
sudo -u appuser -H /srv/app/venv/bin/pip install -r /srv/app/requirements.txt
systemctl restart gunicorn
curl -I https://app.example.com/health502 और चुप क्रैश का निवारण
502 का अर्थ Nginx अपस्ट्रीम से वैध प्रतिक्रिया न पा सका। पहली कमांड journalctl -u gunicorn -e है। आम कारण: गलत module:app नाम, गायब .env कुंजी, Postgres नहीं चल रहा, 127.0.0.1 से बंधा लेकिन Nginx दूसरे होस्ट पर, SELinux (Ubuntu पर दुर्लभ), या ऐप केवल IPv6 सुन रहा। 504 टाइमआउट है। ऐप HTTP पर रीडायरेक्ट करे जबकि X-Forwarded-Proto अनदेखा हो तो 301 लूप होते हैं।
- systemctl status gunicorn — सक्रिय है?
- journalctl -u gunicorn -n 100 — ImportError, गायब env, डेटाबेस
- VPS से curl -v http://127.0.0.1:8000/ — यह विफल हो तो Nginx निर्दोष
- nginx -t और error.log — upstream prematurely closed connection
- ss -tulpn | grep 8000 — कुछ नहीं सुन रहा
- डिस्क भरी — वर्कर रहस्यमय तरीकों से क्रैश करते हैं
सुरक्षा
ऐप कभी सार्वजनिक रूप से बाँधता नहीं। सीक्रेट .env में रहते हैं। venv और OS पैच रखें। Gunicorn को root से न चलाएँ। लॉगिन संभालें तो सत्र कुकी Secure और SameSite सेट करें, और फ्रेमवर्क को केवल Nginx से X-Forwarded-Proto पर भरोसा करने दें। लॉगिन रूट Nginx में या ऐप में दर-सीमित करें।
- 127.0.0.1 या unix सॉकेट से बाँधें
- chmod 600 .env
- systemd में गैर-root User=
- Certbot या Caddy से TLS
- उत्पादन में डिबग मोड और ऑटो-रीलोड बंद करें
सुझाव
- Compose और लोड बैलेंसर के लिए DB कनेक्टिविटी जाँचने वाला /health रूट जोड़ें
- Nginx में cache-control हेडर के साथ स्थिर संपत्ति भेजें
- ईमेल और भारी काम के लिए अलग वर्कर या कतार इस्तेमाल करें (Redis + systemd)
- requirements.txt में gunicorn और uvicorn संस्करण पिन करें
- पहले उत्पादन कटओवर से पहले स्नैपशॉट लें
VPS पर Python ऐप तब उत्पादन-तैयार है जब Gunicorn के नीचे systemd सेवा के रूप में चले, केवल localhost से बँधे, और TLS के साथ Nginx या Caddy के माध्यम से पहुँचा जाए। सीक्रेट EnvironmentFile में रखें, वर्कर ब्लॉग सूत्र से नहीं RAM के अनुसार आकार दें, और 502 पहले Gunicorn जर्नल से डिबग करें। यह पथ आपके रेपो के लिए दस्तावेज़ीकृत हो जाए तो हर बाद का डिप्लॉय rsync या git pull, pip install, और systemctl restart gunicorn है।