Bu derste Flask uygulamalarını nasıl Nginx ve Gunicorn kullanarak Ubuntu 16.04 üzerinde yayınlayabileceğinizi anlatıyoruz.
Flask uygulamalarını yayınlamak Vercel gibi sunucu uygulamalar sayesinde kolaylaştı. Ancak eğer kendi sunucunuzu kurmanız gerekiyorsa okumaya devam edin.
Bu derste bir Flask uygulamasını nasıl yayınlayabileceğinizi anlatıyoruz.
Flask kullanarak basit bir Python uygulaması oluşturacağız. Oluşturduğumuz bu uygulamayı Gunicorn sunucusu ile çalıştıracağız. Sonraki aşamada ise Nginx'i kullanıcı arayüzünü kontrol eden vekil sunucu olarak ayarlayacağız.
Bir Flask uygulamasını Nginx ve Gunicorn kullanarak Ubuntu 16.04 üzerinde yayınlamak istiyoruz.
İlk önce ihtiyaç duyacağımız bileşenlerin yazılım depolarından kurulumunu yapacağız. Gerekli python paketlerini kurup, yönetmek için pip paket yöneticisini kuracağız. Ayrıca bazı Gunicorn bileşenleri tarafından ihtiyaç duyulan python geliştirme kütüphanelerini kuracağız. Tüm bunlarla beraber Nginx'i de kuracağız.
Yerel paket deponuzu güncelleyin ve paketleri kurun. Kullandığınız python sürümüne göre şu paketleri kurabilirsiniz.
Eğer Python2 kullanıyorsunuz şu komutları girin :
$ sudo apt-get update
$ sudo apt-get install python-pip python-dev nginx
Eğer Python3 kullanıyorsunuz şu komutları girin :
$ sudo apt-get update
$ sudo apt-get install python3-pip python3-dev nginx
Şimdi bir tane Python çalışma ortamı oluşturacağız. Böylelikle Flask uygulamamızı sistemde bulunan diğer Python kütüklerinden bağımsız bir şekilde çalıştırabileceğiz.
İlkönce pip kullanarak virtualenv kurulumu yapalım.
Eğer Python2 kullanıyorsanız :
$ sudo pip install virtualenv
Eğer Python3 kullanıyorsanız şu komutu veriniz :
$ sudo pip3 install virtualenv
Şimdi uygulamamız için bir dizin oluşturabiliriz. Dizini oluşturduktan sonra içine girelim :
$ mkdir ~/uygulamam
$ cd ~/uygulamam
Bir çalıştırma ortamı oluşturmak için aşağıdaki komutu verelim. Burada çalışma ortamının da Python3 kullanması için -p python3 seçeneğini kullandık. Eğer Python2 kullanıyorsanız bu seçeneği kullanmayın.
$ virtualenv -p python3 venv
Daha sonra oluşturduğumuz çalışma ortamını etkin hale getirelim.
$ . venv/bin/activate
Şimdi komut satırı çalışma ortamının etkin hale geldiğini gösterecek şekilde değişmiş olmalı : (venv) kullanıcı@sunucu:~/uygulamam$
Artık çalışma ortamında olduğumuza göre Flask ve Gunicorn'u kurup uygulamamızı tasarlamaya başlayabiliriz.
Flask ve Gunicorn'u kurmak için pip'in çalışma ortamında etkin olan yerel sürümünü kullanabiliriz. Kurulum için aşağıdaki komutları veriniz :
Kullandığınız Python sürümünden bağımsız olarak çalışma ortamı etkin iken her zaman pip komutunu kullanmalısınız (pip3 değil)
(venv) $ pip install gunicorn flask
Artık Flask kurulumunu yaptığımıza göre basit bir uygulama oluşturabiliriz. Flask bir mini internet uygulaması geliştirme çatısıdır. Diğer internet uygulaması geliştirme kütüphanelerinden farklı olarak gerekli tüm bileşenlerle gelmez. Bunun yerine ihtiyaç duyduğunuz birimi ekler ve kullanırsınız.
Gerçekte yazacağınız uygulama daha karmaşık olabilir. Ama biz öğrenme amacıyla Flask uygulamasını tek bir kütükte oluşturacağız ve adına uygulamam.py diyeceğiz.
(venv) $ nano ~/uygulamam/uygulamam.py
Bu kütüğün içine uygulamamızını kodunu gireceğiz. Basitçe Flask'ı programa import ile ekleyip bir tane Flask nesnesi oluşturmamız gerek :
from flask import Flask
app = Flask(__name__)
@app.route("/")
def merhaba():
return "<h1 style='color:blue'>Merhaba Flask!</h1>"
if __name__ == "__main__":
app.run(host='0.0.0.0')
Bu kodla alan adımıza erişim sağlandığında gösterilecek içeriği belirtiyoruz. İşiniz bitince dosyayı kaydedin ve kapatın.
Nano metin editörü ile Ctrl - Shift - o tuşlarına basarak kütüğü kaydedebilirsiniz. Çıkmak için ise Ctrl-Shift-x tuşlarına birlikte basınız.
Eğer UFW güvenlik duvarı kuruluysa 5000 numaralı kapıya erişim izni vermemiz gerekiyor.
5000 numaralı kapıyı şu komutu vererek açınız :
(venv) $ sudo ufw allow 5000
Şimdi Flask uygulamanızı şu komutu vererek test edebilirsiniz :
(venv) $ python uygulamam.py
Sunucunuzun alan adını ya da IP numarasını sonuna :5000 koyarak tarayıcınız ile ziyaret edin.
http://sunucunun_alan_adı_ya_da_IP_numarası:5000
Sunucunuzun yerel IP adresini öğrenmek için şu komutu verebilirsiniz :
ip route get 8.8.8.8 | awk '{print $NF; exit}'
Bu adresi ziyaret ettiğinizde şöyle bir ekran görüyor olmalısınız :
İşiniz bittiğinde terminal penceresinde bir kaç kere CTRL-C tuşlarına basarak Flask geliştirme sunucusunu sonlandırın.
WSGI ya da uzun ismiyle "Web Server Gateway Interface" "Ağ Sunucusu Köprü Arayüzü" anlamına geliyor.
Ağ Sunucusu Köprü Arayüzü'nü uygulamamızla sunucu arasında bağlantı sağlayan bir köprü olarak düşünebilirsiniz.
Geleneksel web sunucusu Python uygulamasını nasıl çalıştıracağını bilemez. Bu yüzden Python web uygulamaları çalıştırmak için bir WSGI sunucusuna ihtiyaç duyuyoruz. Gunicorn da sıklıkla Python internet uygulamalarını çalıştırmak için kullanılan bir WSGI sunucusudur. Bizim Python uygulamamız WSGI sunucusu ile iletişim kurar. WSGI sunucusu web sunucusuyla, web sunucusu ise tarayıcı ile haberleşir.
Sonra uygulamamızın giriş noktası olarak göreve yapacak bir kütük oluşturacağız. Bu kütük Gunicorn sunucusuna uygulamamızla nasıl etkileşim kurabileceğini haber verecektir.
Bu dosyaya wsgi.py ismi veriyoruz.
(venv) $ nano ~/uygulamam/wsgi.py
Bu kütük oldukça basit. Tek yaptığımız oluşturduğumuz uygulamadan Flask örneğini programımıza eklemek ve çalıştırmak.
from uygulamam import app
if __name__ == "__main__":
app.run()
Kütükle işiniz bitince kaydedin ve kapatın.
Devam etmeden önce Gunicorn'un istedğimiz gibi çalıştığını ve uygulamayı sunabildiğini teyit etmeliyiz.
Tek yapmamız gereken uygulamanın giriş noktası olarak görev yapan kütüğü çalıştırmak. Bunu yapmak için kütük ismi (sonunda .py olmadan) iki nokta ve çağrılabilir Flask uygulamasının ismi şeklinde bir yazım biçimi kullanıyoruz. Bizim örneğimizde bu wsgi:app olacak.
Ayrıca uygulamayı çalıştıracağımız aygıtı ve kapıyı belirtiyoruz. Burada 0.0.0.0 kullanarak sistemde bulunan tüm ağ aygıtlarına uygulamayı bağla demiş oluyoruz. Aksi halde tek tek IP numaralarını belirtmemiz gerekebilirdi.
(venv) $ cd ~/uygulamam
(venv) $ gunicorn --bind 0.0.0.0:5000 wsgi:app
Tekrardan tarayıcınızla sunucuzun alan adını ya da IP numarasını sonuna :5000 koyarak ziyaret edin.
http://sunucunun_alan_adı_ya_da_IP_numarası:5000
Tekrardan uygulamınızın çıktısını görebiliyor olmanız lazım :
Uygulamanın doğru çalıştığından emin olduktan sonra terminalde CTRL-C tuşlarına basın.
Çalışma ortamımızla işimiz şimdilik bitti. Bu yüzden devre dışı bırakabiliriz.
Bundan sonra yazdığımız Python komutları tekrar sistem genelindeki Python'u kullanacak.
Bir sonraki aşamada systemd dizininde bir hizmet birimi oluşturalım. Bir hizmet birimi oluşturmamız Ubuntu'nun açılış sisteminin sunucu her başlatıldığında otomatik olarak Gunicorn'u ve Flask uygulamamızı başlatmasını sağlayacak.
Başlangıç olarak /etc/systemd/system dizininde sonu .service ile biten bir hizmet dosyası oluşturun.
$ sudo nano /etc/systemd/system/uygulamam.service
Kütüğün içinde bağımlılıklar ve üst veriyi belirtiğimiz [Unit] bölümü ile başlıyoruz. Buraya hizmetimizin bir açıklamasını koyacağız. Açılış sistemine hizmeti ağ hizmeti başladıktan sonra başlatmasını söyleyeceğiz.
[Unit]
Description=Uygulamamı sunan Gunicorn sunucusu
After=network.target
Daha sonra [Service] bölümünü açıyoruz. Burada hizmete erişim izni olan kullanıcı ve grubu belirliyoruz. Grup sahipliğini www-data grubuna veriyoruz. Böylece Nginx Gunicorn iş parçacığı ile kolaylıkla haberleşebilecek. Daha sonra çalışma dizinini detaylarıyla gösterecek ve PATH ortam değişkenini ayarlayacağız. Böylelikle açılış sistemi çalıştırılabilir dosyaların nerede olduğunu bilecek. Daha sonra hizmeti çalıştırmak için gereken komutu belirtiyoruz. systemd dizininde olduğumuz için çalışma ortamımızda bulunan Gunicorn'un çalıştırılabilir dosyasının uzun adresini belirtmek gerekiyor.
Gunicorn'dan 3 tane iş parçacığı oluşturmasını istiyoruz. (İhtiyaca göre bunu ayarlayın) Ayrıca çalışma dizinimizde uygulamam.sock
isminde bir Unix soketi oluşturmasını ve buna bağlanmasını istiyoruz. umask değeri olarak 007 veriyoruz. Böylelikle soket kütüğü sahibi ve grubu erişim sağlayacak, diğerleri erişemeyecek şekilde oluşturulacak. Son olarak uygulamanın giriş noktası olarak görev yapan kütüğü ve içindeki uygulama adını belirtiyoruz.
[Unit]
Description=Uygulamamı sunan Gunicorn sunucusu
After=network.target
[Service]
User=erdem
Group=www-data
WorkingDirectory=/home/erdem/uygulamam
Environment="PATH=/home/erdem/uygulamam/venv/bin"
ExecStart=/home/erdem/uygulamam/ven/bin/gunicorn --workers 3 --bind unix:uygulamam.sock -m 007 wsgi:app
Son olarak [Install] bölümünü ekliyoruz. Bu bölüm hizmet etkinleştirildiğinde ya da devre dışı bırakıldığında davranışını belirliyor. Hizmetin etkinleştirilmesi derken sistem açılışında otomatik olarak başlatılmasını kasdediyorum.
[Unit]
Description=Uygulamamı sunan Gunicorn sunucusu
After=network.target
[Service]
User=erdem
Group=www-data
WorkingDirectory=/home/erdem/uygulamam
Environment="PATH=/home/erdem/uygulamam/venv/bin"
ExecStart=/home/erdem/uygulamam/venv/bin/gunicorn --workers 3 --bind unix:uygulamam.sock -m 007 wsgi:app
[Install]
WantedBy=multi-user.target
Bununla beraber hizmet dosyamız tamamlandı. Kaydedelim ve kapatalım.
Şimdi oluşturduğumuz Gunicorn hizmetini başlatabilir ve açılışta etkin hale gelecek şekilde ayarlayabiliriz.
$ sudo systemctl start uygulamam
$ sudo systemctl enable uygulamam
Bu aşamada hizmetin doğru başlayıp başlatılmadığını aşağıdaki komutla kontrol etmenizi tavsiye ederim.
$ sudo systemctl status uygulamam
Eğer hizmetin durumunu yeşil olarak görüyorsanız bir sonraki Nginx bölümüne devam edin. Eğer kırmızı görüyorsanız şu adımları uygulamanızı tavsiye ederim.Oluşturduğunuz hizmet kütüğünde kullanıcı ismini, PATH ortam değişkenini kendi ortamınıza göre uyarladığınızdan emin olun.
$ cd ~/uygulamam/
$ . venv/bin/activate
Bu kısma hizmet dosyanızdaki Gunicorn sunusunu başlattığınız komutu girin :
(venv) $ /home/erdem/uygulamam/venv/bin/gunicorn --workers 3 --bind unix:uygulamam.sock -m 007 wsgi:app
Eğer sorunsuz olarak başladıysa hizmet dosyasında çalışma ortamı, PATH ortam değişkeni ve kullanıcı ismini doğru olarak girdiğinizden emin olun. Gerekli düzeltmeleri yaptıktan sonra tekrar hizmet dosyasını yükleyin:
$ sudo systemctl daemon-reload
Hizmet eğer doğru başladıysa yukarıda anlatıldığı gibi hizmeti başlatın ve açılışta etkinleştirin.
Bu bölüme geçmeden önce sunucu bilgisayarı bir kere tekrar başlatınız. ~/uygulamam dizininde uygulamam.sock isimli bir soket dosyasının oluştuğunu teyit ediniz.
Gunicorn sunucumuz uygulama dizininde oluşturduğumuz soket dosyası ile gelen istekleri bekliyor ve çalışıyor olmalı. Nginx'i ağdan gelen istekleri bu soket dosyasına aktaracak şekilde ufak ayarlamalar yapmamız gerekir.
İlkönce Nginx'in sites-available dizininde yeni bir sunucu yapılandırma dosyası oluşturarak işe başlayacağız. Dersin diğer bölümleriyle uyumlu olması açısından basitçe uygulamam ismi vereceğiz.
$ sudo nano /etc/nginx/sites-available/uygulamam
Sunucu bloğunu açalım ve Nginx'e 80 numaralı kapıyı dinlemesini söyleyelim. Ayrıca suncumuzun alan adı ya da IP numarasına gelen tüm istekler için bu bloğu kullanmasını isteyelim.
server {
listen 80;
server_name sunucunun_alan_adı_ya_da_IP_adresi;
}
Diğer yapmamız gereken şey bir konum bloğu eklemek. Bu bloğun içine genel vekil sunucu ayarlarını içeren proxy_params kütüğünü ekliyoruz. Daha sonra proxy_pass komutuyla gelen istekleri tanımladığımız sokete geçeceğiz.
server {
listen 80;
server_name sunucunun_alan_adı_ya_da_IP_adresi;
location / {
include proxy_params;
proxy_pass http://unix://home/erdem/uygulamam/uygulamam.sock;
}
}
Uygulamayı sunmak için yapacağımız tüm işlemler bu kadardı. İşiniz bittiğinde dosyayı kaydedip kapatın.
Oluşturduğumuz sunucu bloğunu etkinleştirmek için varsayılan siteyi siliyoruz.
$ sudo rm /etc/nginx/sites-enabled/default
Daha sonra oluşturduğumuz sunucu bloğunu sites-enabled dizinine bağlıyoruz.
$ sudo ln -s /etc/nginx/sites-available/uygulamam /etc/nginx/sites-enabled/default
Bu dosyayı yerine yerleştirdikten sonra yazım hatalarını şu komutla test edebiliriz :
$ sudo nginx -t
Eğer hiç hata vermezse Ngnix'i yeni ayarlarla başlatabiliriz.
$ sudo systemctl restart nginx
Yapmamız gereken tek şey kaldı o da tekrar güvenlik duvarında ufak ayarlamalar yapmak. Artık 5000 numaralı kapıya erişime ihtiyaç duymuyoruz bu nedenle bu kuralı kaldırabiliriz. Daha sonra Nginx sunucuya izin verecek şekilde bir düzenleme yapabiliriz.
$ sudo ufw delete allow 5000
$ sudo ufw allow 'Nginx Full'
Şimdi sunucunuzun alan adına ya da IP numarasını tarayıcınızda yazın.
http://sunucunun_alan_adı_ya_da_IP_numarası:5000
Uygulamanın çıktısını görüyor olmalısınız :
Eğer statik ip adresiniz varsa gerekli port yönlendirmelerini yaparak sunucuyu internete açabilirsiniz.
Burada 80 numaralı HTTP portu (kapısı) için yönlendirme yaptık. Eğer SSH kullanıyorsanız 443 numaralı kapı için de yönlendirme yapmanız gerekebilir.
Sunucunun harici IP adresini öğrenmek için curl programı kurulu ise şu komutu verebilirsiniz.
$ curl ipinfo.io/ip
Sunucunuzun dışarıdan nasıl göründüğünü test etmek isterseniz sayfanın ekran görüntüsünü alan bu hizmeti kullanabilirsiniz. Eğer isterseniz örüt ağ üzerinde kullanılabilen bir tarayıcı da kullanabilirsiniz.
Bu derste Python çalıştırma ortamının içinde basit bir Flask uygulaması oluşturduk. Sonra uygulamamızın giriş noktası olarak görev yapacak bir WSGI kütüğü oluşturduk. Böylelikle WSGI özellikli bir sunucunun bağlanabileceği bir giriş noktası oluşturduk. Daha sonra bu işlevselliği sağlamak için Gunicorn sunucusunu yapılandırdık. Daha sonra uygulama sunucusunu açılışta otomatik olarak başlatmak için bir hizmet oluşturduk. Ağ istemci trafiğini uygulama sunucusuna geçen, harici istekleri aktaran bir Nginx sunucu bloğu oluşturduk.
Flask uygulamalarınıza yapı ve tasarım konusunda çok kısıtlayıcı olmadan uygulamalarınıza işlevsellik kazandırmak için oluşturulmuş basit ama son derece esnek bir çatıdır. Bu kılavuzda açıklanan temel adımları kendi tasarladığınız Flask uygulamalarını sunmak için kullanabilirsiniz.
Yorumlar