ในโลกของการพัฒนา Web Application ด้วย Python การเลือกเว็บเซิร์ฟเวอร์ (Web Server) และแอปพลิเคชันเซิร์ฟเวอร์ (Application Server) ที่ถูกต้องนั้นเป็นสิ่งสำคัญอย่างยิ่ง เมื่อเรานำเสนอแอปพลิเคชัน Django, Flask, FastAPI หรือ Frameworks อื่น ๆ บนเซิร์ฟเวอร์ที่ใช้งานจริง (Production) เราจำเป็นต้องมี Web Server ที่แข็งแกร่ง เช่น Nginx ที่ทำงานร่วมกับ Application Server เช่น Gunicorn หรือ uWSGI ในบทความนี้ เราจะสำรวจวิธีการตั้งค่า Nginx ร่วมกับ Gunicorn และ uWSGI เพื่อให้สามารถใช้งานได้อย่างมีประสิทธิภาพ รวมถึงการจัดการ Static Files, SSL, และ Performance Optimization ต่าง ๆ
ทำไมต้องใช้ Nginx กับ Python WSGI/ASGI Server
Python Framework เช่น Django และ Flask ไม่ได้ออกแบบมาให้รองรับการเชื่อมต่อจากหลายผู้ใช้พร้อมกัน ตัว Web Server ของ Python นั้นทำงานบน Single-threaded process ซึ่งไม่เหมาะสำหรับสภาพแวดล้อม Production
- Nginx — Web Server ที่เบา มีประสิทธิภาพสูง ทำหน้าที่ Reverse Proxy และจัดการ Static Files
- Gunicorn/uWSGI — Application Server ที่เปิด Port เพื่อรับคำขอจาก Nginx
- Socket Connection — การสื่อสารระหว่าง Nginx และ Python Server ผ่าน Unix Socket หรือ TCP
สถาปัตยกรรมนี้ช่วยให้เราสามารถ restart application server โดยไม่ต้อง restart Nginx และสามารถ scale application ได้อย่างยืดหยุ่น
Gunicorn — Python WSGI Application Server
การติดตั้ง Gunicorn
Gunicorn (Green Unicorn) เป็น Application Server ยอดนิยมสำหรับ Python WSGI Applications เช่น Django และ Flask สามารถติดตั้งผ่าน pip ได้ง่าย
# ติดตั้ง Gunicorn
pip install gunicorn
# สำหรับ Django
pip install gunicorn django
# สำหรับ Flask
pip install gunicorn flask
การตั้งค่า Gunicorn — ไฟล์คำสั่ง
Gunicorn สามารถเรียกใช้ผ่านคำสั่ง Command Line หรือผ่าน Configuration File การตั้งค่าพื้นฐานคือ
# คำสั่งพื้นฐาน — รันบน localhost:8000
gunicorn myapp.wsgi:application
# ตั้งค่า bind address และ port
gunicorn --bind 0.0.0.0:8000 myapp.wsgi:application
# ตั้งค่าจำนวน worker processes
gunicorn --workers 4 myapp.wsgi:application
# ตั้งค่า Unix socket
gunicorn --bind unix:/tmp/gunicorn.sock myapp.wsgi:application
Configuration File — gunicorn_config.py
สำหรับการตั้งค่าที่ซับซ้อนมากขึ้น ควรสร้างไฟล์ Configuration ดังนี้
# gunicorn_config.py
import multiprocessing
# Bind
bind = "unix:/tmp/gunicorn.sock"
# bind = "0.0.0.0:8000" # TCP หรือ Unix Socket
# Workers
workers = multiprocessing.cpu_count() * 2 + 1
# Worker class
worker_class = "sync" # หรือ "gevent", "eventlet"
# Worker timeout
timeout = 30
# Maximum number of pending connections
backlog = 2048
# Access log
accesslog = "/var/log/gunicorn/access.log"
errorlog = "/var/log/gunicorn/error.log"
# Log level
loglevel = "info"
# Graceful timeout
graceful_timeout = 30
# Keep-Alive timeout
keepalive = 2
# Process naming
proc_name = "myapp"
จากนั้น รันด้วยคำสั่ง
gunicorn -c gunicorn_config.py myapp.wsgi:application
uWSGI — Application Server อเนกประสงค์
การติดตั้ง uWSGI
uWSGI เป็น Application Server ที่มีพลังและยืดหยุ่นมาก รองรับ WSGI, ASGI, หลายภาษา และระบบปลั๊กอินต่าง ๆ
# ติดตั้ง uWSGI
pip install uwsgi
# ติดตั้งเวอร์ชัน emperor (สำหรับการจัดการแอปฯ หลาย ๆ ตัว)
pip install uwsgi[python]
Configuration File — uwsgi.ini
uWSGI ใช้ไฟล์ .ini สำหรับการตั้งค่า
# uwsgi.ini
[uwsgi]
# Python app module
module = myapp.wsgi:application
# หรือ Flask: module = app:app
# Master process
master = true
# Process and socket
processes = 4
threads = 1
socket = /tmp/uwsgi.sock
chmod-socket = 666
# TCP mode (ถ้าต้องการ)
# http = :8000
# Virtual environment
venv = /path/to/venv
# Chdir to project
chdir = /path/to/myapp
# Daemonize
daemonize = /var/log/uwsgi/uwsgi.log
# Logging
logto = /var/log/uwsgi/uwsgi.log
# Graceful shutdown timeout
graceful-timeout = 30
# PID file
pidfile = /tmp/uwsgi.pid
จากนั้น รันด้วยคำสั่ง
uwsgi --ini uwsgi.ini
Nginx Reverse Proxy Configuration
การตั้งค่า Upstream Gunicorn
ตั้งค่า Nginx เพื่อให้ทำหน้าที่เป็น Reverse Proxy ที่รับคำขอจากผู้ใช้ แล้วส่งต่อไปยัง Gunicorn ซึ่งทำงานบน Unix Socket หรือ TCP Port
# /etc/nginx/sites-available/myapp
# Upstream definition — Unix socket
upstream gunicorn {
server unix:/tmp/gunicorn.sock fail_timeout=0;
}
# หรือ TCP
upstream gunicorn {
server 127.0.0.1:8000 fail_timeout=0;
}
server {
listen 80;
server_name example.com www.example.com;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
# HTTPS Server
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL certificates
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Root directory
root /var/www/myapp;
# Client max body size
client_max_body_size 10M;
# Static files
location /static/ {
alias /var/www/myapp/staticfiles/;
expires 30d;
access_log off;
}
# Media files
location /media/ {
alias /var/www/myapp/media/;
expires 7d;
}
# Proxy to Gunicorn
location / {
proxy_pass http://gunicorn;
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_redirect off;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
การตั้งค่า Upstream uWSGI
สำหรับ uWSGI นั้น ให้ใช้ directive uwsgi_pass แทน proxy_pass
# /etc/nginx/sites-available/myapp-uwsgi
# Upstream for uWSGI
upstream uwsgi {
server unix:/tmp/uwsgi.sock fail_timeout=0;
}
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www/myapp;
client_max_body_size 10M;
# Static files
location /static/ {
alias /var/www/myapp/staticfiles/;
expires 30d;
}
# Media files
location /media/ {
alias /var/www/myapp/media/;
}
# uWSGI pass
location / {
uwsgi_pass uwsgi;
include uwsgi_params;
uwsgi_param HTTP_X_FORWARDED_PROTO $scheme;
uwsgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
uwsgi_param HTTP_HOST $host;
}
}
Unix Socket vs TCP — ข้อดีข้อเสีย
| ลักษณะ | Unix Socket | TCP Socket |
|---|---|---|
| ความเร็ว | เร็วกว่า (local) | ช้ากว่านิดหน่อย |
| ความปลอดภัย | สูง (file permissions) | ต่ำ (network) |
| การดีบัก | ยากกว่า | ง่ายกว่า |
| Scale แนวนอน | ไม่เหมาะ | เหมาะสำหรับ Multi-server |
| การใช้งาน | Single Server | Multi-server, Load Balancing |
สำหรับการใช้งาน Production บน Single Server: ใช้ Unix Socket เพราะความเร็วและความปลอดภัย
สำหรับสภาพแวดล้อม Distributed: ใช้ TCP Socket เพื่อให้ Nginx และ Application Server สามารถ Scale ได้อย่างอิสระ
FastAPI with Uvicorn + Nginx
FastAPI เป็น Modern Framework ที่ใช้ ASGI Server สำหรับการจัดการ Async Operations
# ติดตั้ง Uvicorn
pip install uvicorn fastapi
# สร้าง FastAPI app
# app.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
# รันด้วย Uvicorn
uvicorn --host 0.0.0.0 --port 8000 app:app
# หรือกับ Unix socket ผ่าน Gunicorn
gunicorn --worker-class uvicorn.workers.UvicornWorker \
--bind unix:/tmp/uvicorn.sock \
--workers 4 \
app:app
ตั้งค่า Nginx เหมือนกับ Gunicorn โดยใช้ proxy_pass
Django Deployment — วิธีปฏิบัติที่ดี
โครงสร้างไดเรกทอรี่
/var/www/myproject/
├── venv/ # Virtual environment
├── myapp/ # Django project
│ ├── manage.py
│ ├── myapp/
│ ├── templates/
│ ├── static/
│ └── media/
├── staticfiles/ # Collected static files (Django)
├── gunicorn_config.py # Gunicorn configuration
└── uwsgi.ini # uWSGI configuration
Systemd Service File สำหรับ Gunicorn
สร้าง systemd service เพื่อให้ Gunicorn รันโดยอัตโนมัติเมื่อระบบบูต
# /etc/systemd/system/gunicorn.service
[Unit]
Description=Gunicorn application server
After=network.target
[Service]
Type=notify
User=www-data
Group=www-data
WorkingDirectory=/var/www/myproject
Environment="PATH=/var/www/myproject/venv/bin"
ExecStart=/var/www/myproject/venv/bin/gunicorn \
-c gunicorn_config.py \
myapp.wsgi:application
# Restart on failure
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
เปิดใช้งาน Service
sudo systemctl daemon-reload
sudo systemctl enable gunicorn
sudo systemctl start gunicorn
sudo systemctl status gunicorn
Systemd Service File สำหรับ uWSGI
# /etc/systemd/system/uwsgi.service
[Unit]
Description=uWSGI application server
After=network.target
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/var/www/myproject
Environment="PATH=/var/www/myproject/venv/bin"
ExecStart=/var/www/myproject/venv/bin/uwsgi --ini uwsgi.ini
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
การจัดการ Static และ Media Files
ใน Django Production ต้องรวบรวม Static Files เพื่อให้ Nginx ที่อ่านได้เร็ว
# collect static files
python manage.py collectstatic --noinput
# ผลลัพธ์ใน /var/www/myproject/staticfiles/
ตั้งค่า Nginx เพื่อให้ Serve Static Files โดยตรง (ไม่ผ่าน Django)
# nginx config
location /static/ {
alias /var/www/myproject/staticfiles/;
expires 30d;
add_header Cache-Control "public, immutable";
}
location /media/ {
alias /var/www/myproject/media/;
expires 7d;
add_header Cache-Control "public";
}
SSL/TLS Configuration
ใช้ Let’s Encrypt สำหรับ Free SSL Certificate
# ติดตั้ง Certbot
sudo apt install certbot python3-certbot-nginx
# ขออนุญาต Certificate
sudo certbot certonly --nginx -d example.com -d www.example.com
# Auto-renewal
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer
อัปเดตการตั้งค่า Nginx
# nginx config with SSL
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# ... rest of config
Performance Tuning
การคำนวณจำนวน Workers
สูตรสำหรับการคำนวณจำนวน Worker Processes (Gunicorn)
# สูตร: (2 × CPU cores) + 1
# เช่น CPU 4 cores: (2 × 4) + 1 = 9 workers
# สำหรับ I/O Intensive Apps: 2-4 × CPU cores
# สำหรับ CPU Intensive Apps: CPU cores + 1
import multiprocessing
workers = multiprocessing.cpu_count() * 2 + 1
Buffer Sizes และ Timeouts
# Nginx buffer configuration
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Keep-alive
keepalive_timeout 65;
keepalive_requests 100;
Gzip Compression
# /etc/nginx/nginx.conf
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss
application/rss+xml font/truetype font/opentype
application/vnd.ms-fontobject image/svg+xml;
Monitoring และ Logging
ติดตั้ง Monitoring Tools เพื่อติดตามประสิทธิภาพ
# ดูสถานะ Gunicorn
sudo systemctl status gunicorn
# ดูลอก
tail -f /var/log/gunicorn/error.log
tail -f /var/log/gunicorn/access.log
# ดูสถานะ uWSGI
tail -f /var/log/uwsgi/uwsgi.log
# ใช้ htop เพื่อดูการใช้ทรัพยากร
sudo apt install htop
htop
# ใช้ netstat เพื่อดู Socket connections
netstat -tulpn | grep gunicorn
netstat -tulpn | grep uwsgi
Troubleshooting Common Issues
502 Bad Gateway Error
- ตรวจสอบว่า Gunicorn/uWSGI รันอยู่ —
sudo systemctl status gunicorn - ตรวจสอบ Socket File permissions —
ls -la /tmp/gunicorn.sock - ตรวจสอบ Nginx error log —
tail -f /var/log/nginx/error.log
Connection Refused
# ตรวจสอบว่า Port เปิดอยู่
sudo netstat -tulpn | grep 8000
# หรือ
sudo ss -tulpn | grep gunicorn
# ตรวจสอบ Firewall
sudo ufw status
Slow Application Response
- เพิ่มจำนวน Workers
- ปรับ Worker Timeout ให้เหมาะสม
- เปิด Caching (Redis, Memcached)
- ตรวจสอบ Database Query Performance
Gunicorn vs uWSGI — เปรียบเทียบ
| ลักษณะ | Gunicorn | uWSGI |
|---|---|---|
| ความง่ายในการใช้งาน | ง่ายมาก | ซับซ้อนกว่า |
| ความยืดหยุ่น | ปานกลาง | สูงมาก |
| ประสิทธิภาพ | ดี | ดีมากถึงเหมาะสม |
| สนับสนุนภาษา | Python | หลายภาษา |
| Community | ใหญ่ | ใหญ่ |
| การจัดการหลาย Apps | ไม่เหมาะสม | เหมาะสม (Emperor mode) |
| ความเสถียรใน Production | สูง | สูง |
ใช้ Gunicorn เมื่อ: ต้องการ Simple, Fast setup สำหรับ Django/Flask single application
ใช้ uWSGI เมื่อ: ต้องการความยืดหยุ่นสูง, manage multiple apps, หรือต้องการ Features ขั้นสูง
สรุป
การตั้งค่า Nginx ร่วมกับ Gunicorn หรือ uWSGI นั้นเป็นมาตรฐานทางอุตสาหกรรมสำหรับการ Deploy Python Web Applications บน Production สถาปัตยกรรมนี้ช่วยให้เรามี
- Web Server ที่เบา เร็ว และมีประสิทธิภาพสูง (Nginx)
- Application Server ที่สามารถจัดการ Multiple Workers (Gunicorn/uWSGI)
- การแยกความสำคัญของ Static Content และ Dynamic Content ที่ชัดเจน
- ความสามารถในการ Scale, Monitor, และ Maintain ระบบได้ง่าย
หากปฏิบัติตามวิธีปฏิบัติที่ดีในบทความนี้ แอปพลิเคชัน Python ของคุณจะสามารถรองรับการใช้งานจำนวนมากพร้อมความนี่น (High Availability) อย่างมีประสิทธิภาพ
แนะนำบริการ DE Cloud VPS
หากคุณต้องการนำเสนอ Django, Flask, FastAPI, หรือ Python Applications ตัวอื่นของคุณบน Production Server ที่มีความเสถียรและประสิทธิภาพสูง DE Cloud VPS ของ Dot Enterprise Co., Ltd. คือทางเลือกที่ดีเยี่ยม
- Server ที่เร็ว มั่นคง และสามารถ Customize ได้ตามความต้องการ
- Full Root Access เพื่อติดตั้ง Nginx, Gunicorn, uWSGI อย่างอิสระ
- SSD Storage สำหรับ Performance ที่ดีที่สุด
- Auto Backup และ Security Features
- Support Team ที่พร้อมช่วยเหลือ 24/7
สำหรับข้อมูลเพิ่มเติมและการสั่งซื้อ โปรดเยี่ยมชม DE Cloud Hosting หรือติดต่อทีม Support ของเรา

