Flask Uygulamalarını Gunicorn ve Nginx ile Ubuntu 18.04 Üzerinde Yayınlama
Flask, Python tabanlı hafif ve esnek bir web çatısıdır (web framework). Küçük ve orta ölçekli web uygulamaları, API’ler ve mikro hizmetler geliştirmek için idealdir. Ancak Flask’ın dahili geliştirme sunucusu (development server) üretim ortamları için tasarlanmamıştır. Üretim ortamında Flask uygulamalarını güvenli, performanslı ve ölçeklenebilir bir şekilde yayınlamak için bir WSGI (Web Server Gateway Interface) sunucusu ve bir ters proxy (reverse proxy) kullanmak gerekir. Bu makalede, Flask uygulamalarınızı Ubuntu 18.04 işletim sistemi üzerinde Gunicorn WSGI sunucusu ve Nginx ters proxy sunucusu ile nasıl yayınlayacağınızı adım adım detaylı bir şekilde anlatacağız.
Bu kurulum, uygulamanızın performansını artırırken aynı zamanda güvenlik ve yönetilebilirlik açısından da önemli avantajlar sunar. Gunicorn, Flask uygulamanız ile Nginx arasında bir köprü görevi görürken, Nginx gelen istemci isteklerini yöneterek statik dosyaları sunar, SSL sonlandırması yapar ve yük dengeleme gibi gelişmiş özellikler sağlar.
Neden Gunicorn ve Nginx Kullanmalıyız?
Flask’ın kendi geliştirme sunucusu, aynı anda yalnızca tek bir isteği işleyebilir ve güvenlik açıklarına karşı savunmasızdır. Üretim ortamında gerçek dünya trafiğini yönetmek için tasarlanmamıştır. İşte Gunicorn ve Nginx ikilisinin neden gerekli olduğunu açıklayan bazı temel nedenler:
Gunicorn (WSGI Sunucusu)
Gunicorn (Green Unicorn), Python WSGI uygulamaları için sağlam ve hızlı bir HTTP sunucusu çözümüdür. Flask gibi WSGI uyumlu uygulamaları çalıştırabilir.
* Çoklu İşlem Desteği: Gunicorn, aynı anda birden fazla isteği işlemek için birden fazla işçi (worker) süreci başlatır. Bu, uygulamanızın eşzamanlı kullanıcı sayısını artırır ve daha iyi yanıt süreleri sağlar.
* Basit ve Hafif: Kurulumu ve yapılandırması kolaydır. Kaynak tüketimi düşüktür.
* Güvenilirlik: Üretim ortamlarında test edilmiş ve kanıtlanmış bir çözümdür. Hata durumlarında işçi süreçlerini otomatik olarak yeniden başlatabilir.
* WSGI Uyumluluğu: Python web uygulamaları için standart bir arayüz olan WSGI’yi destekler, bu da Flask, Django gibi birçok framework ile sorunsuz çalışmasını sağlar.
Nginx (Ters Proxy Sunucusu)
Nginx, yüksek performanslı, açık kaynaklı bir web sunucusu ve ters proxy sunucusudur. Gunicorn gibi bir uygulama sunucusunun önüne yerleştirilir.
* Performans: Nginx, statik dosyaları (CSS, JavaScript, resimler vb.) Gunicorn’dan çok daha hızlı ve verimli bir şekilde sunabilir.
* Yük Dengeleme: Gelen istekleri birden fazla Gunicorn örneğine dağıtarak uygulamanızın ölçeklenebilirliğini artırabilir.
* SSL/TLS Sonlandırma: Nginx, SSL sertifikalarını yönetebilir ve şifreli trafiği sonlandırarak Gunicorn’un bu yükten kurtulmasını sağlar. Bu, uygulamanızın güvenliğini artırır.
* Güvenlik: Doğrudan internete açık olan tek bileşen Nginx olduğu için, potansiyel güvenlik açıklarını azaltır ve DDoS saldırılarına karşı bir tampon görevi görebilir.
* Hata Sayfaları ve URL Yönlendirmeleri: Özel hata sayfaları oluşturabilir ve URL yönlendirmeleri gibi gelişmiş trafik yönetimi yapabilir.
Bu makalede Ubuntu 18.04 kullanmamızın nedeni, bu sürümün hala geniş bir kullanıcı tabanına sahip olması ve birçok kurumsal ortamda tercih edilmesidir. İşlemler diğer Ubuntu sürümlerinde de benzer olacaktır.
Ön Gereksinimler
Bu rehbere başlamadan önce aşağıdaki ön gereksinimlere sahip olmanız gerekmektedir:
* Ubuntu 18.04 işletim sistemine sahip bir sunucu (VPS, EC2 vb.).
* SSH erişimi için bir SSH istemcisi.
* sudo ayrıcalıklarına sahip bir kullanıcı hesabı (güvenlik nedeniyle root kullanıcısı yerine bu kullanıcı ile çalışmanız önerilir).
* İsteğe bağlı olarak, uygulamanızı yayınlamak için bir alan adı (örneğin, ornekuygulama.com).
Adım 1: Sunucu Hazırlığı ve Temel Kurulumlar
İlk olarak sunucumuzu güncelleyelim ve gerekli paketleri kuralım. SSH ile sunucunuza bağlanın.
sudo apt update
sudo apt upgrade -y
Ardından Python 3 ve sanal ortam (virtual environment) oluşturmak için gerekli araçları kuralım:
sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev -y
Bu komutlar, Python pip paket yöneticisini, Python geliştirme başlıklarını (Flask ve Gunicorn’un bazı bağımlılıkları için gerekli olabilir), derleyici araçlarını ve SSL/TLS ile ilgili kütüphaneleri kurar.
Güvenlik amacıyla, uygulamanızı çalıştırmak için yeni bir kullanıcı oluşturalım. Bu, uygulamanızın root ayrıcalıklarıyla çalışmasını engeller.
sudo adduser ornekkullanici
sudo usermod -aG sudo ornekkullanici
ornekkullanici yerine kendi istediğiniz kullanıcı adını kullanabilirsiniz. Şimdi bu yeni kullanıcıya geçiş yapalım:
su - ornekkullanici
Adım 2: Flask Uygulamasını Oluşturma ve Sanal Ortam Kurulumu
Uygulamamız için bir dizin oluşturalım ve bu dizine geçiş yapalım.
mkdir ~/myflaskapp
cd ~/myflaskapp
Şimdi bir Python sanal ortamı oluşturalım ve etkinleştirelim. Sanal ortamlar, projenizin bağımlılıklarını sistem genelindeki Python paketlerinden izole etmenizi sağlar.
python3 -m venv venv
source venv/bin/activate
Sanal ortam etkinleştirildikten sonra, komut isteminizin başında (venv) ifadesini görmelisiniz. Şimdi Flask ve Gunicorn’u kuralım:
pip install Flask gunicorn
Bu bağımlılıkları requirements.txt dosyasına kaydedelim:
pip freeze > requirements.txt
Şimdi basit bir Flask uygulaması oluşturalım. wsgi.py adında bir dosya oluşturun:
nano wsgi.py
İçine aşağıdaki kodu yapıştırın:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Merhaba, Flask ve Gunicorn ile Nginx üzerinden yayınlanıyorum!'
if __name__ == '__main__':
app.run(debug=True)
Dosyayı kaydedip kapatın (CTRL+O, Enter, CTRL+X).
Uygulamanızın doğru çalıştığından emin olmak için Gunicorn ile test edelim:
gunicorn --bind 0.0.0.0:5000 wsgi:app
Bu komut, Gunicorn’un uygulamanızı 5000 numaralı port üzerinden tüm arayüzlerde dinlemesini sağlar. Tarayıcınızdan http://SUNUCU_IP_ADRESINIZ:5000 adresine giderek uygulamanızın çalıştığını doğrulayabilirsiniz. Testi tamamladıktan sonra CTRL+C ile Gunicorn’u durdurabilirsiniz.
Bu noktada, Gunicorn’u bir sistem servisi olarak yapılandırmamız gerekiyor ki sunucu yeniden başladığında otomatik olarak başlasın ve arka planda çalışsın.
Adım 3: Gunicorn’u Systemd Servisi Olarak Yapılandırma
Sanal ortamdan çıkın:
deactivate
Şimdi Gunicorn için bir Systemd servis dosyası oluşturalım. Bu dosya, Gunicorn’un nasıl çalıştırılacağını ve yönetileceğini tanımlayacaktır.
sudo nano /etc/systemd/system/myflaskapp.service
Aşağıdaki içeriği dosyaya yapıştırın. ornekkullanici yerine kendi kullanıcı adınızı, /home/ornekkullanici/myflaskapp yerine ise uygulamanızın yolunu güncellemeyi unutmayın.
[Unit]
Description=Gunicorn instance to serve myflaskapp
After=network.target
[Service]
User=ornekkullanici
Group=www-data
WorkingDirectory=/home/ornekkullanici/myflaskapp
ExecStart=/home/ornekkullanici/myflaskapp/venv/bin/gunicorn --workers 3 --bind unix:/home/ornekkullanici/myflaskapp/myflaskapp.sock -m 007 wsgi:app
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
Restart=on-failure
[Install]
WantedBy=multi-user.target
Açıklamalar:
* Description: Servisin kısa açıklaması.
* After=network.target: Servisin ağ bağlantısı kurulduktan sonra başlamasını sağlar.
* User: Gunicorn sürecinin hangi kullanıcı altında çalışacağını belirtir. Uygulama klasörünüzün sahibini kullanın.
* Group: Gunicorn sürecinin hangi grup altında çalışacağını belirtir. www-data grubu, Nginx’in de erişebileceği ortak bir gruptur. Uygulama klasörünüze www-data grubunun erişimini sağlamanız gerekebilir (sudo chown -R ornekkullanici:www-data /home/ornekkullanici/myflaskapp ve sudo chmod -R g+rwx /home/ornekkullanici/myflaskapp).
* WorkingDirectory: Uygulamanızın kök dizini.
* ExecStart: Gunicorn’u başlatmak için çalıştırılacak komut.
--workers 3: Gunicorn’un 3 işçi süreci ile çalışmasını sağlar. Bu değeri sunucunuzun CPU çekirdek sayısına göre ayarlayabilirsiniz (genellikle 2 CPU_ÇEKİRDEĞİ + 1 formülü önerilir).
* --bind unix:/home/ornekkullanici/myflaskapp/myflaskapp.sock: Gunicorn’un bir TCP portu yerine bir Unix soketi üzerinden dinlemesini sağlar. Bu, Nginx ile yerel iletişim için daha hızlı ve güvenli bir yöntemdir.
* -m 007: Soket dosyası için izinleri ayarlar, böylece Nginx bu sokete erişebilir.
* wsgi:app: wsgi.py dosyasındaki app adlı Flask uygulamasını belirtir.
* ExecReload: Gunicorn’u yeniden yüklemek için komut.
* Restart=on-failure: Gunicorn süreci bir hata nedeniyle durursa otomatik olarak yeniden başlatılır.
* WantedBy=multi-user.target: Bu servisin çok kullanıcılı sistem başlatıldığında etkinleştirilmesini sağlar.
Dosyayı kaydedin ve kapatın. Şimdi Systemd’yi yeni servisi tanımak için yeniden yükleyin:
sudo systemctl daemon-reload
Gunicorn servisini başlatın ve sunucu açılışında otomatik başlaması için etkinleştirin:
sudo systemctl start myflaskapp
sudo systemctl enable myflaskapp
Servisin durumunu kontrol edin:
sudo systemctl status myflaskapp
Çıktıda active (running) ibaresini görmelisiniz. Ayrıca, Gunicorn’un soket dosyasını oluşturup oluşturmadığını da kontrol edebilirsiniz:
ls -l /home/ornekkullanici/myflaskapp/myflaskapp.sock
Bu dosyanın www-data grubu tarafından okunabilir ve yazılabilir olması gerekmektedir. Eğer yetki sorunları yaşarsanız, uygulama dizininin ve soket dosyasının sahiplik ve izinlerini kontrol edin.
sudo chown -R ornekkullanici:www-data /home/ornekkullanici/myflaskapp
sudo chmod -R g+rw /home/ornekkullanici/myflaskapp
Adım 4: Nginx’i Kurma ve Yapılandırma
Gunicorn artık Flask uygulamanızı bir Unix soketi üzerinden dinliyor. Şimdi Nginx’i kurup yapılandırarak gelen HTTP isteklerini bu sokete yönlendirelim.
Nginx’i kuralım:
sudo apt install nginx -y
Kurulumdan sonra Nginx servisi otomatik olarak başlayacaktır. Güvenlik duvarını (UFW) yapılandırarak Nginx’e gelen HTTP (ve ileride HTTPS) trafiğine izin verelim:
sudo ufw allow 'Nginx HTTP'
sudo ufw allow 'Nginx HTTPS'
sudo ufw allow 'OpenSSH'
sudo ufw enable
sudo ufw status komutu ile firewall durumunu kontrol edebilirsiniz.
Şimdi Flask uygulamanız için bir Nginx sunucu bloğu (server block) yapılandırma dosyası oluşturalım.
sudo nano /etc/nginx/sites-available/myflaskapp
Aşağıdaki içeriği dosyaya yapıştırın. ornekuygulama.com ve www.ornekuygulama.com yerine kendi alan adınızı veya sunucunuzun IP adresini kullanın. Eğer alan adınız yoksa, server_name satırını server_name SUNUCU_IP_ADRESINIZ; olarak değiştirebilirsiniz.
server {
listen 80;
server_name ornekuygulama.com www.ornekuygulama.com;
location / {
include proxy_params;
proxy_pass http://unix:/home/ornekkullanici/myflaskapp/myflaskapp.sock;
}
location /static {
alias /home/ornekkullanici/myflaskapp/static;
}
}
Açıklamalar:
* listen 80: Nginx’in 80 numaralı HTTP portundan gelen istekleri dinlemesini sağlar.
* server_name: Bu sunucu bloğunun hangi alan adları için etkin olacağını belirtir.
* location /: Tüm gelen istekleri yakalar ve Gunicorn’a yönlendirir.
* include proxy_params: Nginx’in ters proxy olarak çalışması için gerekli standart başlıkları (host, X-Real-IP vb.) ekler.
* proxy_pass http://unix:/home/ornekkullanici/myflaskapp/myflaskapp.sock: Gelen istekleri Gunicorn’un dinlediği Unix soketine yönlendirir.
* location /static: Eğer Flask uygulamanız statik dosyalar (CSS, JS, resimler) sunuyorsa, bu blok Nginx’in bu dosyaları doğrudan sunmasını sağlar. Bu, performansı artırır çünkü Nginx statik dosyaları Gunicorn’dan daha verimli sunar. static dizininin uygulamanızın kök dizininde olması gerektiğini unutmayın. Eğer statik dosyanız yoksa bu bloğu eklemeniz gerekmez.
Dosyayı kaydedin ve kapatın. Şimdi bu yapılandırma dosyasını sites-enabled dizinine sembolik bir bağlantı (symlink) oluşturarak etkinleştirelim:
sudo ln -s /etc/nginx/sites-available/myflaskapp /etc/nginx/sites-enabled
Varsayılan Nginx yapılandırma dosyasını devre dışı bırakalım ki bizim yapılandırmamız çakışmasın:
sudo unlink /etc/nginx/sites-enabled/default
Nginx yapılandırmasının sözdizimini kontrol edin:
sudo nginx -t
Eğer test is successful mesajını alırsanız, Nginx’i yeniden başlatın:
sudo systemctl restart nginx
Şimdi tarayıcınızdan alan adınıza veya sunucunuzun IP adresine giderek uygulamanızın çalıştığını doğrulayabilirsiniz. Flask uygulamanızın Nginx üzerinden yayınlandığını görmelisiniz.
Adım 5: Let’s Encrypt ile SSL/TLS Kurulumu (İsteğe Bağlı ama Şiddetle Önerilir)
Uygulamanızın güvenliğini artırmak için HTTPS kullanmak önemlidir. Let’s Encrypt, ücretsiz SSL/TLS sertifikaları sağlar ve Certbot aracı ile kolayca kurulabilir.
Certbot’u ve Nginx eklentisini kuralım:
sudo apt install certbot python3-certbot-nginx -y
Şimdi Certbot’u çalıştırarak SSL sertifikası alalım. ornekuygulama.com ve www.ornekuygulama.com yerine kendi alan adlarınızı girin.
sudo certbot --nginx -d ornekuygulama.com -d www.ornekuygulama.com
Certbot size birkaç soru soracaktır:
1. E-posta adresinizi girin.
2. Hizmet şartlarını kabul edin.
3. E-posta adresinizi EFF ile paylaşmak isteyip istemediğinizi belirtin (isteğe bağlı).
4. Nginx yapılandırmanızı otomatik olarak HTTPS’ye yönlendirip yönlendirmeyeceğini sorun (genellikle 2: Redirect seçeneği önerilir).
Başarılı bir kurulumdan sonra, Certbot Nginx yapılandırmanızı otomatik olarak güncelleyecek ve HTTP isteklerini HTTPS’ye yönlendirecektir. Artık tarayıcınızdan https://ornekuygulama.com adresine giderek uygulamanızın güvenli bir bağlantı üzerinden çalıştığını doğrulayabilirsiniz.
Certbot sertifikaları otomatik olarak yenilemek için bir cron işi de kurar. Yenileme mekanizmasının çalıştığını test edebilirsiniz:
sudo certbot renew --dry-run
Eğer herhangi bir hata almazsanız, otomatik yenileme doğru şekilde çalışıyor demektir.
Adım 6: Uygulamayı Yönetme ve Güncelleme
Uygulamanız artık yayında. Peki uygulamayı nasıl yönetecek veya güncelleyeceksiniz?
Gunicorn Servisini Yönetme
* Durum kontrolü: sudo systemctl status myflaskapp
* Başlatma: sudo systemctl start myflaskapp
* Durdurma: sudo systemctl stop myflaskapp
* Yeniden başlatma: sudo systemctl restart myflaskapp
Nginx Servisini Yönetme
* Durum kontrolü: sudo systemctl status nginx
* Başlatma: sudo systemctl start nginx
* Durdurma: sudo systemctl stop nginx
* Yeniden başlatma: sudo systemctl restart nginx
* Yapılandırmayı yeniden yükleme (servisi durdurmadan): sudo systemctl reload nginx
Uygulama Güncelleme
1. Kod değişiklikleri: Uygulamanızın kodunda (wsgi.py veya diğer Python dosyaları) değişiklikler yapın.
2. Bağımlılıkları güncelleme (gerekirse): Eğer requirements.txt dosyanızda değişiklik varsa, sanal ortamı etkinleştirip bağımlılıkları yeniden kurun:
cd ~/myflaskapp
source venv/bin/activate
pip install -r requirements.txt
deactivate
3. Gunicorn’u yeniden başlatma: Değişikliklerin etkili olması için Gunicorn servisini yeniden başlatın:
sudo systemctl restart myflaskapp
Logları Kontrol Etme
Sorun giderme için logları kontrol etmek önemlidir.
* Gunicorn logları: sudo journalctl -u myflaskapp
* Nginx erişim logları: sudo tail -f /var/log/nginx/access.log
* Nginx hata logları: sudo tail -f /var/log/nginx/error.log
Sonuç
Bu kapsamlı rehberde, Flask uygulamalarınızı Ubuntu 18.04 sunucusu üzerinde Gunicorn ve Nginx kullanarak güvenli, performanslı ve ölçeklenebilir bir şekilde nasıl yayınlayacağınızı adım adım öğrendiniz. Flask’ın dahili geliştirme sunucusunun aksine, bu kurulum üretim ortamları için tasarlanmıştır ve uygulamanızın gerçek dünya trafiğiyle başa çıkmasını sağlar.
Özetle, süreç şu adımları içeriyordu:
1. Sunucu Hazırlığı: Ubuntu 18.04’ü güncelledik, gerekli Python araçlarını kurduk ve uygulama için ayrı bir kullanıcı oluşturduk.
2. Flask Uygulaması ve Sanal Ortam: Uygulama dizini oluşturduk, sanal ortamı yapılandırdık ve basit bir Flask uygulaması (wsgi.py) yazdık.
3. Gunicorn Kurulumu: Gunicorn’u kurduk ve Flask uygulamasını bir Unix soketi üzerinden dinlemesi için bir Systemd servisi olarak yapılandırdık.
4. Nginx Kurulumu: Nginx’i kurduk, güvenlik duvarını yapılandırdık ve gelen web isteklerini Gunicorn’a yönlendiren bir sunucu bloğu oluşturduk.
5. SSL/TLS Güvenliği: Let’s Encrypt ve Certbot kullanarak uygulamanıza ücretsiz SSL sertifikası ekledik ve HTTPS’ye yönlendirme sağladık.
6. Yönetim: Uygulamanızı nasıl güncelleyeceğinizi ve servisleri nasıl yöneteceğinizi ele aldık.
Bu kurulum, web uygulamanızın temelini oluşturur. Daha karmaşık uygulamalar için veritabanı entegrasyonu (PostgreSQL, MySQL vb.), arka plan görevleri (Celery), izleme ve sürekli entegrasyon/sürekli teslimat (CI/CD) gibi ek adımlar gerekebilir. Ancak bu makaledeki adımları takip ederek Flask uygulamanızı güvenle ve verimli bir şekilde üretim ortamına taşıyabilirsiniz.