Python ve Django ile bir web uygulaması geliştirdiniz, üretim ortamına taşıma zamanı geldi ve önünüzde bir sürü seçenek var. Nginx, Apache, Gunicorn, uWSGI… Peki ya OpenLiteSpeed? Çoğu sysadmin’in göz ardı ettiği bu güçlü web sunucusu, Django uygulamaları için son derece performanslı ve yönetimi kolay bir alternatif sunuyor. Bu yazıda OpenLiteSpeed üzerinde Django uygulamasını baştan sona nasıl ayağa kaldıracağınızı, production ortamına hazır hale getireceğinizi ve olası sorunları nasıl çözeceğinizi detaylıca ele alacağız.
OpenLiteSpeed ve Django: Neden Bu Kombinasyon?
OpenLiteSpeed, LiteSpeed Technologies’in açık kaynak web sunucusudur. Nginx’e kıyasla daha düşük bellek tüketimi, yerleşik önbellek mekanizması ve web tabanlı yönetim paneli gibi avantajları ile öne çıkıyor. Django uygulamaları için tipik tercih Nginx + Gunicorn kombinasyonu olsa da OpenLiteSpeed + Python LSAPI kombinasyonu bazı senaryolarda belirgin performans avantajları sunuyor.
LSAPI (LiteSpeed SAPI) nedir diye soracak olursanız: Bu, LiteSpeed’in PHP ve Python gibi diller için geliştirdiği özel bir uygulama sunucusu arayüzüdür. WSGI protokolünü kullanan Gunicorn’un aksine, LSAPI doğrudan LiteSpeed/OpenLiteSpeed ile konuştuğu için bazı overhead’ları ortadan kaldırıyor.
Ancak bu yazıda daha yaygın ve stabil olan OpenLiteSpeed + Gunicorn + Django mimarisini kullanacağız. OpenLiteSpeed burada bir reverse proxy görevi üstleniyor, Gunicorn ise Django uygulamasını çalıştırıyor.
Gereksinimler ve Sistem Hazırlığı
Bu yazı Ubuntu 22.04 LTS üzerinde test edilmiştir. Başlamadan önce sunucunuzun güncel olduğundan emin olun.
sudo apt update && sudo apt upgrade -y
sudo apt install python3 python3-pip python3-venv git curl wget -y
OpenLiteSpeed kurulumu için LiteSpeed deposunu ekleyelim:
wget -O - https://repo.litespeed.sh | sudo bash
sudo apt install openlitespeed -y
Kurulum tamamlandıktan sonra servis durumunu kontrol edin:
sudo systemctl status lsws
sudo systemctl enable lsws
sudo systemctl start lsws
OpenLiteSpeed varsayılan olarak 8088 portunda çalışır, yönetim paneli ise 7080 portunda hizmet verir. Güvenlik duvarınızı buna göre yapılandırın:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 8088/tcp
sudo ufw allow 7080/tcp
sudo ufw enable
Admin şifresini ayarlamak için:
sudo /usr/local/lsws/admin/misc/admpass.sh
Django Projesini Hazırlamak
Gerçek dünya senaryomuzda bir e-ticaret uygulaması varsayalım. Uygulama için ayrı bir sistem kullanıcısı oluşturmak güvenlik açısından en iyi pratik:
sudo useradd -m -s /bin/bash djangoapp
sudo su - djangoapp
Proje dizinini oluşturun ve sanal ortamı kurun:
mkdir -p /home/djangoapp/myproject
cd /home/djangoapp/myproject
python3 -m venv venv
source venv/bin/activate
pip install django gunicorn psycopg2-binary whitenoise python-decouple
Eğer mevcut bir projeniz varsa requirements.txt dosyanızı kullanabilirsiniz:
pip install -r requirements.txt
Yeni bir Django projesi oluşturuyorsanız:
django-admin startproject config .
python manage.py startapp core
Django Production Ayarları
Production ortamı için settings.py dosyasını düzenlemek kritik önem taşıyor. Hassas bilgileri doğrudan kod içine yazmak yerine ortam değişkenlerini kullanalım. Proje dizinine bir .env dosyası oluşturun:
cat > /home/djangoapp/myproject/.env << 'EOF'
DEBUG=False
SECRET_KEY=buraya-cok-gizli-bir-anahtar-yazin-en-az-50-karakter
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com,sunucu-ip-adresiniz
DATABASE_URL=postgres://dbuser:dbpassword@localhost:5432/myprojectdb
EOF
settings.py dosyanızı production için güncelleyin:
from decouple import config, Csv
SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', default=False, cast=bool)
ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv())
# Static ve Media dosyaları
STATIC_URL = '/static/'
STATIC_ROOT = '/home/djangoapp/myproject/staticfiles'
MEDIA_URL = '/media/'
MEDIA_ROOT = '/home/djangoapp/myproject/media'
# WhiteNoise ile static dosya servisi
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
# diğer middleware'ler...
]
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
# Güvenlik ayarları
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = 'DENY'
Statik dosyaları toplayın ve veritabanı migrasyonlarını çalıştırın:
python manage.py collectstatic --noinput
python manage.py migrate
python manage.py createsuperuser
Gunicorn Yapılandırması
Gunicorn için bir yapılandırma dosyası oluşturmak production ortamında çok daha yönetilebilir bir yapı sağlar. Worker sayısını genellikle (2 x CPU çekirdeği) + 1 formülüyle belirleriz:
cat > /home/djangoapp/myproject/gunicorn.conf.py << 'EOF'
# Gunicorn yapılandırması
bind = "127.0.0.1:8000"
workers = 5
worker_class = "sync"
worker_connections = 1000
timeout = 120
keepalive = 5
max_requests = 1000
max_requests_jitter = 50
preload_app = True
accesslog = "/home/djangoapp/logs/gunicorn_access.log"
errorlog = "/home/djangoapp/logs/gunicorn_error.log"
loglevel = "info"
capture_output = True
EOF
Log dizinini oluşturun:
mkdir -p /home/djangoapp/logs
Gunicorn’u test amaçlı başlatın:
cd /home/djangoapp/myproject
source venv/bin/activate
gunicorn -c gunicorn.conf.py config.wsgi:application
Başka bir terminal açıp bağlantıyı test edin:
curl -I http://127.0.0.1:8000
Systemd Servis Dosyası
Gunicorn’u systemd ile yönetmek production ortamında olmazsa olmaz. Sunucu yeniden başladığında otomatik olarak devreye girsin, çöktüğünde kendini yeniden başlatsın:
sudo tee /etc/systemd/system/gunicorn-myproject.service > /dev/null << 'EOF'
[Unit]
Description=Gunicorn daemon for MyProject Django Application
After=network.target
[Service]
Type=notify
User=djangoapp
Group=djangoapp
RuntimeDirectory=gunicorn
WorkingDirectory=/home/djangoapp/myproject
ExecStart=/home/djangoapp/myproject/venv/bin/gunicorn
-c /home/djangoapp/myproject/gunicorn.conf.py
config.wsgi:application
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
Servisi etkinleştirin ve başlatın:
sudo systemctl daemon-reload
sudo systemctl enable gunicorn-myproject
sudo systemctl start gunicorn-myproject
sudo systemctl status gunicorn-myproject
Servis loglarını takip etmek için:
sudo journalctl -u gunicorn-myproject -f
OpenLiteSpeed Virtual Host Yapılandırması
İşin asıl kritik kısmı burası. OpenLiteSpeed’i Django uygulamanıza reverse proxy olarak yapılandıracağız. İki yol var: web arayüzü veya doğrudan konfigürasyon dosyaları. Ben konfigürasyon dosyaları yolunu tercih ediyorum çünkü versiyon kontrolü yapılabilir ve otomasyona daha uygun.
Virtual host konfigürasyon dizinini oluşturun:
sudo mkdir -p /usr/local/lsws/conf/vhosts/myproject
sudo mkdir -p /usr/local/lsws/myproject/logs
Virtual host konfigürasyon dosyasını oluşturun:
sudo tee /usr/local/lsws/conf/vhosts/myproject/vhconf.conf > /dev/null << 'EOF'
docRoot /home/djangoapp/myproject/staticfiles
vhDomain yourdomain.com
vhAliases www.yourdomain.com
adminEmails [email protected]
enableGzip 1
errorlog /usr/local/lsws/myproject/logs/error.log {
useServer 0
logLevel WARN
rollingSize 10M
}
accesslog /usr/local/lsws/myproject/logs/access.log {
useServer 0
logFormat "%h %l %u %t "%r" %>s %b"
logHeaders 5
rollingSize 10M
keepDays 30
}
context / {
type proxy
handler django_backend
addDefaultCharset off
}
context /static/ {
location /home/djangoapp/myproject/staticfiles/
allowBrowse 0
addDefaultCharset off
expires {
enableExpires 1
expiresByType image/*=A2592000,text/css=A604800,application/javascript=A604800
}
}
context /media/ {
location /home/djangoapp/myproject/media/
allowBrowse 0
addDefaultCharset off
}
rewrite {
enable 1
autoLoadHtaccess 0
}
EOF
Şimdi ana httpd_config.conf dosyasına virtual host’u ve backend tanımını ekleyelim:
sudo tee -a /usr/local/lsws/conf/httpd_config.conf > /dev/null << 'EOF'
extprocessor django_backend {
type proxy
address 127.0.0.1:8000
maxConns 100
pcKeepAliveTimeout 60
initTimeout 60
retryTimeout 0
respBuffer 0
}
virtualhost myproject {
vhRoot /usr/local/lsws/myproject/
configFile /usr/local/lsws/conf/vhosts/myproject/vhconf.conf
allowSymbolLink 1
enableScript 1
restrained 0
}
EOF
Listener konfigürasyonunda virtual host’u eşleştirin. Httpd_config.conf dosyasındaki listener bölümüne ekleyin:
# Mevcut listener bloğunu düzenleyin, örneğin:
# listener HTTP {
# ...
# map yourdomain.com myproject
# }
sudo nano /usr/local/lsws/conf/httpd_config.conf
Listener bloğuna map yourdomain.com myproject satırını ekledikten sonra OpenLiteSpeed’i yeniden başlatın:
sudo systemctl restart lsws
SSL/TLS Sertifikası Eklemek
Production ortamında HTTPS zorunluluk, HTTP değil. Let’s Encrypt ile ücretsiz SSL sertifikası alalım:
sudo apt install certbot -y
sudo certbot certonly --standalone -d yourdomain.com -d www.yourdomain.com
Sertifika dosyaları /etc/letsencrypt/live/yourdomain.com/ altına kaydedildi. OpenLiteSpeed web arayüzünden (https://sunucu-ip:7080) Listeners bölümüne gidip HTTPS listener oluşturun ve sertifika yollarını girin. Ya da httpd_config.conf dosyasına doğrudan ekleyin:
listener HTTPS {
address *:443
secure 1
map yourdomain.com myproject
SSL {
keyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem
certFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem
CACertFile /etc/letsencrypt/live/yourdomain.com/chain.pem
}
}
Sertifika yenileme için cron job ekleyin:
sudo crontab -e
# Şu satırı ekleyin:
# 0 3 * * 1 certbot renew --quiet && systemctl restart lsws
Yaygın Sorunlar ve Çözümleri
502 Bad Gateway Hatası
Bu hata genellikle Gunicorn’un çalışmadığını veya OpenLiteSpeed’in Gunicorn’a ulaşamadığını gösterir.
# Gunicorn servis durumunu kontrol edin
sudo systemctl status gunicorn-myproject
# Port dinleniyor mu kontrol edin
ss -tlnp | grep 8000
# OpenLiteSpeed error logunu inceleyin
tail -f /usr/local/lsws/myproject/logs/error.log
Static Dosyalar Yüklenmiyor
collectstatic çalıştırıldı mı ve dosya izinleri doğru mu kontrol edin:
sudo chown -R djangoapp:www-data /home/djangoapp/myproject/staticfiles
sudo chmod -R 755 /home/djangoapp/myproject/staticfiles
Permission Denied Hataları
OpenLiteSpeed genellikle nobody kullanıcısı altında çalışır. Dosya izinlerini buna göre düzenleyin:
# OpenLiteSpeed'in hangi kullanıcıyla çalıştığını öğrenin
ps aux | grep lshttpd
# Uygulama dizinine erişim izni verin
sudo chmod o+x /home/djangoapp
sudo chmod o+x /home/djangoapp/myproject
Django ALLOWED_HOSTS Hatası
Production’da bu hatayı çok sık görürsünüz. .env dosyanızdaki ALLOWED_HOSTS değerini kontrol edin ve domain ile IP adresini eklediğinizden emin olun:
# Gunicorn logunu kontrol edin
tail -f /home/djangoapp/logs/gunicorn_error.log
Performans Optimizasyonu
OpenLiteSpeed’in built-in cache mekanizmasını Django ile kullanmak için LSCache middleware’ini entegre edebilirsiniz. Ancak bu ileri düzey bir konu, temel optimizasyonlarla başlayalım.
Gunicorn worker sayısını ve tipini iş yüküne göre ayarlayın. CPU-bound işlemler için sync worker, I/O-bound işlemler (çok sayıda veritabanı sorgusu, harici API çağrıları) için gevent veya eventlet worker kullanabilirsiniz:
pip install gevent
gunicorn.conf.py dosyasını güncelleyin:
worker_class = "gevent"
workers = 3
worker_connections = 1000
Değişiklik sonrası servisi yeniden yükleyin (sıfır downtime):
sudo systemctl reload gunicorn-myproject
Django tarafında da bazı production optimizasyonları ekleyin:
# settings.py içine ekleyin
CONN_MAX_AGE = 60 # Veritabanı bağlantı havuzu
# Template önbellekleme
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'OPTIONS': {
'loaders': [
('django.template.loaders.cached.Loader', [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
]),
],
},
},
]
Monitoring ve Log Yönetimi
Production ortamında ne olduğunu bilmek şart. Temel monitoring için birkaç pratik komut:
# Tüm servislerin durumunu tek seferde kontrol etmek için alias ekleyin
echo "alias check-app='sudo systemctl status lsws gunicorn-myproject && ss -tlnp | grep -E "8000|80|443"'" >> ~/.bashrc
source ~/.bashrc
# Uygulama loglarını canlı takip edin
tail -f /home/djangoapp/logs/gunicorn_error.log
/home/djangoapp/logs/gunicorn_access.log
/usr/local/lsws/myproject/logs/error.log
Logrotate yapılandırması ekleyelim ki loglar zamanla diskimizi doldurmasm:
sudo tee /etc/logrotate.d/myproject > /dev/null << 'EOF'
/home/djangoapp/logs/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 djangoapp djangoapp
sharedscripts
postrotate
systemctl reload gunicorn-myproject > /dev/null 2>&1 || true
endscript
}
EOF
Deployment Workflow
Her güncelleme için tekrarlanabilir bir deployment akışı oluşturun:
#!/bin/bash
# /home/djangoapp/deploy.sh
set -e
PROJECT_DIR="/home/djangoapp/myproject"
cd $PROJECT_DIR
echo ">>> Kodu güncelliyoruz..."
git pull origin main
echo ">>> Sanal ortamı aktif ediyoruz..."
source venv/bin/activate
echo ">>> Bağımlılıkları güncelliyoruz..."
pip install -r requirements.txt --quiet
echo ">>> Migrasyonları çalıştırıyoruz..."
python manage.py migrate --noinput
echo ">>> Statik dosyaları topluyoruz..."
python manage.py collectstatic --noinput --clear
echo ">>> Gunicorn'u yeniden yüklüyoruz..."
sudo systemctl reload gunicorn-myproject
echo ">>> Deployment tamamlandı!"
Script’e çalıştırma izni verin:
chmod +x /home/djangoapp/deploy.sh
Sudoers dosyasına Gunicorn reload için izin ekleyin:
sudo visudo
# Şu satırı ekleyin:
# djangoapp ALL=(ALL) NOPASSWD: /bin/systemctl reload gunicorn-myproject
Sonuç
OpenLiteSpeed ile Django uygulamasını production ortamına taşımak göründüğü kadar karmaşık değil, ancak her adımı doğru yapmak gerekiyor. Bu yazıda ele aldığımız mimari; OpenLiteSpeed’in reverse proxy kabiliyetleri, Gunicorn’un güvenilir WSGI sunucusu işlevi, systemd’nin servis yönetimi ve Let’s Encrypt’in SSL desteği bir araya gelince sağlam bir production stack oluşturuyor.
Nginx + Gunicorn kombinasyonuna alışkın bir sysadmin olarak OpenLiteSpeed’e geçişin en büyük avantajı web tabanlı yönetim paneli ve built-in cache mekanizması. Özellikle ekibinizde derin Linux bilgisine sahip olmayan geliştiriciler varsa OpenLiteSpeed’in görsel arayüzü büyük kolaylık sağlıyor.
Üretim ortamında şunları asla atlamamalısınız: DEBUG=False ayarı, güçlü SECRET_KEY, güncel SSL sertifikası, düzenli yedekleme ve log monitoring. Bu temeller sağlamdaysa Django uygulamanız OpenLiteSpeed arkasında gayet verimli çalışacaktır.
Sorularınız veya karşılaştığınız sorunlar için yorum bölümünü kullanabilirsiniz, elimden geldiğince yardımcı olmaya çalışırım.