دیپلوی پروژه Django روی سرور اختصاصی و VPS: PostgreSQL، Gunicorn و Nginx با HTTPS

دستور python manage.py runserver فقط برای توسعه است و روی سرور واقعی کار نمیکند؛ نه چند درخواست همزمان را درست مدیریت میکند، نه از نظر امنیتی برای قرار گرفتن مستقیم روی اینترنت مناسب است. برای دیپلوی جنگو روی سرور — چه یک VPS باشد چه سرور اختصاصی — به ترکیب PostgreSQL برای دیتابیس، Gunicorn بهعنوان WSGI سرور، و Nginx بهعنوان ریورسپراکسی و سرو فایلهای استاتیک نیاز دارید. در این مقاله کل مسیر را از صفر تا HTTPS فعال، مرحله به مرحله پیاده میکنیم.
چرا این سهتایی: PostgreSQL، Gunicorn و Nginx؟
PostgreSQL دیتابیس پیشفرض توصیهشده برای پروژههای Django در پروڈاکشن است؛ محدودیتهای SQLite در نوشتن همزمان آن را برای ترافیک واقعی ناکافی میکند. Gunicorn چندین worker process اجرا میکند تا درخواستها بهصورت موازی پاسخ داده شوند. Nginx جلوی Gunicorn مینشیند، فایلهای static و media را مستقیماً سرو میکند تا پایتون وقتش را روی آنها هدر نکند، و SSL/TLS را مدیریت میکند.
انتخاب زیرساخت: VPS یا سرور اختصاصی؟
قبل از شروع نصب، باید مشخص شود پروژه روی چه زیرساختی اجرا میشود. برای اکثر پروژههای Django در ابتدای راه، یک VPS کافی و مقرونبهصرفه است؛ سرور اختصاصی زمانی معنا پیدا میکند که ترافیک یا نیاز به منابع اختصاصی بالا رفته باشد.
| ویژگی | هاستینگ اشتراکی | VPS | سرور اختصاصی |
|---|---|---|---|
| دسترسی root | ندارد | کامل | کامل |
| نصب نسخه دلخواه PostgreSQL/Nginx | معمولاً ممکن نیست | آزاد | آزاد |
| قابلیت مقیاسپذیری (افزایش منابع) | محدود | سریع و ساده | نیاز به تغییر سختافزار |
| مناسب برای | سایتهای ساده و استاتیک | اکثر پروژههای Django در پروڈاکشن | ترافیک بالا یا نیاز به منابع ایزوله |
برای دیپلوی جنگو روی سرور، هاستینگ اشتراکی عملاً گزینه نیست چون کنترل سطح سیستمعامل لازم است. انتخاب بین VPS و سرور اختصاصی به حجم ترافیک و بودجه برمیگردد؛ برای مقایسه دقیقتر این دو گزینه با هاست اشتراکی، تفاوت هاست اشتراکی و سرور مجازی (VPS) را ببینید.
پیشنیازهای سرور
بهروزرسانی سیستم و نصب پکیجهای پایه
روی Ubuntu/Debian:
sudo apt update && sudo apt upgrade -y
sudo apt install -y python3-pip python3-venv python3-dev \
libpq-dev nginx curl
برای جزئیات بیشتر درباره نصب و تنظیم محیط پایتون روی سرور، نصب پایتون و تنظیم محیط برنامهنویسی در سرور اوبونتو ۲۰.۰۴ را ببینید.
ساخت کاربر غیر root
اجرای دائمی اپلیکیشن با کاربر root توصیه نمیشود:
sudo adduser deployer
sudo usermod -aG sudo deployer
su - deployer
از این نقطه به بعد، تمام دستورها زیر همین کاربر اجرا میشوند.
نصب و تنظیم PostgreSQL
sudo apt install -y postgresql postgresql-contrib
sudo -u postgres psql
داخل پرامپت psql:
CREATE DATABASE myproject_db;
CREATE USER myproject_user WITH PASSWORD 'رمز-قوی-اینجا';
ALTER ROLE myproject_user SET client_encoding TO 'utf8';
ALTER ROLE myproject_user SET default_transaction_isolation TO 'read committed';
ALTER ROLE myproject_user SET timezone TO 'Asia/Tehran';
GRANT ALL PRIVILEGES ON DATABASE myproject_db TO myproject_user;
\q
در settings.py پروژه:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "myproject_db",
"USER": "myproject_user",
"PASSWORD": os.environ.get("DB_PASSWORD"),
"HOST": "localhost",
"PORT": "5432",
}
}
رمز دیتابیس را مستقیم در settings.py ننویسید؛ از متغیر محیطی یا فایل .env بخوانید.
استقرار پروژه در محیط مجازی
cd /home/deployer
git clone <آدرس-ریپازیتوری> myproject
cd myproject
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install gunicorn psycopg2-binary

