FastAPI tez yozish va tez ishlash uchun yaratilgan freymvork, shuning uchun u mobil ilovalar, Telegram botlar va ichki xizmatlar uchun API sifatida tobora ko'p tanlanmoqda. Lokal kompyuterda uvicorn main:app --reload buyrug'i bilan hammasi bir zumda ishga tushadi. Ammo bu rejim ishlab chiqish uchun: --reload fayllarni kuzatadi, bitta jarayonda ishlaydi va server qayta yuklanganda o'zi tiklanmaydi. Ushbu maqolada FastAPI ilovasini VPS'ga to'g'ri joylash, uni doimiy ishlaydigan xizmatga aylantirish va Nginx orqali HTTPS bilan ochishni ko'rib chiqamiz.
ASGI nima va nega Uvicorn kerak
FastAPI ASGI standartiga asoslangan, ya'ni u asinxron so'rovlarni, WebSocket ulanishlarini va uzoq davom etadigan aloqalarni qo'llab-quvvatlaydi. Bunday ilovani ishga tushirish uchun ASGI server kerak, eng keng tarqalgani Uvicorn. U bir nechta ishchi jarayon ochishi mumkin, har bir jarayon esa ichida ko'plab asinxron so'rovni parallel ravishda qayta ishlaydi. Nginx esa oldinda turib, HTTPS shifrlash, sekin mijozlar va so'rov hajmi cheklovlarini o'z zimmasiga oladi, shunda Python jarayonlari faqat ilova mantig'i bilan band bo'ladi.
Misol: Toshkentdagi milliy taomlar oshxonasi yetkazib berish uchun mobil ilova buyurtma qildi. Ilova api.misol.uz manzilidagi FastAPI xizmatiga murojaat qiladi: menyu ro'yxatini oladi, buyurtma yuboradi va kuryer joylashuvini WebSocket orqali kuzatadi. Tushlik paytida so'rovlar keskin ko'payadi, shuning uchun xizmat bir nechta ishchi bilan, avtomatik qayta tiklanish bilan va to'g'ri sozlangan proksi orqali ishlashi kerak.
Loyihani serverga tayyorlash
Ilova uchun alohida tizim foydalanuvchisi va virtual muhit yarating. Bog'liqliklarni requirements.txt faylidan o'rnating; Uvicorn'ning standard varianti tezroq hodisa sikli va WebSocket kutubxonalarini birga olib keladi.
sudo apt update
sudo apt install python3-venv nginx
sudo adduser --system --group --home /srv/api api
sudo -u api python3 -m venv /srv/api/venv
sudo -u api /srv/api/venv/bin/pip install -r /srv/api/requirements.txt "uvicorn[standard]"
Ma'lumotlar bazasi paroli, JWT kaliti va tashqi xizmatlar tokenlari kodda emas, /srv/api/.env faylida saqlanadi va ilova ularni muhit o'zgaruvchilari sifatida o'qiydi. Bu faylga faqat api foydalanuvchisi kira olishi uchun chmod 600 qo'ying. Avval ilovani qo'lda ishga tushirib, javob berishini tekshirib oling:
cd /srv/api
sudo -u api venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000
curl http://127.0.0.1:8000/health
Ishlab chiqarish uchun ilova sozlamalari
FastAPI standart holatda /docs va /redoc sahifalarida API'ning to'liq tavsifini ochiq ko'rsatadi. Ichki yoki tijorat API uchun bu ortiqcha ma'lumot, shuning uchun ishlab chiqarishda ularni o'chirib qo'yish yoki faqat ma'lum IP manzillarga ochish ma'qul. Monitoring uchun esa oddiy sog'liq tekshiruvi nuqtasini qo'shing.
import os
from fastapi import FastAPI
is_prod = os.getenv("APP_ENV") == "production"
app = FastAPI(
docs_url=None if is_prod else "/docs",
redoc_url=None if is_prod else "/redoc",
)
@app.get("/health")
def health():
return {"status": "ok"}
Yana bir muhim jihat bor: async def bilan yozilgan endpoint ichida bloklovchi kod, masalan sinxron HTTP so'rov yoki sinxron ma'lumotlar bazasi drayveri ishlatilsa, butun ishchi jarayon kutib qoladi va boshqa so'rovlar ham sekinlashadi. Bunday hollarda yo asinxron kutubxonadan foydalaning, yo endpoint'ni oddiy def qilib yozing, shunda FastAPI uni alohida oqimlar hovuzida bajaradi.
Uvicorn'ni systemd xizmati qilish
Xizmat server qayta yuklanganda avtomatik ko'tarilishi va xato bilan to'xtaganda qayta ishga tushishi kerak. /etc/systemd/system/api.service faylini yarating:
[Unit]
Description=FastAPI (Uvicorn) for api.misol.uz
After=network.target
[Service]
User=api
Group=api
WorkingDirectory=/srv/api
EnvironmentFile=/srv/api/.env
ExecStart=/srv/api/venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 2 --proxy-headers --forwarded-allow-ips=127.0.0.1
Restart=on-failure
[Install]
WantedBy=multi-user.target
--host 127.0.0.1 xizmat faqat serverning ichidan ochiq bo'lishini ta'minlaydi, tashqaridan unga faqat Nginx orqali kirish mumkin. --proxy-headers va --forwarded-allow-ips esa Nginx yuborgan X-Forwarded-For va X-Forwarded-Proto sarlavhalariga ishonishni buyuradi, shunda ilova haqiqiy mijoz IP manzilini va HTTPS ekanini ko'radi. Ishchilar soni serverdagi protsessor yadrolariga qarab tanlanadi. Xizmatni yoqing:
sudo systemctl daemon-reload
sudo systemctl enable --now api
sudo journalctl -u api -f
Nginx proksi va WebSocket
WebSocket ulanishi oddiy HTTP so'rovdan protokolni yangilash orqali boshlanadi, shuning uchun Nginx Upgrade va Connection sarlavhalarini o'tkazishi kerak. Avval /etc/nginx/conf.d/upgrade.conf faylida yordamchi o'zgaruvchi e'lon qilinadi:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
So'ng sayt konfiguratsiyasi /etc/nginx/sites-available/api yoziladi:
server {
listen 80;
server_name api.misol.uz;
client_max_body_size 10M;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 300s;
}
}
sudo ln -s /etc/nginx/sites-available/api /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d api.misol.uz
proxy_read_timeout kuryer kuzatuvi kabi uzoq ochiq turadigan WebSocket ulanishlarining Nginx tomonidan bir daqiqada uzib qo'yilishining oldini oladi. Sertifikat olishdan oldin api subdomeni uchun A yozuvi VPS manziliga ko'rsatilgan bo'lishi kerak; buni sayt.uz kabinetidagi DNS bo'limida qo'shish mumkin.
Yangilash va muammolarni aniqlash
Yangi versiyani chiqarish tartibi oddiy: kodni yangilash, bog'liqliklarni o'rnatish, kerak bo'lsa ma'lumotlar bazasi migratsiyasini bajarish va sudo systemctl restart api. Agar Nginx 502 qaytarsa, avval journalctl -u api loglariga qarang: ko'pincha modul yo'li noto'g'ri, .env dagi o'zgaruvchi yetishmaydi yoki port boshqa jarayon tomonidan band qilingan bo'ladi. Ilova ichida mijozning IP manzili doim 127.0.0.1 bo'lib ko'rinayotgan bo'lsa, --proxy-headers parametrini tekshiring. Oshxona misolida bu tartib tushlik oldidan yangilanishni xavfsiz qilish imkonini beradi: xizmat bir necha soniyada qayta ko'tariladi, mobil ilova esa buni deyarli sezmaydi.