OpenLiteSpeed ile Django ve Python Uygulaması Sunumu

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.

Yorum yapın