در settings.py برای پروڈاکشن:
DEBUG = False
ALLOWED_HOSTS = ["example.com", "www.example.com"]
سپس:
python manage.py collectstatic
python manage.py migrate
اجرای Django با Gunicorn
ابتدا اجرای دستی برای تست:
gunicorn --workers 3 --bind 0.0.0.0:8000 myproject.wsgi:application
اگر صفحه از طریق http://IP-سرور:8000 باز شد، مرحله بعد تعریف یک سرویس systemd است تا Gunicorn بعد از ریبوت سرور یا کرش، خودش دوباره بالا بیاید.
فایل /etc/systemd/system/gunicorn.service:
[Unit]
Description=Gunicorn daemon for myproject
After=network.target
[Service]
User=deployer
Group=www-data
WorkingDirectory=/home/deployer/myproject
ExecStart=/home/deployer/myproject/venv/bin/gunicorn \
--workers 3 \
--bind unix:/home/deployer/myproject/myproject.sock \
myproject.wsgi:application
[Install]
WantedBy=multi-user.target
sudo systemctl start gunicorn
sudo systemctl enable gunicorn
استفاده از unix socket بهجای پورت TCP برای ارتباط با Nginx، یک لایه اضافه در شبکه را حذف میکند.
تنظیم Nginx بهعنوان ریورسپراکسی
فایل /etc/nginx/sites-available/myproject:
server {
listen 80;
server_name example.com www.example.com;
location /static/ {
alias /home/deployer/myproject/staticfiles/;
}
location /media/ {
alias /home/deployer/myproject/media/;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/deployer/myproject/myproject.sock;
}
}
فعالسازی و تست:
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx
اگر nginx -t خطا نداد، سایت از طریق دامنه روی پورت 80 در دسترس است.
فعالسازی HTTPS رایگان با Let's Encrypt
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
Certbot خودش فایل تنظیمات Nginx را ویرایش میکند، گواهی را نصب میکند و ریدایرکت HTTP به HTTPS را اضافه میکند. گواهیهای Let's Encrypt هر ۹۰ روز منقضی میشوند؛ Certbot یک تایمر systemd برای رینیو خودکار نصب میکند که معمولاً نیازی به دخالت دستی ندارد. برای جزئیات بیشتر درباره Certbot و تنظیمات SSL، نصب گواهی SSL رایگان با Let's Encrypt و Certbot روی سرور مجازی و اختصاصی لینوکس را مطالعه کنید. برای اطمینان از عملکرد رینیو خودکار:
sudo certbot renew --dry-run
نکات امنیتی و نگهداری بعد از دیپلوی
چند مورد که بعد از راهاندازی اولیه باید بررسی شوند:
- فایروال را با ufw فقط روی پورتهای 22، 80 و 443 باز نگه دارید.
DEBUG=Falseرا دوباره چک کنید — نمایش traceback به کاربر در پروڈاکشن اطلاعات حساس را لو میدهد.- از دیتابیس PostgreSQL بهصورت دورهای با
pg_dumpبکاپ بگیرید و بکاپ را روی یک مسیر جدا از سرور اصلی نگه دارید. - لاگهای Gunicorn و Nginx را برای خطاهای ۵۰۰ زیر نظر داشته باشید، بهخصوص در روزهای اول بعد از دیپلوی.
جمعبندی
دیپلوی Django روی سرور اختصاصی یا VPS از چند بخش مجزا تشکیل شده: دیتابیس PostgreSQL، اجرای پایدار اپلیکیشن با Gunicorn پشت systemd، و Nginx برای مسیردهی ترافیک و مدیریت HTTPS. هیچکدام از این مراحل پیچیده نیستند، اما ترتیب و دقت در تنظیمات (مخصوصاً permission فایلهای socket و مسیر static/media) جایی است که بیشتر مشکلات دیده میشود. اگر پروژه شما بهجای Django با Laravel نوشته شده، مراحل مشابهی در دیپلوی پروژه Laravel روی سرور اختصاصی و VPS توضیح داده شده است.
اگر هنوز زیرساخت مناسبی برای این دیپلوی ندارید، یک VPS با منابع قابل تنظیم نقطه شروع مناسبی است — بدون نیاز به تعهد اولیه سختافزار اختصاصی و با امکان افزایش منابع هر وقت ترافیک پروژه بالا رفت.




