FastAPI Uygulamalarını Gunicorn ve Nginx ile Ubuntu 24.04 Üzerine Dağıtma Rehberi
Modern web uygulamaları geliştirirken performans, güvenlik ve ölçeklenebilirlik, projenin başarısı için kritik öneme sahiptir. Özellikle Python ekosisteminde, hızlı ve verimli API’ler oluşturmak için FastAPI gibi framework’ler (yazılım çerçeveleri) öne çıkarken, bu uygulamaları üretim ortamında (production environment) güvenli ve yüksek performanslı bir şekilde çalıştırmak, doğru mimari seçimleriyle mümkündür. Bu makalede, FastAPI uygulamanızı Ubuntu 24.04 işletim sistemi üzerinde Gunicorn uygulama sunucusu ve Nginx ters proxy (reverse proxy) kullanarak nasıl dağıtabileceğinizi (deploy) adım adım inceleyeceğiz. Bu rehber sayesinde, uygulamanızın sadece çalışmasını sağlamakla kalmayacak, aynı zamanda onu gerçek dünya senaryolarına uygun, sağlam ve yönetilebilir bir yapıya kavuşturacaksınız.
Neden FastAPI, Gunicorn ve Nginx Üçlüsü Bu Kadar Önemli?
Bir web uygulamasını başarılı bir şekilde dağıtmak, sadece kodu bir sunucuya kopyalamaktan çok daha fazlasını gerektirir. Performans, güvenlik ve yönetilebilirlik gibi unsurlar, uygulamanızın kullanıcı deneyimini ve genel operasyonel verimliliğini doğrudan etkiler. Bu bağlamda, FastAPI, Gunicorn ve Nginx kombinasyonu, modern Python web servisleri için altın standart olarak kabul edilen güçlü bir üçlü oluşturur. Her bir bileşenin kendine özgü bir rolü vardır ve birlikte çalışarak kusursuz bir dağıtım mimarisi sunarlar.
FastAPI, Python tabanlı, yüksek performanslı bir web framework’üdür. Özellikle asenkron (asynchronous) işlemleri desteklemesi, otomatik etkileşimli API dokümantasyonu (Swagger UI ve ReDoc) sağlaması ve Pydantic sayesinde veri doğrulama (data validation) yetenekleriyle geliştiriciler arasında hızla popülerlik kazanmıştır. FastAPI, hızlı geliştirme süreçleri ve güçlü performans vaat ederken, tek başına bir web sunucusu değildir; geliştirme sırasında kullanılan Uvicorn gibi bir ASGI (Asynchronous Server Gateway Interface) sunucusu ile çalışır. Ancak Uvicorn, genellikle tek bir işlem (process) üzerinde çalıştığı için üretim ortamındaki yüksek trafik ve eş zamanlı bağlantıları yönetme konusunda sınırlı kalabilir. İşte tam bu noktada Gunicorn devreye girer.
Gunicorn (Green Unicorn), bir WSGI (Web Server Gateway Interface) ve ASGI uyumlu HTTP sunucusudur. Python web uygulamalarını üretim ortamında çalıştırmak için tasarlanmıştır. Gunicorn, birden fazla worker (işçi) süreci oluşturarak gelen istekleri bu süreçlere dağıtır. Bu sayede, uygulamanızın eş zamanlı bağlantıları daha verimli bir şekilde yönetmesini ve daha yüksek bir işlem hacmi (throughput) elde etmesini sağlar. Gunicorn, uygulamanızın kararlılığını artırır ve kaynak kullanımını optimize eder. Gunicorn’un asıl görevi, FastAPI uygulamanızın kodunu çalıştırmak ve gelen HTTP isteklerini bu koda iletmektir. Ancak, Gunicorn doğrudan internetten gelen isteklere maruz kalmamalıdır. Bunun yerine, bir ters proxy sunucusu tarafından korunmalı ve yönetilmelidir.
Nginx ise, yüksek performanslı, açık kaynaklı bir web sunucusu, ters proxy ve yük dengeleyicidir (load balancer). Nginx’in temel görevi, istemcilerden gelen tüm HTTP isteklerini karşılamak, bu istekleri uygun Gunicorn worker’larına yönlendirmek ve Gunicorn’dan gelen yanıtları istemcilere geri göndermektir. Nginx, statik dosyaları (resimler, CSS, JavaScript) doğrudan sunma konusunda son derece etkilidir ve bu, uygulamanızın genel performansını önemli ölçüde artırır. Ayrıca, Nginx, SSL/TLS şifrelemesini (encryption) yönetmek, güvenlik duvarı (firewall) görevi görmek, istekleri önbelleğe almak (caching) ve birden fazla uygulama sunucusu arasında yük dengeleme yapmak gibi kritik görevleri üstlenir. Bu sayede, Gunicorn’un sadece uygulama mantığını çalıştırmaya odaklanmasını sağlarken, Nginx trafik yönetimi ve güvenlik gibi ağır yükleri üstlenir. Bu mimari, uygulamanızın hem hızlı hem de güvenli olmasını garanti eder. Örneğin, bir e-ticaret sitesinde, Nginx binlerce eş zamanlı bağlantıyı yönetirken, Gunicorn sadece sepet ve ödeme işlemlerini yürüten FastAPI kodunu çalıştırır. Nginx’in statik dosya sunma yeteneği sayesinde, ürün resimleri ve stil dosyaları hızla yüklenir, bu da kullanıcı deneyimini iyileştirir. Özetle, FastAPI uygulamanızın kalbini oluştururken, Gunicorn bu kalbin verimli bir şekilde atmasını sağlar ve Nginx ise bu kalbi dış dünyadan koruyan ve trafiği düzenleyen bir kalkan görevi görür.
Ubuntu 24.04 Üzerinde Temel Ortam Kurulumu Nasıl Yapılır?
FastAPI uygulamanızı dağıtmadan önce, Ubuntu 24.04 sunucunuzu gerekli araçlarla donatmanız gerekmektedir. Bu adımlar, projeniz için temiz ve güvenli bir çalışma ortamı oluşturmanın ilk basamaklarıdır. İlk olarak, sistem paketlerini güncelleyerek başlayalım. Bu, mevcut paketlerin en son sürümlerine sahip olmanızı sağlar ve olası güvenlik açıklarını kapatır. Terminalinizi açın ve aşağıdaki komutları çalıştırın:
sudo apt update
sudo apt upgrade -y
Sisteminiz güncellendikten sonra, Python’ı ve sanal ortam (virtual environment) oluşturmak için gerekli araçları kurmanız gerekiyor. Ubuntu 24.04 genellikle Python 3 ile birlikte gelir, ancak python3-venv paketini kurmak, projeniz için izole bir sanal ortam oluşturmanıza olanak tanır. Sanal ortamlar, farklı projeler için farklı bağımlılık setlerini (dependency sets) yönetmek için kritik öneme sahiptir, böylece bağımlılık çakışmalarını önlersiniz.
sudo apt install python3-pip python3-venv -y
Şimdi projeniz için bir dizin (directory) oluşturalım ve bu dizine geçelim. Bu dizin, FastAPI uygulamanızın kodunu ve sanal ortamını barındıracak ana yer olacaktır. Örneğin, /var/www/myfastapiapp adında bir dizin oluşturabiliriz. Bu dizini, web sunucularının genellikle uygulama dosyalarını barındırdığı /var/www altında konumlandırmak standart bir yaklaşımdır.
sudo mkdir -p /var/www/myfastapiapp
cd /var/www/myfastapiapp
Dizinin sahipliğini mevcut kullanıcınıza atamak, dosyalar üzerinde root yetkisi olmadan çalışmanıza olanak tanır. Bu, güvenlik açısından önemlidir ve gereksiz yetki kullanımını engeller. your_username kısmını kendi kullanıcı adınızla değiştirmeyi unutmayın.
sudo chown -R your_username:your_username /var/www/myfastapiapp
Şimdi, projeniz için bir sanal ortam oluşturalım ve bu ortamı etkinleştirelim. Sanal ortamı etkinleştirdiğinizde, terminal oturumunuzda kurduğunuz tüm Python paketleri yalnızca bu ortama özgü olacaktır.
python3 -m venv venv
source venv/bin/activate
Sanal ortam etkinleştirildikten sonra, terminal komut isteminizin başında (venv) gibi bir ibare göreceksiniz. Bu, sanal ortamın başarıyla etkinleştirildiğini gösterir. Son olarak, FastAPI ve Uvicorn’u sanal ortamınıza kuralım. Uvicorn, FastAPI uygulamanızı geliştirme sırasında test etmek için kullanılan bir ASGI sunucusudur ve Gunicorn ile entegrasyon için de gereklidir.
pip install fastapi uvicorn gunicorn python-multipart
python-multipart paketini eklememiz, FastAPI’nin form verileri ve dosya yüklemeleri gibi multipart/form-data ile çalışabilmesini sağlar, bu da birçok modern web uygulaması için standart bir gerekliliktir. Bu adımları tamamladığınızda, FastAPI uygulamanızı geliştirmeye ve dağıtmaya hazır bir temel ortama sahip olacaksınız. Bu temel kurulum, uygulamanızın bağımlılıklarını izole etmenizi, güvenlik güncellemelerini takip etmenizi ve sisteminizde tutarlı bir geliştirme ve dağıtım süreci sürdürmenizi sağlar.
Basit Bir FastAPI Uygulaması Nasıl Oluşturulur ve Test Edilir?
Şimdi sıra, dağıtımını yapacağımız basit bir FastAPI uygulaması oluşturmaya geldi. Bu örnek uygulama, bir “Merhaba Dünya” mesajı döndürecek ve temel bir API işlevselliğini sergileyecektir. /var/www/myfastapiapp dizini içinde main.py adında bir dosya oluşturalım ve aşağıdaki kodu içine yazalım. Bu dosya, FastAPI uygulamanızın ana giriş noktası (entry point) olacaktır.
# /var/www/myfastapiapp/main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"message": "Merhaba, FastAPI!"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
Bu kod, iki farklı endpoint (uç nokta) tanımlar:
* /: Kök dizine yapılan GET isteğine “Merhaba, FastAPI!” mesajı ile yanıt verir.
* /items/{item_id}: Belirli bir item_id ile yapılan GET isteğine, bu ID’yi ve isteğe bağlı bir q parametresini içeren bir JSON yanıtı verir. Bu, FastAPI’nin yol parametreleri (path parameters) ve sorgu parametreleri (query parameters) ile nasıl çalıştığını gösterir.
Uygulamanızı geliştirdiğinizde, genellikle yerel makinenizde veya sunucunuzda Uvicorn ile test etmek istersiniz. Sanal ortamınız hala etkin durumdayken (eğer değilse, source venv/bin/activate komutunu tekrar çalıştırın), uygulamayı Uvicorn ile başlatın:
uvicorn main:app --host 0.0.0.0 --port 8000
Bu komut, Uvicorn’u main.py dosyasındaki app objesini kullanarak uygulamayı başlatmaya yönlendirir. --host 0.0.0.0 parametresi, uygulamanın tüm ağ arayüzlerinden (network interfaces) erişilebilir olmasını sağlar, bu da sunucunuzun IP adresi üzerinden veya localhost üzerinden erişilebileceği anlamına gelir. --port 8000 ise uygulamanın 8000 numaralı portta dinleyeceğini belirtir. Tarayıcınızdan veya bir HTTP istemcisi (örneğin Postman veya curl) kullanarak sunucunuzun IP adresini ve 8000 portunu kullanarak uygulamanıza erişebilirsiniz:
* http://YOUR_SERVER_IP:8000/
* http://YOUR_SERVER_IP:8000/items/5?q=example
* http://YOUR_SERVER_IP:8000/docs (FastAPI’nin otomatik API dokümantasyonu)
Uygulamanızın doğru çalıştığını doğruladıktan sonra, Uvicorn sunucusunu durdurmak için terminalde Ctrl+C tuş kombinasyonuna basabilirsiniz. Bu basit test, uygulamanızın temel işlevselliğinin beklendiği gibi çalıştığından emin olmanızı sağlar. Üretim ortamında Uvicorn yerine Gunicorn kullanacağımız için bu adım sadece geliştirme ve test amaçlıdır.
Gunicorn ile FastAPI Uygulamasını Çalıştırma ve Yönetme
FastAPI uygulamanızı üretim ortamında çalıştırmak için Gunicorn’ı kullanacağız. Gunicorn, birden fazla worker (işçi) süreci oluşturarak uygulamanızın eş zamanlı istekleri daha verimli bir şekilde işlemesini sağlar. İlk olarak, Gunicorn’ı basit bir komutla nasıl çalıştıracağımıza bakalım. Sanal ortamınız etkin durumdayken, aşağıdaki komutu kullanarak uygulamanızı Gunicorn ile başlatabilirsiniz:
gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
Bu komutun bileşenlerini inceleyelim:
* main:app: Gunicorn’a main.py dosyasındaki app objesini çalıştırmasını söyler.
* --workers 4: Uygulamanız için 4 adet worker süreci oluşturur. İdeal worker sayısı genellikle (2 * CPU_çekirdek_sayısı) + 1 formülüyle hesaplanır, ancak bu, uygulamanızın CPU yoğunluğuna ve bellek kullanımına bağlı olarak değişebilir. Başlangıç için 2-4 worker iyi bir seçimdir.
* --worker-class uvicorn.workers.UvicornWorker: Gunicorn’a ASGI uyumlu bir uygulama olan FastAPI’yi çalıştırmak için Uvicorn worker sınıfını kullanmasını söyler. Bu, Gunicorn’un asenkron FastAPI uygulamanızla düzgün bir şekilde iletişim kurmasını sağlar.
* --bind 0.0.0.0:8000: Gunicorn’un 8000 numaralı portta ve tüm ağ arayüzlerinde dinlemesini sağlar.
Bu komutla Gunicorn, FastAPI uygulamanızı başlatacak ve gelen istekleri worker süreçlerine dağıtmaya başlayacaktır. Ancak, bu komutu manuel olarak çalıştırmak ve terminali açık tutmak üretim ortamı için pratik değildir. Uygulamanızın sunucu yeniden başlatıldığında otomatik olarak başlamasını ve arka planda sürekli çalışmasını sağlamak için systemd servisi kullanmamız gerekir.
systemd, Linux sistemlerinde servisleri yönetmek için kullanılan bir sistem ve servis yöneticisidir. Uygulamanız için bir systemd servis dosyası oluşturarak Gunicorn’ın otomatik olarak başlatılmasını, durdurulmasını ve yeniden başlatılmasını sağlayabiliriz.
Öncelikle, systemd servis dosyamızı oluşturalım. /etc/systemd/system/ dizini altında myfastapiapp.service adında bir dosya oluşturun:
sudo nano /etc/systemd/system/myfastapiapp.service
Dosyanın içine aşağıdaki içeriği yapıştırın:
[Unit]
Description=Gunicorn instance to serve myfastapiapp
After=network.target
[Service]
User=your_username
Group=your_username
WorkingDirectory=/var/www/myfastapiapp
Environment="PATH=/var/www/myfastapiapp/venv/bin"
ExecStart=/var/www/myfastapiapp/venv/bin/gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind unix:/run/myfastapiapp.sock
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
Restart=on-failure
[Install]
WantedBy=multi-user.target
Bu servis dosyasındaki önemli noktalar:
* User ve Group: Uygulamanın çalışacağı kullanıcı ve grup. Kendi kullanıcı adınızla değiştirmeyi unutmayın. Bu, uygulamanın root yetkileriyle çalışmasını engelleyerek güvenlik sağlar.
* WorkingDirectory: Uygulamanızın kök dizini.
* Environment="PATH=...": Sanal ortamınızın bin dizinini PATH’e ekleyerek gunicorn komutunun doğru şekilde bulunmasını sağlar.
* ExecStart: Gunicorn’ı başlatmak için kullanılacak komut. Burada --bind unix:/run/myfastapiapp.sock kullanıyoruz. Bu, Gunicorn’ın bir Unix soketi (socket) üzerinden dinlemesini sağlar. Nginx, bu soket üzerinden Gunicorn ile iletişim kuracak, bu da HTTP üzerinden iletişim kurmaktan daha hızlı ve güvenlidir.
* Restart=on-failure: Uygulama bir hata nedeniyle kapanırsa, systemd otomatik olarak yeniden başlatmaya çalışır.
Dosyayı kaydedip kapattıktan sonra, systemd‘yi yeni servis dosyasını okuması için yeniden yükleyin ve ardından servisi başlatıp etkinleştirin:
sudo systemctl daemon-reload
sudo systemctl start myfastapiapp
sudo systemctl enable myfastapiapp
Servisin durumunu kontrol etmek için:
sudo systemctl status myfastapiapp
Eğer her şey yolundaysa, servis aktif (running) durumda olacaktır. Artık Gunicorn, uygulamanızı arka planda ve sürekli olarak çalıştırıyor. Bir sonraki adım, Nginx’i bu Gunicorn servisiyle iletişim kuracak şekilde yapılandırmaktır.
Nginx’i Ters Proxy Olarak Yapılandırma ve Statik Dosyaları Sunma
Uygulamanızın internetten erişilebilir olması ve performans, güvenlik gibi ek özelliklerden faydalanması için Nginx’i bir ters proxy olarak yapılandırmamız gerekiyor. Nginx, istemcilerden gelen istekleri alacak ve bunları Gunicorn tarafından dinlenen Unix soketine yönlendirecektir. Ayrıca, uygulamanızın statik dosyalarını (örneğin CSS, JavaScript, resimler) doğrudan sunarak Gunicorn’un yükünü azaltacak ve performansı artıracaktır.
İlk olarak, Nginx’i kurmanız gerekebilir. Eğer kurulu değilse:
sudo apt install nginx -y
Şimdi, Nginx için bir yapılandırma dosyası oluşturalım. Bu dosya, Nginx’in uygulamanız için nasıl davranacağını tanımlayacaktır. /etc/nginx/sites-available/ dizini altında myfastapiapp adında yeni bir dosya oluşturalım:
sudo nano /etc/nginx/sites-available/myfastapiapp
Dosyanın içine aşağıdaki içeriği yapıştırın:
server {
listen 80;
server_name your_domain_or_server_ip;
location /static/ {
alias /var/www/myfastapiapp/static/;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/myfastapiapp.sock;
}
}
Bu yapılandırmadaki önemli noktalar:
* listen 80;: Nginx’in 80 numaralı HTTP portunda dinlemesini sağlar.
* server_name your_domain_or_server_ip;: Buraya sunucunuzun IP adresini veya alan adınızı (domain name) yazın. Örneğin, example.com veya 192.168.1.100.
* location /static/ { ... }: Bu blok, Nginx’in /static/ ile başlayan URL’ler için statik dosyaları doğrudan /var/www/myfastapiapp/static/ dizininden sunmasını sağlar. Uygulamanızda statik dosyalar kullanacaksanız, bu dizini oluşturmanız ve dosyalarınızı buraya yerleştirmeniz gerekir.
* location / { ... }: Bu blok, diğer tüm istekleri yönetir.
* include proxy_params;: Nginx’in proxy istekleri için standart başlıkları (headers) ayarlamasını sağlar. Bu dosya genellikle Nginx kurulumuyla birlikte gelir ve istemci IP adresi gibi bilgileri Gunicorn’a iletmek için önemlidir.
* proxy_pass http://unix:/run/myfastapiapp.sock;: Gelen istekleri, Gunicorn’ın dinlediği Unix soketine yönlendirir. Bu, Nginx ile Gunicorn arasındaki iletişimi sağlar.
Yapılandırma dosyasını kaydettikten sonra, Nginx’in bu yapılandırmayı kullanabilmesi için sites-enabled dizinine bir sembolik bağlantı (symbolic link) oluşturmanız gerekir:
sudo ln -s /etc/nginx/sites-available/myfastapiapp /etc/nginx/sites-enabled/
Mevcut varsayılan Nginx yapılandırmasını devre dışı bırakmak iyi bir uygulamadır, çünkü kendi yapılandırmanız çakışmalara neden olabilir:
sudo unlink /etc/nginx/sites-enabled/default
Nginx yapılandırmanızın sözdizimini (syntax) kontrol etmek için:
sudo nginx -t
Eğer herhangi bir hata yoksa, Nginx servisini yeniden başlatarak yeni yapılandırmayı etkinleştirin:
sudo systemctl restart nginx
Şimdi tarayıcınızdan http://your_domain_or_server_ip adresine giderek FastAPI uygulamanıza erişebilmeniz gerekir. Nginx, isteği alacak, Gunicorn’a yönlendirecek ve Gunicorn’dan gelen yanıtı size geri gönderecektir. Ayrıca, http://your_domain_or_server_ip/docs adresinden FastAPI’nin otomatik API dokümantasyonuna da erişebilirsiniz. Eğer uygulamanızda statik dosyalar kullanacaksanız, /var/www/myfastapiapp/static/ dizinini oluşturmayı ve içine deneme amaçlı bir style.css dosyası koymayı unutmayın. Örneğin:
sudo mkdir -p /var/www/myfastapiapp/static
echo "body { background-color: lightblue; }" | sudo tee /var/www/myfastapiapp/static/style.css
Daha sonra FastAPI uygulamanızda bu statik dosyayı kullanmak için, main.py dosyanıza aşağıdaki satırları ekleyebilir ve HTML çıktısını güncelleyebilirsiniz:
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/", response_class=HTMLResponse)
async def read_root():
return """
Merhaba FastAPI
Merhaba, FastAPI!
Bu bir FastAPI uygulamasıdır.