Flask Uygulamalarını uWSGI ve Nginx ile Ubuntu 22.04 Üzerinde Dağıtma
Giriş
Web uygulamalarının geliştirilmesi günümüzde oldukça popüler hale gelmiştir. Python tabanlı mikro web çatısı Flask, esnekliği ve hafif yapısıyla birçok geliştirici tarafından tercih edilmektedir. Ancak Flask uygulamaları, geliştirme sunucusuyla (Flask’ın kendi app.run() fonksiyonu) doğrudan üretim ortamında kullanılmamalıdır. Üretim ortamları için daha sağlam, performanslı ve güvenli çözümlere ihtiyaç duyulur. Bu makalede, Flask uygulamalarınızı Ubuntu 22.04 sunucusu üzerinde uWSGI uygulama sunucusu ve Nginx ters proxy sunucusu kullanarak nasıl dağıtacağınızı adım adım açıklayacağız.
Flask, uWSGI ve Nginx üçlüsü, modern web uygulamalarını dağıtmak için kanıtlanmış ve yaygın olarak kullanılan bir mimaridir. Bu kombinasyonun her bir bileşeni belirli bir role sahiptir:
* Flask: Web uygulamanızın kendisi, iş mantığını ve API uç noktalarını barındırır.
* uWSGI: Bir WSGI (Web Server Gateway Interface) sunucusudur. Flask gibi Python web uygulamaları ile web sunucuları (Nginx gibi) arasında bir köprü görevi görür. Uygulama kodunuzu çalıştırır ve gelen istekleri işleyerek yanıtları Nginx’e geri gönderir. Performans, ölçeklenebilirlik ve güvenlik açısından geliştirme sunucusundan çok daha üstündür.
* Nginx: Yüksek performanslı bir web sunucusu ve ters proxy’dir. Doğrudan istemcilerden gelen istekleri alır, statik dosyaları (CSS, JavaScript, resimler) doğrudan sunar ve dinamik istekleri (Flask uygulamanızın işleyeceği istekler) uWSGI’ye yönlendirir. Nginx, yük dengeleme, SSL/TLS sonlandırma ve güvenlik gibi ek özellikler de sunar.
Bu rehberin sonunda, Flask uygulamanızın güvenli, performanslı ve ölçeklenebilir bir şekilde internet üzerinden erişilebilir olmasını sağlayacaksınız.
Ön Koşullar
Bu rehbere başlamadan önce aşağıdaki ön koşulların yerine getirildiğinden emin olun:
* Ubuntu 22.04 Sunucusu: Temiz bir Ubuntu 22.04 kurulumu yapılmış bir sunucuya erişiminiz olmalı. Bir VPS (Virtual Private Server) veya bulut sunucu kullanabilirsiniz.
* Sudo Yetkilerine Sahip Bir Kullanıcı: Root olmayan, ancak sudo komutunu kullanarak yükseltilmiş ayrıcalıklarla komut çalıştırabilen bir kullanıcı hesabınız olmalı. Güvenlik nedenleriyle root kullanıcısı olarak çalışmaktan kaçınılması önerilir.
* Temel Linux Komut Bilgisi: Komut satırında dosya oluşturma, düzenleme ve dizinlerde gezinme gibi temel işlemlere aşina olmalısınız.
* Python 3 ve Pip: Ubuntu 22.04 genellikle Python 3 ile birlikte gelir. Pip, Python paket yöneticisidir ve sanal ortamlar oluşturmak ve paketleri yüklemek için gereklidir.
İlk adım olarak, sunucunuzdaki paket listesini güncelleyelim ve yükseltmeleri yapalım:
sudo apt update
sudo apt upgrade -y
Flask Uygulamasını Hazırlama
Flask uygulamanızı sunucuya dağıtmadan önce, uygulamanın kendisini ve gerekli bağımlılıklarını hazırlamamız gerekiyor. Uygulama dosyalarınızı sunucunuza aktarmak için scp veya git gibi yöntemleri kullanabilirsiniz. Bu rehberde, basit bir Flask uygulaması oluşturup onu dağıtacağız. Uygulama dosyalarınızı genellikle /var/www/ dizini altında bir alt dizine yerleştirmek iyi bir uygulamadır. Örneğin, /var/www/my_flask_app.
sudo mkdir -p /var/www/my_flask_app
sudo chown -R $USER:$USER /var/www/my_flask_app # Kullanıcınıza sahiplik verin
cd /var/www/my_flask_app
Sanal Ortam Oluşturma
Python projeleri için sanal ortamlar kullanmak, bağımlılık çakışmalarını önlemek ve proje bağımlılıklarını izole etmek için kritik öneme sahiptir.
python3 -m venv venv
source venv/bin/activate
Bu komutlar, venv adında bir sanal ortam oluşturur ve onu etkinleştirir. Komut satırınızın başında (venv) ifadesini görmelisiniz.
Flask Uygulama Kodu
Şimdi basit bir Flask uygulaması oluşturalım. app.py adında bir dosya oluşturun:
nano app.py
Dosyanın içine aşağıdaki kodu yapıştırın:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, Flask! This is a uWSGI + Nginx deployment on Ubuntu 22.04.'
@app.route('/test')
def test_route():
return 'This is a test route.'
if __name__ == '__main__':
app.run(debug=True)
Kaydedip kapatın (Ctrl+O, Enter, Ctrl+X).
Gereksinimleri Yükleme
Uygulamanızın ihtiyaç duyduğu Python paketlerini requirements.txt dosyasına eklemelisiniz.
nano requirements.txt
İçine sadece Flask yazın:
Flask
Kaydedip kapatın. Şimdi bu gereksinimleri sanal ortamınıza yükleyin:
pip install -r requirements.txt
Uygulamayı Test Etme
Flask uygulamanızın düzgün çalışıp çalışmadığını test etmek için geliştirme sunucusuyla çalıştırabilirsiniz:
flask run --host=0.0.0.0
Bu komut, Flask uygulamasını tüm ağ arayüzlerinde dinlemeye başlatır (genellikle 5000 portunda). Sunucunuzun IP adresini biliyorsanız, web tarayıcınızdan http://SUNUCU_IP_ADRESINIZ:5000 adresine giderek “Hello, Flask!” mesajını görmelisiniz. Test ettikten sonra, Ctrl+C ile geliştirme sunucusunu durdurun. Unutmayın, bu geliştirme sunucusu üretim için uygun değildir. Sanal ortamı devre dışı bırakmak için deactivate komutunu kullanabilirsiniz, ancak şimdilik etkin bırakabiliriz.
uWSGI Kurulumu ve Yapılandırması
uWSGI, Flask uygulamamız ile Nginx arasında aracı görevi görecek olan uygulama sunucusudur.
uWSGI Kurulumu
Sanal ortamınız etkin durumdayken uWSGI’yi pip ile yükleyin:
pip install uwsgi
apt ile yüklemek yerine pip ile yüklemek, uWSGI’nin sanal ortamınızın Python yorumlayıcısını kullanmasını sağlar ve sistem genelindeki Python paketleriyle çakışmaları önler.
uWSGI Yapılandırma Dosyası Oluşturma
uWSGI’yi komut satırı argümanlarıyla çalıştırmak yerine, bir yapılandırma dosyası kullanmak daha iyidir. Bu, ayarları daha düzenli tutar ve Systemd servisi ile entegrasyonu kolaylaştırır. Uygulama dizininizde uwsgi.ini adında bir dosya oluşturalım:
nano uwsgi.ini
Aşağıdaki içeriği ekleyin:
[uwsgi]
module = app:app
master = true
processes = 5
socket = /tmp/my_flask_app.sock
chmod-socket = 660
vacuum = true
die-on-term = true
logto = /var/log/uwsgi/my_flask_app.log
chdir = /var/www/my_flask_app
virtualenv = /var/www/my_flask_app/venv
Bu ayarların anlamları:
* module = app:app: app.py dosyasındaki app adlı Flask uygulamasını çalıştırmasını söyler. Eğer Flask uygulamanız başka bir dosyada veya farklı bir değişken adında ise, buna göre ayarlamalısınız (örneğin wsgi:application veya my_app:app).
* master = true: Bir ana uWSGI süreci başlatır.
* processes = 5: 5 adet işçi (worker) süreci başlatır. Bu, uygulamanızın aynı anda birden fazla isteği işleyebilmesini sağlar. İhtiyaçlarınıza göre bu sayıyı ayarlayabilirsiniz.
* socket = /tmp/my_flask_app.sock: Nginx’in uygulamanızla iletişim kurmak için kullanacağı Unix soketinin yolunu belirtir. Unix soketleri, TCP portlarına göre daha hızlıdır çünkü ağ yığını üzerinden geçmezler.
* chmod-socket = 660: Soket dosyasının izinlerini ayarlar. Bu, Nginx’in sokete erişebilmesini sağlar. www-data grubunun (Nginx’in varsayılan kullanıcısı) okuma/yazma iznine sahip olmasını sağlar.
* vacuum = true: uWSGI durdurulduğunda soket dosyasını ve PID dosyasını otomatik olarak temizler.
* die-on-term = true: uWSGI’nin ana sürecinin sonlandırılması durumunda tüm işçi süreçlerini de sonlandırır.
* logto = /var/log/uwsgi/my_flask_app.log: uWSGI günlüklerini bu dosyaya yazar. Bu dosyanın oluşturulması ve uWSGI kullanıcısının yazma iznine sahip olması gerekecektir.
* chdir = /var/www/my_flask_app: uWSGI’nin uygulamanızın kök dizininde çalışmasını sağlar.
* virtualenv = /var/www/my_flask_app/venv: Sanal ortamınızın yolunu belirtir.
Kaydedip kapatın. Günlük dosyası için dizin oluşturalım ve izinleri ayarlayalım:
sudo mkdir -p /var/log/uwsgi
sudo chown -R $USER:www-data /var/log/uwsgi # Kullanıcınız ve Nginx grubuna yazma izni verin
uWSGI Test Etme
uWSGI yapılandırmasının düzgün çalıştığından emin olmak için elle çalıştırabiliriz:
uwsgi --ini uwsgi.ini
Eğer herhangi bir hata mesajı almazsanız ve komut satırı donuk kalırsa, uWSGI başarıyla çalışıyor demektir. Yeni bir terminal açıp veya mevcut terminali arka plana atıp soket dosyasının oluşturulup oluşturulmadığını kontrol edebilirsiniz:
ls -l /tmp/my_flask_app.sock
Eğer dosya listeleniyorsa, uWSGI soketi başarıyla oluşturmuştur. Ctrl+C ile uWSGI’yi durdurun.
uWSGI için Systemd Servisi Oluşturma
uWSGI’yi manuel olarak çalıştırmak yerine, sunucu yeniden başlatıldığında otomatik olarak başlamasını ve arka planda çalışmasını sağlamak için bir Systemd servisi oluşturalım.
sudo nano /etc/systemd/system/my_flask_app.service
Aşağıdaki içeriği yapıştırın. User ve Group değerlerini sunucunuzdaki uygun kullanıcı ve grupla değiştirmeyi unutmayın. Genellikle www-data grubu Nginx ile uyumludur.
[Unit]
Description=uWSGI instance to serve my_flask_app
After=network.target
[Service]
User=your_user # Kendi kullanıcı adınızla değiştirin (örn. ubuntu, admin)
Group=www-data
WorkingDirectory=/var/www/my_flask_app
Environment="PATH=/var/www/my_flask_app/venv/bin"
ExecStart=/var/www/my_flask_app/venv/bin/uwsgi --ini /var/www/my_flask_app/uwsgi.ini
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all
[Install]
WantedBy=multi-user.target
Bu dosya, Systemd’ye uWSGI uygulamanızı nasıl başlatacağını ve yöneteceğini söyler:
* Description: Servisin kısa bir açıklaması.
* After=network.target: Ağ servisleri başlatıldıktan sonra bu servisin başlamasını sağlar.
* User ve Group: uWSGI sürecinin hangi kullanıcı ve grup altında çalışacağını belirtir. Bu, güvenlik için önemlidir. Soket dosyasının bu kullanıcı ve grup tarafından erişilebilir olduğundan emin olun.
* WorkingDirectory: Uygulamanızın kök dizinini belirtir.
* Environment="PATH=...": Sanal ortamınızın bin dizinini PATH’e ekler, böylece uwsgi komutu sanal ortamdan doğru bir şekilde çağrılır.
* ExecStart: uWSGI’yi yapılandırma dosyasıyla başlatan komut.
* Restart=always: Servis başarısız olursa veya beklenmedik bir şekilde durursa otomatik olarak yeniden başlatılmasını sağlar.
* KillSignal=SIGQUIT: uWSGI’nin zarif bir şekilde kapanmasını sağlayan sinyal.
* Type=notify: uWSGI’nin Systemd’ye başlatıldığını bildirmesini sağlar.
* StandardError=syslog: Hataların syslog’a kaydedilmesini sağlar.
* WantedBy=multi-user.target: Sunucu açıldığında bu servisin otomatik olarak başlatılmasını sağlar.
Kaydedip kapatın. Şimdi Systemd’yi yeni servisi yeniden yüklemesi için bilgilendirin, servisi başlatın ve otomatik başlamasını sağlayın:
sudo systemctl daemon-reload
sudo systemctl start my_flask_app
sudo systemctl enable my_flask_app
Servisin durumunu kontrol ederek düzgün çalışıp çalışmadığını doğrulayın:
sudo systemctl status my_flask_app
Çıktıda active (running) ibaresini görmelisiniz.
Nginx Kurulumu ve Yapılandırması
Nginx, istemcilerden gelen istekleri alacak, statik dosyaları sunacak ve dinamik istekleri uWSGI’ye yönlendirecek olan ters proxy sunucusudur.
Nginx Kurulumu
Nginx’i Ubuntu paket yöneticisi aracılığıyla kolayca yükleyebilirsiniz:
sudo apt install nginx -y
Kurulumdan sonra Nginx servisi otomatik olarak başlayacaktır. Durumunu kontrol edebilirsiniz:
sudo systemctl status nginx
active (running) olduğundan emin olun.
Nginx Yapılandırma Dosyası Oluşturma
Şimdi Nginx’i Flask uygulamanıza gelen istekleri uWSGI’ye yönlendirecek şekilde yapılandıralım. Nginx yapılandırma dosyaları /etc/nginx/sites-available/ dizininde bulunur.
sudo nano /etc/nginx/sites-available/my_flask_app
Aşağıdaki içeriği yapıştırın. server_name kısmını sunucunuzun IP adresi veya alan adınızla değiştirmeyi unutmayın.
server {
listen 80;
server_name your_domain.com www.your_domain.com your_server_ip; # Kendi alan adınız veya IP adresinizle değiştirin
location / {
include uwsgi_params;
uwsgi_pass unix:///tmp/my_flask_app.sock; # uWSGI yapılandırmasındaki soket yoluyla eşleşmeli
}
# Statik dosyalarınızı doğrudan Nginx üzerinden sunmak için aşağıdaki bölümü etkinleştirebilirsiniz.
# Örneğin, Flask uygulamanızın 'static' klasöründeki dosyalar.
# location /static {
# alias /var/www/my_flask_app/static;
# }
error_log /var/log/nginx/my_flask_app_error.log;
access_log /var/log/nginx/my_flask_app_access.log;
}
Bu ayarların anlamları:
* listen 80: Nginx’in 80 numaralı HTTP portunu dinlemesini sağlar.
* server_name: Nginx’in hangi alan adları veya IP adresleri için bu yapılandırmayı kullanacağını belirtir.
* location /: Tüm gelen istekleri bu bloğa yönlendirir.
* include uwsgi_params: uWSGI ile iletişim kurmak için gerekli olan standart parametreleri içerir.
* uwsgi_pass unix:///tmp/my_flask_app.sock: İstekleri uWSGI’nin dinlediği Unix soketine yönlendirir. Bu yol, uWSGI yapılandırma dosyanızdaki socket değeriyle aynı olmalıdır.
* location /static: Eğer uygulamanızın statik dosyaları varsa (CSS, JS, resimler), Nginx’in bunları doğrudan sunması için bu bloğu kullanabilirsiniz. Bu, uWSGI’nin bu tür isteklerle uğraşmasını engelleyerek performansı artırır. alias yolu, statik dosyalarınızın sunucudaki fiziksel konumunu işaret etmelidir.
* error_log ve access_log: Nginx’in bu siteye ait hata ve erişim günlüklerini nereye yazacağını belirtir.
Kaydedip kapatın.
Nginx Yapılandırmasını Etkinleştirme
Oluşturduğumuz yapılandırma dosyasını etkinleştirmek için, /etc/nginx/sites-enabled/ dizinine sembolik bir bağlantı (symlink) oluşturmalıyız:
sudo ln -s /etc/nginx/sites-available/my_flask_app /etc/nginx/sites-enabled
Varsayılan Nginx yapılandırmasını devre dışı bırakmak iyi bir uygulamadır, böylece çakışmalar önlenir:
sudo rm /etc/nginx/sites-enabled/default
Nginx’i Test Etme
Nginx yapılandırma dosyasında herhangi bir sözdizimi hatası olup olmadığını kontrol etmek için:
sudo nginx -t
Eğer test is successful mesajını görürseniz, yapılandırmanız doğru demektir. Şimdi Nginx’i yeniden başlatarak yeni yapılandırmayı uygulayın:
sudo systemctl restart nginx
Güvenlik Duvarı Yapılandırması
Sunucunuzda bir güvenlik duvarı (firewall) etkinse, Nginx’in gelen HTTP (80) ve HTTPS (443) isteklerini alabilmesi için bu portlara izin vermeniz gerekir. Ubuntu’da UFW (Uncomplicated Firewall) yaygın olarak kullanılır.
sudo ufw allow 'Nginx HTTP' # HTTP (80) portuna izin verir
sudo ufw allow 'Nginx HTTPS' # Eğer SSL/TLS kuracaksanız HTTPS (443) portuna da izin verin
sudo ufw enable # Güvenlik duvarını etkinleştirir (eğer daha önce etkin değilse)
sudo ufw status # Güvenlik duvarı durumunu kontrol edin
Şimdi web tarayıcınızdan sunucunuzun IP adresine veya alan adına giderek Flask uygulamanızın çalıştığını doğrulayabilirsiniz. http://SUNUCU_IP_ADRESINIZ veya http://alanadiniz.com adresine gidin. “Hello, Flask! This is a uWSGI + Nginx deployment on Ubuntu 22.04.” mesajını görmelisiniz.
Sonuç
Bu rehberde, bir Flask uygulamasını Ubuntu 22.04 sunucusu üzerinde uWSGI ve Nginx kullanarak nasıl dağıtacağınızı adım adım öğrendiniz. Flask uygulamanızı bir sanal ortamda hazırladık, uWSGI’yi yapılandırarak Flask ile Nginx arasında bir köprü oluşturduk ve Nginx’i ters proxy olarak ayarlayarak gelen istekleri uWSGI’ye yönlendirdik. Son olarak, güvenlik duvarı ayarlarını yaparak uygulamanızın internetten erişilebilir olmasını sağladık.
Bu kurulum, Flask uygulamalarınız için sağlam, güvenli ve performanslı bir üretim ortamı sağlar. Nginx’in statik dosya sunma, yük dengeleme ve SSL/TLS sonlandırma yetenekleri, uygulamanızın performansını ve güvenliğini artırırken, uWSGI’nin çoklu işlem yetenekleri uygulamanızın ölçeklenebilirliğini sağlar.
Ek Bilgiler ve Sonraki Adımlar
Uygulamanızı daha da geliştirmek ve üretim ortamına uygun hale getirmek için aşağıdaki adımları düşünebilirsiniz:
SSL/TLS (HTTPS) ile Güvenlik
Web uygulamanızın güvenliğini artırmak için HTTPS kullanmak kritik öneme sahiptir. Let’s Encrypt ve Certbot, ücretsiz SSL/TLS sertifikaları almak ve Nginx ile otomatik olarak yapılandırmak için harika bir yoldur.
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d your_domain.com -d www.your_domain.com
Bu komutlar, Certbot’u yükler ve Nginx yapılandırmanızı otomatik olarak HTTPS’i kullanacak şekilde günceller.
Statik Dosyalar ve Medya Dosyaları
Eğer Flask uygulamanızın statik dosyaları (CSS, JS, resimler) veya kullanıcı tarafından yüklenen medya dosyaları varsa, Nginx’in bunları doğrudan sunmasını sağlamak en verimli yoldur. Yukarıdaki Nginx yapılandırmasında location /static bloğu için bir örnek verilmiştir. Uygulamanızın static klasörünün yanı sıra, kullanıcıların yüklediği dosyaları depoladığınız ayrı bir media klasörü varsa, benzer bir location /media bloğu ekleyebilirsiniz:
location /media {
alias /var/www/my_flask_app/media; # Medya dosyalarınızın yolu
}
Bu, Flask uygulamanızın bu tür isteklerle uğraşmasını engelleyerek uygulamanın daha hızlı yanıt vermesini sağlar.
Gunicorn Alternatifi
uWSGI popüler bir WSGI sunucusu olsa da, Gunicorn (Green Unicorn) da yaygın olarak kullanılan başka bir güçlü alternatiftir. Kurulum ve yapılandırma adımları uWSGI’ye benzerdir ve Gunicorn da Systemd servisleri ile entegre edilebilir. Tercihiniz veya projenizin gereksinimleri doğrultusunda Gunicorn’u da değerlendirebilirsiniz.
Hata Ayıklama ve Günlükler
Herhangi bir sorunla karşılaştığınızda, aşağıdaki günlük dosyalarını kontrol etmek sorun giderme için çok önemlidir:
* uWSGI Günlükleri: /var/log/uwsgi/my_flask_app.log
* Systemd Servis Günlükleri: sudo journalctl -u my_flask_app.service
* Nginx Hata Günlükleri: /var/log/nginx/my_flask_app_error.log
* Nginx Erişim Günlükleri: /var/log/nginx/my_flask_app_access.log
* Nginx Genel Hata Günlükleri: /var/log/nginx/error.log
Performans Optimizasyonları
uWSGI İşçi Sayısı: uwsgi.ini dosyasındaki processes değerini sunucunuzun CPU çekirdeği sayısına göre ayarlayın. Genellikle (CPU çekirdeği sayısı 2) + 1 gibi bir formül önerilir, ancak en iyi performans için test yapmanız gerekebilir.
* Nginx Buffer Boyutları: Nginx yapılandırmasına client_max_body_size, client_body_buffer_size, proxy_buffers, proxy_buffer_size gibi direktifler ekleyerek büyük istekler veya yanıtlar için performansı optimize edebilirsiniz.
* Önbellekleme: Nginx’i statik dosyalar için önbellekleme yapacak şekilde yapılandırarak tekrar eden isteklerde performansı artırabilirsiniz.
Bu adımlar, Flask uygulamanızı üretim ortamında daha da güçlendirecek ve daha iyi bir kullanıcı deneyimi sunmanızı sağlayacaktır. Başarılı dağıtımlar dileriz!