Gunicorn और nginx के साथ VPS पर Django ऐप कैसे डिप्लॉय करें
VPS पर Django ऐप डिप्लॉय करने के लिए उसे प्रोडक्शन सर्वर के साथ चलाएँ, आगे एक रिवर्स प्रॉक्सी रखें, डेटाबेस कनेक्ट करें और HTTPS कॉन्फ़िगर करें। यह गाइड Ubuntu 24.04 LTS, Django 5.2, PostgreSQL, Gunicorn, systemd और nginx इस्तेमाल करता है। पाथ और मॉड्यूल का नाम अपने प्रोजेक्ट के हिसाब से बदल लें।
आपको SSH और sudo एक्सेस वाला VPS, उसकी ओर पॉइंट किया गया डोमेन, एक चालू Django रिपॉज़िटरी और डिपेंडेंसी लॉक या पिन की गई requirements.txt चाहिए। उदाहरण में example.com, /srv/myapp और myproject.wsgi:application प्लेसहोल्डर के तौर पर इस्तेमाल हुए हैं। यह गाइड WSGI ऐप्लिकेशन के लिए है; अगर आपके ऐप को ASGI चाहिए, तो ASGI सेटअप इस्तेमाल करें। रेफ़रेंस 9 सितंबर 2026 को जाँचे गए।
1. सर्वर और ऐप्लिकेशन यूज़र तैयार करें
नए Ubuntu सर्वर पर बेस पैकेज इंस्टॉल करें:
sudo apt update
sudo apt install -y python3-venv python3-dev build-essential libpq-dev postgresql nginx git
sudo adduser --system --group --home /srv/myapp django
sudo install -d -o django -g django /srv/myappdjango यूज़र ऐप्लिकेशन को root अधिकारों के बिना चलाता है। एडमिन वाला SSH एक्सेस अपने सामान्य अकाउंट से रखें। फ़ायरवॉल नियम चालू करने से पहले फ़ायरवॉल में अपने SSH कनेक्शन की अनुमति दें, और इनबाउंड HTTP व HTTPS की अनुमति दें। PostgreSQL को सिर्फ़ वहीं से पहुँचने लायक रखें जहाँ ऐप को उसकी ज़रूरत है।
2. PostgreSQL क्रेडेंशियल बनाएँ
एक डेटाबेस role बनाएँ और प्रॉम्प्ट आने पर उसका पासवर्ड चुनें, फिर उसका डेटाबेस बनाएँ:
sudo -u postgres createuser --pwprompt myapp
sudo -u postgres createdb --owner=myapp myappऐप्लिकेशन 127.0.0.1 से कनेक्ट होगा, जो Ubuntu पर PostgreSQL के आम सेटअप में पासवर्ड ऑथेंटिकेशन इस्तेमाल करता है। कनेक्शन फ़ेल हो, तो अपनी pg_hba.conf जाँचें। लोकल ऑथेंटिकेशन की समस्या सुलझाने के लिए डेटाबेस पोर्ट को पब्लिक न करें।
3. ऐप्लिकेशन और डिपेंडेंसी इंस्टॉल करें
उदाहरण वाला रिपॉज़िटरी URL बदलें। प्राइवेट रिपॉज़िटरी के लिए रीड एक्सेस का इंतज़ाम ऐसे करें कि टोकन URL या कमिट की गई फ़ाइलों में न जाए।
sudo -u django git clone https://github.com/your-org/your-app.git /srv/myapp/app
sudo -u django python3 -m venv /srv/myapp/venv
sudo -u django /srv/myapp/venv/bin/pip install -r /srv/myapp/app/requirements.txtआपकी requirements फ़ाइल में Django का वर्ज़न, Gunicorn और प्रोजेक्ट में इस्तेमाल होने वाला PostgreSQL ड्राइवर होना चाहिए। अगर प्रोजेक्ट में कोई दूसरी lockfile है, तो उसका मौजूदा पैकेज मैनेजर इस्तेमाल करें। पक्का करें कि सेटिंग्स मॉड्यूल और WSGI import पाथ आपकी रिपॉज़िटरी से मेल खाते हैं।
4. प्रोडक्शन सेटिंग्स को साफ़ तौर पर लोड करें
अपने एडिटर से /etc/myapp.env बनाएँ। असली वैल्यू वहीं रखें, Git में नहीं। यह उदाहरण मानता है कि आपकी सेटिंग्स ये नाम पढ़ती हैं:
DJANGO_SECRET_KEY='replace-with-a-long-random-secret'
DJANGO_ALLOWED_HOSTS='example.com'
DJANGO_CSRF_TRUSTED_ORIGINS='https://example.com'
DB_NAME='myapp'
DB_USER='myapp'
DB_PASSWORD='replace-with-the-password-you-set'
DB_HOST='127.0.0.1'
DB_PORT='5432'ऐसी सीधी, कोट में लिखी वैल्यू इस्तेमाल करें जो शेल और systemd की environment-file सिंटैक्स, दोनों के साथ चलें। फ़ाइल को सुरक्षित करें:
sudo chown root:django /etc/myapp.env
sudo chmod 640 /etc/myapp.envप्रोडक्शन सेटिंग्स में इन्हीं वैल्यू को पढ़ने का कॉन्फ़िगरेशन करें। यह स्निपेट मानता है कि BASE_DIR पहले से मौजूद है:
import os
DEBUG = False
SECRET_KEY = os.environ['DJANGO_SECRET_KEY']
ALLOWED_HOSTS = os.environ['DJANGO_ALLOWED_HOSTS'].split(',')
CSRF_TRUSTED_ORIGINS = os.environ['DJANGO_CSRF_TRUSTED_ORIGINS'].split(',')
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ['DB_NAME'],
'USER': os.environ['DB_USER'],
'PASSWORD': os.environ['DB_PASSWORD'],
'HOST': os.environ['DB_HOST'],
'PORT': os.environ['DB_PORT'],
}
}
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'अपलोड किए गए मीडिया को collectstatic से इकट्ठा की गई static फ़ाइलों से अलग रखें। अपलोड होने वाले कंटेंट के हिसाब से टिकाऊ स्टोरेज, बैकअप पॉलिसी और एक्सेस कंट्रोल चुनें। Django की डिप्लॉयमेंट चेकलिस्ट देखें।
5. सेटिंग्स जाँचें और डेटाबेस तैयार करें
मैनेजमेंट कमांड ऐप यूज़र के तौर पर और सर्विस वाले एनवायरनमेंट के साथ ही चलाएँ:
sudo -u django bash -c 'set -a; . /etc/myapp.env; set +a; cd /srv/myapp/app; /srv/myapp/venv/bin/python manage.py check --deploy'
sudo -u django bash -c 'set -a; . /etc/myapp.env; set +a; cd /srv/myapp/app; /srv/myapp/venv/bin/python manage.py migrate --noinput'
sudo -u django bash -c 'set -a; . /etc/myapp.env; set +a; cd /srv/myapp/app; /srv/myapp/venv/bin/python manage.py collectstatic --noinput'डिप्लॉयमेंट की चेतावनियों का रिव्यू करें। HTTPS से जुड़ी सेटिंग्स तब आती हैं जब प्रॉक्सी पर चालू सर्टिफ़िकेट लग जाए। अगर प्रोडक्शन डेटाबेस पहले से है, तो स्कीमा बदलाव लागू करने से पहले बैकअप लें और उसे टेस्ट करें। माइग्रेशन हर Gunicorn वर्कर में नहीं, बल्कि रिलीज़ के हिस्से के तौर पर एक बार चलाएँ।
6. systemd के तहत Gunicorn चलाएँ
/etc/systemd/system/myapp.service बनाएँ:
[Unit]
Description=Django application
After=network.target postgresql.service
[Service]
User=django
Group=django
WorkingDirectory=/srv/myapp/app
EnvironmentFile=/etc/myapp.env
ExecStart=/srv/myapp/venv/bin/gunicorn myproject.wsgi:application --bind 127.0.0.1:8001 --workers 2 --access-logfile - --error-logfile -
Restart=on-failure
RestartSec=5
PrivateTmp=true
NoNewPrivileges=true
[Install]
WantedBy=multi-user.targetदो वर्कर वाली वैल्यू सिर्फ़ शुरुआती उदाहरण है, साइज़ तय करने का फ़ॉर्मूला नहीं। इसे बढ़ाने से पहले मेमोरी, डेटाबेस कनेक्शन और रिस्पॉन्स टाइम मापें। Gunicorn लूपबैक पर bind होता है, ताकि विज़िटर nginx के ज़रिए ही ऐप तक पहुँचें।
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
sudo systemctl status myapp --no-pager
curl -I -H 'Host: example.com' http://127.0.0.1:8001/प्रोसेस की एरर के लिए journalctl -u myapp इस्तेमाल करें। import फ़ेल होना आम तौर पर मॉड्यूल पाथ, वर्किंग डायरेक्टरी या डिपेंडेंसी इंस्टॉलेशन की गड़बड़ी की ओर इशारा करता है। Django की WSGI गाइड और Gunicorn देखें।
7. nginx को आगे रखें
/etc/nginx/sites-available/myapp बनाएँ:
server {
listen 80;
server_name example.com;
location /static/ {
alias /srv/myapp/app/staticfiles/;
}
location / {
proxy_pass http://127.0.0.1:8001;
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;
}
}नई साइट को एक बार इनेबल करें, कॉन्फ़िगरेशन टेस्ट करें और रीलोड करें:
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/myapp
sudo nginx -t
sudo systemctl reload nginxपक्का करें कि nginx इकट्ठा की गई static फ़ाइलें पढ़ सकता है और उनकी parent डायरेक्टरी में जा (traverse कर) सकता है। किसी भी डिफ़ॉल्ट साइट कॉन्फ़िगरेशन को अपने बाकी होस्ट किए गए डोमेन के हिसाब से ही रखें; जिन साइटों से इसका लेना-देना नहीं, उन्हें न हटाएँ। nginx गाइड रिवर्स प्रॉक्सी और static फ़ाइलों का कॉन्फ़िगरेशन समझाती है।
8. HTTPS जोड़ें और Django को फिर से जाँचें
अपनी पसंद के ACME क्लाइंट और उसके मौजूदा निर्देशों से सर्टिफ़िकेट इंस्टॉल करें। अगर nginx के लिए Certbot इंस्टॉल है, तो इस उदाहरण के लिए सर्टिफ़िकेट रिक्वेस्ट यह है:
sudo certbot --nginx -d example.com
sudo certbot renew --dry-runअपने OS पर इंस्टॉलेशन के लिए Certbot निर्देश देखें। TLS को पूरा मानने से पहले डोमेन DNS, HTTP से पहुँच और रिन्यूअल की जाँच करें।
HTTPS काम करने लगे, तो ये Django विकल्प सेट करें:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = Trueफ़ॉरवर्डेड-प्रोटोकॉल हेडर पर भरोसा सिर्फ़ इसलिए किया जा सकता है क्योंकि इसे nginx कंट्रोल करता है और Gunicorn सीधे बाहर उपलब्ध नहीं है। सर्विस रीस्टार्ट करें, check --deploy फिर से चलाएँ, और HTTPS पर लॉगिन और फ़ॉर्म सबमिशन टेस्ट करें। हर प्रभावित होस्ट पर HTTPS की पुष्टि हो जाने के बाद HSTS का अलग से रिव्यू करें।
9. आगे के रिलीज़ को दोहराने लायक बनाएँ
हर रिलीज़ के लिए रिव्यू किया गया रिवीज़न चुनें, उसकी लॉक की गई डिपेंडेंसी इंस्टॉल करें, जो भी कम्पैटिबल माइग्रेशन हो उसे लागू करें, static फ़ाइलें इकट्ठा करें और सर्विस रीस्टार्ट करें। बदलाव के बाद लाइव ऐप्लिकेशन टेस्ट करें और एरर पर नज़र रखें।
पिछला रिवीज़न उपलब्ध रखें, लेकिन याद रखें कि कोड को पिछले रिवीज़न पर लौटाने से हो सकता है डेटाबेस माइग्रेशन वापस न हो। स्कीमा बदलावों के लिए रिकवरी का तरीका डॉक्यूमेंट करें और किसी अलग डेटाबेस में डेटा रिस्टोर करके टेस्ट करें।
अगर ऐप Celery इस्तेमाल करता है, तो उसके लिए अलग सर्विस डेफ़िनिशन, कमांड और ब्रोकर कॉन्फ़िगरेशन रखें। वर्कर को Gunicorn सर्विस के अंदर बैकग्राउंड शेल कमांड के रूप में न चलाएँ।
इसकी जगह मैनेज्ड होस्टिंग कब चुनें
VPS तब ठीक है जब आपको सर्वर पर कंट्रोल चाहिए और आप उसे मेंटेन कर सकते हैं। अगर आप होस्ट से जुड़े ज़्यादा काम किसी और को सौंपना चाहते हैं, तो Python ऐप होस्टिंग के विकल्पों की तुलना करें। Lizard पर ऐप्लिकेशन Managed Postgres और अलग वर्कर इस्तेमाल कर सकता है, जबकि कोड और कॉन्फ़िगरेशन पर कंट्रोल आपके पास रहता है।
डिप्लॉयमेंट डॉक्यूमेंटेशन यह तरीका कवर करता है। फिर भी आपको सही Django सेटिंग्स, रिलीज़ प्रोसेस और जाँचा हुआ डेटा रिकवरी प्लान चाहिए।
आम सवाल
मुझे 502 एरर क्यों मिलती है? जाँचें कि Gunicorn चल रहा है और 127.0.0.1:8001 पर listen कर रहा है, फिर उसके लॉग और nginx का एरर लॉग देखें। रिवर्स प्रॉक्सी ऐसे प्रोसेस को ठीक नहीं कर सकता जो शुरू ही नहीं हो पाता।
static फ़ाइलें क्यों नहीं दिख रहीं? STATIC_ROOT, collectstatic का आउटपुट, nginx का alias पाथ और फ़ाइल परमिशन जाँचें। अपलोड किए गए मीडिया के लिए अलग सेटअप चाहिए।
क्या मैं PostgreSQL की जगह SQLite इस्तेमाल कर सकता हूँ? कुछ ऐप्लिकेशन कर सकते हैं, लेकिन concurrency, डेटा persistence और बैकअप की ज़रूरतों का आकलन करें। अपने ऐप्लिकेशन के वर्कलोड को टेस्ट किए बिना डेटाबेस इंजन न बदलें।
क्या डिप्लॉयमेंट चेक सफल होना काफ़ी है? नहीं। असली यूज़र फ़्लो, डेटाबेस राइट, फ़ाइल एक्सेस और रिकवरी टेस्ट करें। कॉन्फ़िगरेशन चेक प्रोडक्शन व्यवहार का सिर्फ़ एक हिस्सा पकड़ते हैं।
AI के साथ बिल्ड करें। Lizard के साथ शिप करें।
लाइव जाने के लिए आपको प्लेटफ़ॉर्म टीम की ज़रूरत नहीं है। आपका पूरा क्लाउड, बस एक CLI कमांड की दूरी पर।
- सर्विसेज़
- —
- ऐडऑन
- —
- डिप्लॉयमेंट्स
- —
- सैंडबॉक्स स्टार्ट्स
- —