Python Bottle Uygulamalarını Ubuntu 14.04 Üzerine Dağıtma Rehberi
Bu makalede, hafif ve hızlı Python mikro framework’ü Bottle ile geliştirilmiş bir web uygulamasını Ubuntu 14.04 sunucusu üzerinde nasıl dağıtacağınızı adım adım öğreneceksiniz. Ubuntu 14.04, uzun süreli destek (LTS) sunan ve birçok sunucu ortamında hala yaygın olarak kullanılan sağlam bir işletim sistemidir. Bottle’ın basitliği ve Gunicorn gibi bir WSGI sunucusu ile Nginx gibi bir ters proxy’nin gücü bir araya geldiğinde, üretim ortamları için hem performanslı hem de bakımı kolay bir yapılandırma elde edebilirsiniz.
Giriş: Bottle, Ubuntu ve Dağıtımın Temelleri
Bottle, Python için son derece hafif, hızlı ve basit bir web mikro framework’üdür. Tek bir .py dosyasında dağıtılır, harici bağımlılıkları neredeyse hiç yoktur ve bu da onu küçük veya orta ölçekli projeler için ideal bir seçim haline getirir. Özellikle hızlı prototipleme, API geliştirme veya düşük kaynak tüketimli uygulamalar için tercih edilir.
Ubuntu 14.04 (Trusty Tahr), 2014 yılında piyasaya sürülen ve Nisan 2019’a kadar standart destek, Nisan 2022’ye kadar da ESM (Extended Security Maintenance) desteği alan bir LTS sürümüdür. Her ne kadar güncel bir sürüm olmasa da, birçok eski sistemde veya belirli kurumsal ortamlarda hala aktif olarak kullanılmaktadır. Bu makale, özellikle bu eski ancak hala geçerli ortamlar için bir dağıtım stratejisi sunmaktadır.
Bir Python web uygulamasını üretim ortamında çalıştırmak, sadece python app.py komutunu çalıştırmaktan çok daha fazlasını gerektirir. Üretim ortamında uygulamanızın kararlı, güvenli ve performanslı olmasını sağlamak için genellikle şu bileşenlere ihtiyaç duyulur:
* WSGI Sunucusu (Gunicorn, uWSGI vb.): Python web uygulamaları için bir arayüz standardı olan WSGI (Web Server Gateway Interface) sayesinde, uygulamanız ile web sunucusu arasında iletişim kurulur. Bir WSGI sunucusu, uygulamanızı çoklu işlem veya çoklu iş parçacığı modunda çalıştırarak eş zamanlı istekleri yönetir ve uygulamanızın kararlılığını artırır.
* Ters Proxy (Nginx, Apache vb.): Doğrudan gelen istekleri WSGI sunucusuna yönlendiren, statik dosyaları sunan, SSL/TLS sonlandırması yapan, yük dengelemesi sağlayan ve güvenlik katmanı ekleyen bir sunucudur.
* Sistem Servis Yöneticisi (Upstart, Systemd vb.): Uygulamanızın arka planda sürekli çalışmasını, sunucu yeniden başlatıldığında otomatik olarak başlamasını ve olası çökmelerde otomatik olarak yeniden başlatılmasını sağlar. Ubuntu 14.04, Upstart’ı kullanmaktadır.
Bu rehberde, basit bir Bottle uygulamasını Gunicorn ile WSGI sunucusu olarak çalıştıracak ve gelen tüm HTTP isteklerini Nginx üzerinden Gunicorn’a yönlendireceğiz. Uygulamamızın sunucu yeniden başlatmalarında dahi ayakta kalmasını sağlamak için Upstart servis yöneticisinden faydalanacağız.
Ön Gereksinimler ve Ortam Kurulumu
Başlamadan önce, Ubuntu 14.04 yüklü bir sunucuya SSH erişiminizin olması gerekmektedir. Makale boyunca tüm komutları sunucu üzerinde root yetkileriyle (veya sudo kullanarak) çalıştıracağız.
Sistem Güncellemesi ve Temel Paketlerin Kurulumu
Öncelikle sunucunuzdaki paket listesini güncelleyelim ve mevcut paketleri yükseltelim:
sudo apt-get update
sudo apt-get upgrade -y
Ardından, Python geliştirme için gerekli temel araçları ve virtualenv’i kuralım. Ubuntu 14.04 varsayılan olarak Python 2.7 ile gelir. Bu makalede Python 2.7’yi kullanacağız, ancak Python 3 kullanmak isterseniz ek kurulumlar yapmanız gerekebilir.
sudo apt-get install python-pip python-dev build-essential -y
sudo pip install virtualenv
* python-pip: Python paket yöneticisi.
* python-dev: Python başlık dosyalarını ve geliştirme kütüphanelerini içerir, bazı Python paketlerinin derlenmesi için gereklidir.
* build-essential: Derleyici ve diğer geliştirme araçlarını içerir.
* virtualenv: Python projeleri için izole edilmiş sanal ortamlar oluşturmaya yarar, bağımlılık çakışmalarını önler.
Uygulama İçin Kullanıcı Oluşturma (İsteğe Bağlı ama Önerilir)
Güvenlik açısından, web uygulamanızı root kullanıcısı altında çalıştırmak yerine, ona özel bir sistem kullanıcısı altında çalıştırmak en iyi uygulamadır.
sudo adduser --system --no-create-home --group mybottleapp
Bu komut, mybottleapp adında bir kullanıcı ve grup oluşturur. --system sistem kullanıcısı olduğunu, --no-create-home ana dizin oluşturulmamasını sağlar.
Basit Bir Bottle Uygulaması Oluşturma
Şimdi, sunucumuzda dağıtacağımız basit bir Bottle uygulamasını oluşturalım.
Proje Dizini ve Sanal Ortam Oluşturma
Uygulama dosyalarımızı barındıracak bir dizin oluşturalım ve bu dizine geçelim:
sudo mkdir -p /var/www/mybottleapp
sudo chown -R mybottleapp:mybottleapp /var/www/mybottleapp
cd /var/www/mybottleapp
Şimdi, bu dizin içinde bir sanal ortam oluşturalım ve etkinleştirelim:
sudo -u mybottleapp virtualenv venv
sudo -u mybottleapp /var/www/mybottleapp/venv/bin/pip install bottle gunicorn
Burada sudo -u mybottleapp kullanarak mybottleapp kullanıcısı altında komutları çalıştırıyoruz. Bu, sanal ortamın ve içindeki paketlerin doğru kullanıcıya ait olmasını sağlar.
* virtualenv venv: Mevcut dizinde venv adında bir sanal ortam oluşturur.
* /var/www/mybottleapp/venv/bin/pip install bottle gunicorn: Sanal ortamın pip‘ini kullanarak Bottle ve Gunicorn’u kurar.
Bottle Uygulama Dosyası Oluşturma
Şimdi app.py adında basit bir Bottle uygulaması oluşturalım.
sudo -u mybottleapp nano /var/www/mybottleapp/app.py
Aşağıdaki içeriği dosyaya yapıştırın:
import bottle
app = bottle.Bottle()
@app.route('/')
def home():
return ""
@app.route('/hello/')
def hello(name='Dünya'):
return "Merhaba %s!" % name
if __name__ == '__main__':
# Bu kısım sadece geliştirme ortamında test etmek içindir.
# Üretim ortamında Gunicorn gibi bir WSGI sunucusu kullanılacaktır.
app.run(host='0.0.0.0', port=8080, debug=True)
Dosyayı kaydedin ve kapatın (Ctrl+O, Enter, Ctrl+X).
Uygulamayı Yerel Olarak Test Etme
Uygulamamızın düzgün çalıştığından emin olmak için sanal ortam içinde manuel olarak çalıştırabiliriz:
sudo -u mybottleapp /var/www/mybottleapp/venv/bin/python /var/www/mybottleapp/app.py
Eğer her şey yolundaysa, konsolda “Bottle server starting up…” gibi bir çıktı görmelisiniz. Sunucunuzun IP adresini kullanarak (örneğin http://SUNUCU_IP:8080/) tarayıcınızdan uygulamaya erişmeyi deneyin. “Merhaba, Bottle Uygulaması Ubuntu 14.04 Üzerinde!” mesajını görmelisiniz. Testi bitirdikten sonra Ctrl+C ile sunucuyu durdurun.
WSGI Sunucusu Seçimi ve Gunicorn ile Çalıştırma
Daha önce de bahsettiğimiz gibi, app.py dosyasındaki app.run() komutu sadece geliştirme amaçlıdır. Üretim ortamında, eş zamanlı istekleri yönetebilen, daha kararlı ve performanslı bir WSGI sunucusuna ihtiyacımız var. Bu makalede Gunicorn’u (Green Unicorn) kullanacağız. Gunicorn, basitliği ve etkinliği nedeniyle popüler bir seçimdir.
Gunicorn Kurulumu
Gunicorn’u daha önce sanal ortamımıza kurmuştuk:
sudo -u mybottleapp /var/www/mybottleapp/venv/bin/pip install gunicorn
Gunicorn ile Uygulamayı Çalıştırma
Gunicorn’u Bottle uygulamamızla birlikte çalıştırmak için aşağıdaki komutu kullanabiliriz:
sudo -u mybottleapp /var/www/mybottleapp/venv/bin/gunicorn --workers 3 --bind 0.0.0.0:8000 app:app
--workers 3: Gunicorn’un 3 adet worker (işçi) süreci başlatmasını söyler. Bu sayı genellikle (2 CPU_Çekirdek_Sayısı) + 1 formülüyle hesaplanır, ancak uygulamanızın ihtiyaçlarına göre ayarlanmalıdır.
* --bind 0.0.0.0:8000: Gunicorn’un tüm ağ arayüzlerinde 8000 portunu dinlemesini sağlar. Nginx bu porta yönlendirme yapacaktır.
* app:app: Gunicorn’a app.py dosyasındaki app adlı Bottle uygulamasını çalıştırmasını söyler. İlk app dosya adını (uzantısız), ikinci app ise dosya içindeki bottle.Bottle() nesnesinin adını temsil eder.
Bu komutu çalıştırdığınızda Gunicorn başlayacak ve 8000 portunu dinleyecektir. Tarayıcınızdan http://SUNUCU_IP:8000/ adresine giderek uygulamaya doğrudan erişebilirsiniz. Testi bitirdikten sonra Ctrl+C ile Gunicorn’u durdurun.
Upstart ile Gunicorn’u Yönetme
Gunicorn’u manuel olarak çalıştırmak üretim ortamı için uygun değildir. Sunucu yeniden başlatıldığında uygulamanızın otomatik olarak başlamasını ve olası çökmelerde yeniden başlatılmasını sağlamak için bir servis yöneticisi kullanmalıyız. Ubuntu 14.04, Upstart’ı kullanır.
Upstart Yapılandırma Dosyası Oluşturma
mybottleapp.conf adında bir Upstart yapılandırma dosyası oluşturalım:
sudo nano /etc/init/mybottleapp.conf
Aşağıdaki içeriği dosyaya yapıştırın. Açıklamaları dikkatlice okuyun:
# /etc/init/mybottleapp.conf
description "Gunicorn server for my Bottle application"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
respawn limit 10 5
setuid mybottleapp
setgid mybottleapp
chdir /var/www/mybottleapp
exec /var/www/mybottleapp/venv/bin/gunicorn --workers 3 --bind unix:/tmp/mybottleapp.sock app:app
Dosyayı kaydedin ve kapatın.
Açıklamalar:
* description: Servisin kısa bir açıklaması.
* start on runlevel [2345]: Servisin çok kullanıcılı grafiksel olmayan (2), çok kullanıcılı (3), tam çok kullanıcılı (4) ve grafiksel çok kullanıcılı (5) çalışma seviyelerinde başlatılmasını sağlar.
* stop on runlevel [!2345]: Bu çalışma seviyeleri dışında (örneğin tek kullanıcılı mod veya kapanma) servisin durdurulmasını sağlar.
* respawn: Servis çökerse veya beklenmedik bir şekilde durursa otomatik olarak yeniden başlatılmasını sağlar.
* respawn limit 10 5: 5 saniye içinde 10 kez yeniden başlatma denemesi başarısız olursa, Upstart servisi yeniden başlatmayı durdurur.
* setuid mybottleapp: Servisi mybottleapp kullanıcısı altında çalıştırır. Bu, güvenlik için önemlidir.
* setgid mybottleapp: Servisi mybottleapp grubu altında çalıştırır.
* chdir /var/www/mybottleapp: Servis başlatıldığında çalışma dizinini /var/www/mybottleapp olarak ayarlar.
* exec: Çalıştırılacak komutu belirtir. Burada Gunicorn’u sanal ortamımızdaki ikili dosya üzerinden çalıştırıyoruz.
Önemli Not: exec satırında 0.0.0.0:8000 yerine unix:/tmp/mybottleapp.sock kullandık. Bu, Gunicorn’un belirli bir IP ve port yerine bir Unix soketi üzerinden dinlemesini sağlar. Unix soketleri, aynı sunucu üzerindeki işlemler arası iletişim için genellikle TCP/IP portlarından daha hızlı ve güvenlidir. Nginx’i de bu sokete yönlendireceğiz.
Upstart Servisini Yönetme
Şimdi servislerimizi başlatabilir, durdurabilir ve durumunu kontrol edebiliriz:
sudo service mybottleapp start # Servisi başlat
sudo service mybottleapp status # Servisin durumunu kontrol et
sudo service mybottleapp stop # Servisi durdur
sudo service mybottleapp restart # Servisi yeniden başlat
sudo service mybottleapp status komutunu çalıştırdığınızda, servisin “start/running” durumunda olduğunu görmelisiniz.
Nginx Ters Proxy Olarak Kurulumu ve Yapılandırması
Uygulamamız artık Gunicorn tarafından yönetiliyor ve bir Unix soketi üzerinden dinleniyor. Ancak doğrudan bu sokete veya Gunicorn’un dinlediği porta dışarıdan erişim sağlamak istemeyiz. İşte bu noktada Nginx devreye girer. Nginx, gelen HTTP isteklerini karşılayacak, statik dosyaları sunacak ve istekleri Gunicorn’a yönlendirecek bir ters proxy olarak görev yapacaktır.
Nginx Kurulumu
Nginx’i sunucumuza kuralım:
sudo apt-get install nginx -y
Kurulum tamamlandığında Nginx otomatik olarak başlayacaktır. Tarayıcınızdan sunucunuzun IP adresine gittiğinizde Nginx’in varsayılan “Welcome to nginx!” sayfasını görmelisiniz.
Nginx Yapılandırma Dosyası Oluşturma
Şimdi Bottle uygulamamız için bir Nginx yapılandırma dosyası oluşturalım:
sudo nano /etc/nginx/sites-available/mybottleapp
Aşağıdaki içeriği dosyaya yapıştırın. your_domain_or_ip kısmını kendi alan adınız veya sunucunuzun IP adresi ile değiştirin.
# /etc/nginx/sites-available/mybottleapp
server {
listen 80;
server_name your_domain_or_ip; # Alan adınızı veya sunucunuzun IP adresini buraya yazın
# Gunicorn Unix soketine proxy ayarları
location / {
include proxy_params;
proxy_pass http://unix:/tmp/mybottleapp.sock;
}
# Statik dosyalar için ayrı bir konum bloğu (isteğe bağlı)
# Eğer uygulamanız statik dosyalar (CSS, JS, resimler) sunuyorsa
# bu kısmı yapılandırmanız gerekir.
# Örneğin, statik dosyalarınız /var/www/mybottleapp/static dizininde ise:
# location /static/ {
# alias /var/www/mybottleapp/static/;
# }
}
Dosyayı kaydedin ve kapatın.
Açıklamalar:
* listen 80: Nginx’in 80 (HTTP) portunu dinlemesini sağlar.
* server_name: Bu sunucu bloğunun hangi alan adı veya IP adresi için geçerli olduğunu belirtir.
* location /: Gelen tüm istekleri (root yolu ve altındaki her şeyi) yakalar.
* include proxy_params: Nginx’in öntanımlı proxy parametrelerini (örneğin proxy_set_header ayarları gibi) içerir. Bu parametreler, orijinal istemci IP adresi gibi bilgileri Gunicorn’a iletmek için önemlidir.
* proxy_pass http://unix:/tmp/mybottleapp.sock: İstekleri Gunicorn’un dinlediği Unix soketine yönlendirir.
* location /static/: Eğer uygulamanız statik dosyalar sunuyorsa, bu bloğu kullanarak Nginx’in bu dosyaları doğrudan sunmasını sağlayabilirsiniz. Bu, Gunicorn’un statik dosya sunumu yükünden kurtulmasını ve uygulamanızın daha performanslı çalışmasını sağlar. alias yönergesi, URL yolunu dosya sistemindeki gerçek yola eşler.
Nginx Yapılandırmasını Etkinleştirme
Yeni yapılandırma dosyamızı etkinleştirmek için sites-enabled dizinine bir sembolik bağlantı oluşturalım:
sudo ln -s /etc/nginx/sites-available/mybottleapp /etc/nginx/sites-enabled/
Varsayılan Nginx yapılandırmasını devre dışı bırakalım ki bizimkiyle çakışmasın:
sudo rm /etc/nginx/sites-enabled/default
Nginx Yapılandırmasını Test Etme ve Yeniden Başlatma
Yapılandırma dosyamızda herhangi bir sözdizimi hatası olup olmadığını kontrol edelim:
sudo nginx -t
Eğer “test is successful” mesajını görürseniz, her şey yolundadır. Şimdi Nginx’i yeniden başlatalım ki yeni yapılandırmayı yüklesin:
sudo service nginx restart
Artık tarayıcınızdan sunucunuzun IP adresine veya alan adına (eğer bir alan adı yapılandırdıysanız) gittiğinizde, Bottle uygulamanızın Nginx üzerinden çalıştığını görmelisiniz.
Güvenlik İpuçları ve En İyi Uygulamalar
Uygulamanızı dağıttıktan sonra, sunucunuzun ve uygulamanızın güvenliğini sağlamak için bazı ek adımlar atmanız önemlidir.
Güvenlik Duvarı (UFW) Yapılandırması
Ubuntu’da UFW (Uncomplicated Firewall) varsayılan olarak gelir ve kullanımı kolaydır. Yalnızca gerekli portlara izin vererek sunucunuzu koruyun.
sudo ufw allow OpenSSH # SSH erişimine izin ver (port 22)
sudo ufw allow 'Nginx HTTP' # HTTP (port 80) erişimine izin ver
sudo ufw allow 'Nginx HTTPS' # Eğer SSL/TLS kullanacaksanız HTTPS (port 443) erişimine izin verin
sudo ufw enable # Güvenlik duvarını etkinleştir
sudo ufw status # Güvenlik duvarı durumunu kontrol et
SSL/TLS Kurulumu (Let’s Encrypt)
Üretim ortamındaki her web uygulaması HTTPS kullanmalıdır. Let’s Encrypt, ücretsiz SSL/TLS sertifikaları sağlar ve Certbot aracı ile kurulumu oldukça kolaydır. Ubuntu 14.04 için Certbot kurulumu biraz daha eski yöntemlerle yapılabilir, ancak yine de mümkündür.
sudo apt-get install python-certbot-nginx -y # Nginx eklentisi ile Certbot
sudo certbot --nginx -d your_domain_or_ip # Sertifika alma ve Nginx'i yapılandırma
Bu komutlar, domain adınızı doğrulayacak ve Nginx yapılandırmanızı HTTPS’i kullanacak şekilde güncelleyecektir.
Sürekli Güncellemeler
Sunucunuzdaki işletim sistemi ve paketleri düzenli olarak güncel tutmak, bilinen güvenlik açıklarına karşı korunmanın en temel yoludur.
sudo apt-get update && sudo apt-get upgrade -y
Ayrı Kullanıcı Hesabı
Uygulamanızı root dışındaki ayrı bir kullanıcı altında çalıştırmak, bir güvenlik ihlali durumunda potansiyel zararı sınırlar. Bu rehberde mybottleapp kullanıcısını oluşturarak bu adımı atmış olduk.
Hata Yönetimi ve Loglama
Uygulamanızın ve sunucunuzun loglarını düzenli olarak kontrol edin.
* Gunicorn logları: Upstart yapılandırma dosyasındaki exec komutuna --error-logfile ve --access-logfile parametreleri ekleyerek Gunicorn loglarının belirli bir dosyaya yazılmasını sağlayabilirsiniz. Aksi takdirde Upstart loglarında (örneğin /var/log/upstart/mybottleapp.log) bulabilirsiniz.
* Nginx logları: /var/log/nginx/access.log ve /var/log/nginx/error.log dosyalarını kontrol edin.
Ortam Değişkenleri ile Hassas Veriler
Veritabanı şifreleri, API anahtarları gibi hassas bilgileri doğrudan kodunuzda saklamayın. Bunları ortam değişkenleri olarak veya güvenli bir yapılandırma yönetim sistemi aracılığıyla yönetin. Upstart yapılandırmasında env komutu ile ortam değişkenleri tanımlayabilirsiniz.
# /etc/init/mybottleapp.conf içine eklenecek
env DATABASE_URL="postgresql://user:pass@host:port/db"
Sorun Giderme
Dağıtım sırasında karşılaşabileceğiniz bazı yaygın sorunlar ve çözümleri:
* Uygulama Çalışmıyor:
* sudo service mybottleapp status komutuyla Gunicorn servisinin durumunu kontrol edin.
* Gunicorn loglarını kontrol edin. Upstart logları genellikle /var/log/upstart/mybottleapp.log altında bulunur.
* sudo -u mybottleapp /var/www/mybottleapp/venv/bin/gunicorn --workers 3 --bind 0.0.0.0:8000 app:app komutunu manuel olarak çalıştırarak Gunicorn’un hata verip vermediğini kontrol edin.
* Python sanal ortamının doğru etkinleştirildiğinden ve Bottle ile Gunicorn’un yüklü olduğundan emin olun.
* Dosya izinlerini kontrol edin. mybottleapp kullanıcısının /var/www/mybottleapp dizinine ve içindeki dosyalara okuma/yazma erişimi olmalı.
* Nginx Hata Veriyor veya Uygulamaya Yönlendirmiyor:
* sudo nginx -t komutuyla Nginx yapılandırmanızda hata olup olmadığını kontrol edin.
* Nginx hata loglarını kontrol edin: /var/log/nginx/error.log.
* Nginx’in Gunicorn’a doğru Unix soketine veya porta yönlendirdiğinden emin olun (proxy_pass ayarı).
* Gunicorn’un gerçekten dinlediği soket dosyasının (/tmp/mybottleapp.sock) var olup olmadığını kontrol edin (ls -l /tmp/mybottleapp.sock). Eğer yoksa Gunicorn servisi düzgün başlamamış demektir.
* Bağlantı Zaman Aşımı (Connection Timeout):
* Güvenlik duvarınızın (UFW) Nginx’in kullandığı 80 (veya 443) portuna izin verdiğinden emin olun.
* Nginx’in çalıştığından emin olun (sudo service nginx status).
Sonuç
Bu kapsamlı rehberde, Python Bottle mikro framework’ü ile geliştirilmiş bir web uygulamasını Ubuntu 14.04 sunucusu üzerinde dağıtmanın tüm adımlarını ele aldık. Gunicorn’u bir WSGI sunucusu olarak kullanarak uygulamanızın kararlı ve performanslı çalışmasını sağladık. Nginx’i ters proxy olarak yapılandırarak gelen istekleri yönetmesini, statik dosyaları sunmasını ve güvenlik katmanı eklemesini sağladık. Son olarak, Upstart ile Gunicorn servisinin otomatik olarak başlamasını ve yönetilmesini temin ettik.
Bu yapılandırma, küçük ve orta ölçekli Bottle uygulamaları için sağlam ve güvenilir bir dağıtım ortamı sunar. Unutmayın ki Ubuntu 14.04 artık eski bir sürüm olsa da, bu makaledeki prensipler ve yaklaşımlar daha yeni Ubuntu sürümleri (Systemd ile bazı farklılıklar olacaktır) veya diğer Linux dağıtımları için de temel teşkil edebilir.
İleri adımlar olarak, uygulamanıza bir veritabanı entegre etmeyi (örneğin PostgreSQL veya MySQL), daha karmaşık Bottle özelliklerini keşfetmeyi, CI/CD (Sürekli Entegrasyon/Sürekli Dağıtım) boru hatları kurmayı veya izleme ve uyarı sistemleri eklemeyi düşünebilirsiniz. Her zaman güvenlik en iyi uygulamalarını takip edin ve sunucunuzu güncel tutun.
