LiteLLM ile kendi LLM gateway sunucunuzu kurun
LiteLLM kullanarak tüm LLM servislerini tek bir OpenAI uyumlu uç noktada birleştirin. Sanal anahtarlar, bütçe limitleri ve model yedekleme özelliklerini yapılandırın.
Self-hosted LLM gateway nedir
LiteLLM, kendi sunucunuzda barındırdığınız açık kaynaklı bir LLM gateway'idir: tüm uygulamalarınızın çağrı yaptığı ve gelen her isteği ilgili sağlayıcıya ileten tek bir HTTP uç noktasıdır. LLM, büyük dil modeli (large language model) anlamına gelir. Gateway, OpenAI chat completions API (uygulama programlama arayüzü) ile uyumludur; bu nedenle OpenAI ile iletişim kurabilen her istemci kütüphanesi, base URL ve anahtar (key) üzerinde yapılacak iki değişikliğin ardından bu gateway ile çalışabilir.
Bu dolaylı katmanın temel amacı budur. Uygulamalarınız artık sağlayıcı kimlik bilgilerini tutmaz. Bir modeli değiştirmek, beş farklı serviste kod değişikliği yapmak yerine sunucudaki yapılandırma dosyasında tek satırlık bir işleme dönüşür. Her çağrı tek bir süreç üzerinden geçtiği için, bütçe kısıtlaması uygulayabileceğiniz ve harcamaların kaydını tutabileceğiniz merkezi bir noktanız olur.
Sistem çalışır hale geldiğinde şunlara sahip olursunuz:
- Tek bir uç nokta. Uygulamalar
https://gateway.example.com/v1adresini hedefler vebulkveyastronggibi sizin belirlediğiniz bir model adını talep eder. - Sanal anahtarlar. Her uygulama, kendi model izin listesine ve harcama limitine sahip özel bir anahtar alır. Diğerlerini etkilemeden birini iptal edebilirsiniz.
- Yedekleme (Fallbacks). Başarısız olan bir çağrı veya çok büyük bir istem (prompt), otomatik olarak farklı bir model üzerinden tekrar denenir.
- Log kaydı. Her istek, maliyetini içeren bir satır olarak yazılır; böylece "bu harcamayı hangi uygulama yaptı" sorusunun bir yanıtı olur.
Ağ geçidini neden kendiniz çalıştırmalısınız
Yönetilen bir yönlendirici, her isteğin ortasında başka birinin süreci bulunan aynı yapıdadır. Bunu kendiniz çalıştırdığınızda, sağlayıcı anahtarlarınızı ve istem metinlerinizi kontrolünüz altındaki bir kutuda tutarsınız. Bunun maliyeti gerçektir: Artık her uygulamanın bağımlı olduğu bileşeni siz yönetiyorsunuz. Bu kılavuzun son bölümü bu maliyet hakkındadır, çünkü çoğu yazının dışarıda bıraktığı kısım budur.
Gereksinimler
- Docker ve Compose eklentisi kurulu, Ubuntu 24.04 çalıştıran bir VPS (sanal özel sunucu).
- Makine dışındaki istemciler ağ geçidine TLS (taşıma katmanı güvenliği) üzerinden erişecekse, sunucuya yönlendirilmiş bir alan adı.
- En az bir sağlayıcı API anahtarı.
Ağ geçidi çıkarım işlemi yapmaz. İstekleri iletir ve yanıtları akış olarak geri döndürür; bu nedenle CPU yükü model boyutundan ziyade istek hacmine göre değişir. 1 vCPU kapasiteli bir sunucu, birkaç dahili uygulamayı sorunsuz bir şekilde çalıştırır. Ağ geçidi her istek için bir harcama satırı yazdığından, veritabanı zamanla büyür.
Önce config.yaml dosyasını oluşturun
Yapılandırma dosyası, bir istemcinin hangi modelleri talep edebileceğini belirler. Dört üst düzey bölüm önemlidir: model_list, litellm_settings, router_settings ve general_settings.
model_list:
- model_name: bulk
litellm_params:
model: anthropic/claude-haiku-4-5
api_key: os.environ/ANTHROPIC_API_KEY
- model_name: strong
litellm_params:
model: anthropic/claude-sonnet-5
api_key: os.environ/ANTHROPIC_API_KEY
- model_name: strong
litellm_params:
model: openai/gpt-5.5
api_key: os.environ/OPENAI_API_KEY
litellm_settings:
num_retries: 2
request_timeout: 120
json_logs: true
set_verbose: false
router_settings:
allowed_fails: 3
cooldown_time: 30
fallbacks: [{"bulk": ["strong"]}]
context_window_fallbacks: [{"bulk": ["strong"]}]
general_settings:
background_health_checks: true
health_check_interval: 300model_name, istemcilerinizin gönderdiği isimdir. litellm_params.model ise provider/model olarak yazılan gerçek modeldir. Modellerinizi satıcı ismine göre değil, yaptıkları işe göre adlandırın. bulk için istekte bulunan bir uygulama, gelecek ay bulk modelini farklı bir modelle değiştirmeye karar verdiğinizde çalışmaya devam eder.
api_key: os.environ/ANTHROPIC_API_KEY, LiteLLM'e bu değişkeni çalışma zamanında okumasını söyler. Gerçek anahtar dosya içinde asla yer almaz; bu önemlidir çünkü config.yaml sürüm kontrolüne gönderdiğiniz dosyadır.
İki girdi, kasıtlı olarak strong ismini paylaşır. Birden fazla dağıtım aynı model_name değerini taşıdığında, yönlendirici bunları birbirinin yerine kullanılabilir olarak görür ve o isim için gelen istekleri aralarında dağıtır. strong, bir sağlayıcının sorun yaşadığı durumlarda bu şekilde ayakta kalır: bir dağıtım soğuma (aşağıda açıklanmıştır) moduna girdiğinde, strong için gelen yeni istekler diğerine yönlendirilir.
num_retries: 2, tekrar denenebilir bir hatayı iki defaya kadar yeniden dener. Bu yeniden denemeler, aynı model grubu içindeki başka bir uygun dağıtımı seçebilir: 2026-10-29 tarihinde kontrol edilen LiteLLM mimari belgeleri, grup içi yeniden denemeleri ve grup dışı yedeklemeleri (fallback) ayrı adımlar olarak tanımlar. Bu nedenle strong için yapılan bir yeniden deneme, ağırlıklı yük devretme (weighted failover) etkinleştirilmeden diğer sağlayıcıya ulaşabilir. Bir yedekleme (fallback) ancak bu yeniden denemeler tükendikten sonra devreye girer.
allowed_fails ve cooldown_time yönlendirici seçenekleridir, bu nedenle router_settings altında yer alırlar. Proxy, yönlendiricisini bu bölümden oluşturur ve v1.95.0 sürümünde litellm_settings altına yazılan bir cooldown_time ona asla ulaşmaz; bu yüzden soğuma süreleri sessizce 5 saniyelik varsayılan değerde kalır. cooldown_time: 30, bir dağıtımın soğuma moduna girdikten sonra ne kadar süre rotasyon dışında kalacağını belirler. Yapılandırma referansı allowed_fails değerini, bir dağıtımın soğuma moduna girmeden önce cooldown_time süresi içinde aşması gereken hata sayısı olarak tanımlar. v1.95.0 kaynak kodunda allowed_fails: 3 varsayılan değerdir ve bu değerde yönlendirici yerleşik tetikleyicilere bağlı kalır; hata sayısı ancak siz farklı bir değer atadığınızda devreye girer. Bu tetikleyiciler arasında; birden fazla dağıtımı olan bir grup için 429 yanıtı alındığında anında soğuma, en az 5 istekten sonra mevcut dakika içinde %50'den fazla hata oluşması ve 401 gibi yönlendiricinin yeniden denemeyeceği hatalar bulunur. Ayrıca, mevcut dakika içindeki tüm istekler başarısız olduğunda ve trafik SINGLE_DEPLOYMENT_TRAFFIC_FAILURE_THRESHOLD değerine (varsayılan olarak 1000 istek) ulaştığında tek bir dağıtımı soğumaya alan ayrı bir tetikleyici daha vardır. Bir sağlayıcı anlık olarak 500 hataları döndürdüğünde her istekte denenmeyi bırakır, ancak birkaç dakikada bir gelen tek tük 500 hataları soğumayı tetiklemez.
fallbacks ve context_window_fallbacks farklı tetikleyicilere sahiptir ve ikincisi, insanların göz ardı ettiği ancak oldukça yararlı olan seçenektir.
fallbacks, birincil çağrı başarısız olduğunda tetiklenir.context_window_fallbacks, sağlayıcı isteği modelin bağlam penceresinden (context window) daha uzun olduğu gerekçesiyle reddettiğinde tetiklenir; böylece çok büyük bir istem, hata döndürmek yerine yer açabilen başka bir modele gönderilir.
Ayrıca, sağlayıcının içerik politikası gereği reddettiği durumlar için content_policy_fallbacks seçeneği de mevcuttur. Bunu yalnızca bu çağrıları yönlendirebileceğiniz mantıklı bir yeriniz varsa ayarlayın.
LiteLLM uygulamasının Docker Compose ile VPS üzerinde dağıtılması
Üç dosya barındıran bir dizin oluşturun: config.yaml, docker-compose.yml ve .env. Upstream hızlı başlangıç kılavuzu latest etiketini çeker. Bunun yerine bir sürüm etiketi sabitleyin; böylece docker compose up -d tarihinde yapacağınız işlem size bugün sunduğu ağ geçidinin aynısını sunar ve geri alma işlemi tek satıra iner.
services:
litellm:
image: ghcr.io/berriai/litellm:v1.95.0
restart: unless-stopped
command: ["--config", "/app/config.yaml", "--num_workers", "1"]
ports:
- "127.0.0.1:4000:4000"
volumes:
- ./config.yaml:/app/config.yaml:ro
env_file: .env
depends_on:
db:
condition: service_healthy
db:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_USER: litellm
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}
POSTGRES_DB: litellm
healthcheck:
test: ["CMD-SHELL", "pg_isready -U litellm"]
interval: 5s
timeout: 5s
retries: 10
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:Compose, .env dosyasını burada iki kez okur. Birincisi, ${POSTGRES_PASSWORD} değişkenini compose dosyası içinde yerine koymak için; ikincisi ise env_file aracılığıyla tüm değişkenleri container içine aktarmak için.
v1.95.0, Ağustos 2026 itibarıyla güncel sürümdü. Projenin sürümler sayfasına bakın ve dağıtım yaptığınız sırada güncel olan sürümü sabitleyin. Her sürüm bir imza yayınlar, böylece güvenmeden önce imajı doğrulayabilirsiniz:
cosign verify --key https://raw.githubusercontent.com/BerriAI/litellm/v1.95.0/cosign.pub ghcr.io/berriai/litellm:v1.95.0Port satırı 127.0.0.1:4000:4000 şeklindedir ve portu yalnızca loopback arayüzünde yayınlar. Bunun yerine 4000:4000 yazarsanız ağ geçidiniz tüm internete açık hale gelir. Çünkü Docker, iptables FORWARD zincirine kendi kurallarını ekler ve bu kurallar ufw kurallarından önce değerlendirilir; bu nedenle ufw deny 4000 bunu engellemez. Self-hosted bir ağ geçidinin açık kalmasının en yaygın yolu budur: Docker'ın bir container portunu ufw kurallarını atlayarak nasıl yayınladığına bakın. Dışarıdan gelen trafik bunun yerine reverse proxy üzerinden ulaşmalıdır.
Sağlayıcı anahtarlarını imajın dışında tutun
.env dosyası tüm gizli bilgileri barındırır. Çalışma zamanında ortam değişkeni olarak aktarılır, bu nedenle asla imajın içine gömülmez ve hiçbir zaman commit edilmez.
LITELLM_MASTER_KEY=sk-REPLACE_ME
LITELLM_SALT_KEY=sk-REPLACE_ME_TOO
POSTGRES_PASSWORD=REPLACE_ME_AS_WELL
DATABASE_URL=postgresql://litellm:REPLACE_ME_AS_WELL@db:5432/litellm
STORE_MODEL_IN_DB=True
LITELLM_MODE=PRODUCTION
LITELLM_LOG=ERROR
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-proj-...İki adet LiteLLM anahtarını gerçek rastgelelik ile oluşturun ve ardından dosya erişimini kısıtlayın:
printf 'sk-%s\n' "$(openssl rand -hex 32)"
chmod 600 .envLITELLM_MASTER_KEY yönetici kimlik bilgisidir. Yönetim API'sinin kimlik doğrulamasını sağlar ve /ui adresindeki Admin UI için paroladır. Hiçbir uygulama bu bilgiyi saklamamalıdır.
LITELLM_SALT_KEY, veritabanında saklanan sağlayıcı kimlik bilgilerini şifreler. Bir kez ayarlayın ve öyle bırakın. Daha sonra değiştirirseniz, halihazırda saklanan kimlik bilgileri şifresi çözülemez hale gelir; bu durumda ağ geçidi normal şekilde başlar ancak sağlayıcılara yapılan her çağrı kimlik doğrulama hatası verir.
STORE_MODEL_IN_DB=True, config.yaml dosyasına dokunmadan Admin UI üzerinden model eklemenize ve düzenlemenize olanak tanır. Bu kullanışlıdır ancak doğruluk kaynağınızı ikiye böler. Hangisinin yetkili olduğuna karar verin ve bu kararı config dosyasının yanına not edin.
Anahtarları yapılandırma dosyasının dışında tutma mantığı, onları bir aracıya (agent) verdiğiniz araçların dışında tutma mantığıyla aynıdır. Sağlayıcı gizli bilgilerini yapay zeka aracılarından uzak tutma bu modeli, env dosyaları ve Docker Compose içindeki gizli bilgiler ise teknik işleyişi ele alır.
Sistemi ayağa kaldırın ve ilk başlatma sürecini izleyin:
docker compose up -d
docker compose logs -f litellmÇalıştığından emin olun
Kimlik doğrulaması gerektirmeyen iki adet ve kimlik doğrulaması gerektiren bir adet sonda bulunmaktadır; bu sondalar farklı nedenlerle başarısız olurlar.
curl -s http://127.0.0.1:4000/health/liveliness
curl -s http://127.0.0.1:4000/health/readiness/health/liveliness kimlik doğrulaması gerektirmez ve süreç çalışırken "I'm alive!" yanıtını verir. /health/readiness da kimlik doğrulaması gerektirmez. Bu uç nokta, "status": "healthy" ve db alanlarını içeren bir JSON nesnesi döndürür; veritabanına ulaşılamadığında ise 503 hatası verir. İzleme aracınızı readiness uç noktasına yönlendirin; çünkü liveliness, tek bir sanal anahtarı bile çözümleyemeyen bir ağ geçidinde dahi yeşil kalmaya devam eder.
Kimlik doğrulaması gerektiren kontrol, sağlayıcılarla iletişim kuran sondadır:
curl -s http://127.0.0.1:4000/health \
-H "Authorization: Bearer $LITELLM_MASTER_KEY"Bu sonda, healthy_endpoints ve unhealthy_endpoints dizileriyle yanıt verir. unhealthy_endpoints içinde bir kimlik doğrulama hatasıyla bekleyen bir model, .env içindeki sağlayıcı anahtarının yanlış veya eksik olduğu anlamına gelir; bu, şu an tespit etmeniz gereken hata türüdür. background_health_checks: true ayarlı olduğu için, proxy bu sondaları kendi başına her health_check_interval saniyede bir çalıştırır ve /health son sonucu döndürür; bu nedenle uç noktayı sorgulamak, her seferinde sağlayıcılarınıza bir test isteği göndermez.
Sanal anahtarlar ve anahtar bazlı bütçeler
Her uygulama, ana anahtara karşı oluşturulmuş kendi özel anahtarını alır.
curl -s http://127.0.0.1:4000/key/generate \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H 'Content-Type: application/json' \
-d '{
"key_alias": "nightly-summariser",
"models": ["bulk"],
"max_budget": 5,
"budget_duration": "30d",
"rpm_limit": 60,
"tpm_limit": 200000
}'Yanıt, sk- ile başlayan bir key alanı içerir. Uygulamanın aldığı ve erişebildiği tek veri bu dizgidir.
models, bu anahtarın neleri talep edebileceğini belirleyen bir izin listesidir. Yukarıdaki anahtar yalnızcabulkisteğinde bulunabilir, başka hiçbir şey isteyemez.budget_duration: "30d"ilemax_budget: 5, takvim ayı başına beş ABD dolarıdır. LiteLLM,litellm_settingsaltındatimezoneayarlanmadığı sürece,30dbütçesini her ayın 1'inde gece yarısı UTC saatine göre sıfırlar. Bu, 30 günlük kayan bir dönem yerine sabit bir takvim ayını ifade eder; dolayısıyla anahtar beş dolarlık limiti tükettiğinde, bir sonraki ayın 1'ine kadar çalışmayı durdurur.rpm_limitvetpm_limit, yalnızca bu anahtar için dakika başına istek ve dakika başına token sınırlarını belirler.key_alias, altı hafta sonra harcama günlüğünde göreceğiniz tanımlayıcıdır. Bunu mutlaka ayarlayın.
Bütçe tükendiğinde, çağrı budget_exceeded türünde bir hata ve şu biçimde bir mesajla başarısız olur:
Budget has been exceeded! Key=<key> Current cost: <spend>, Max budget: <max_budget>Durum kodu sürüme göre değişiklik gösterir. Sabitlenmiş v1.95.0 sürümünde bu kod HTTP 429'dur. v1.104.0 sürümünden itibaren varsayılan değer HTTP 422'dir; litellm_settings altında budget_exceeded_status_code: 429 ayarını yapmak, önceki kodun kullanılmasını sağlar. Gerçek rpm_limit ve tpm_limit limit aşımları, her iki sürümde de 429 döndürmeye devam eder. Her yükseltmeden sonra hangi kodu aldığınızı kontrol edin.
Durum kodları kafa karıştırıcı olabilir çünkü hiçbir kod doğrudan "bütçe" ifadesini içermez. Bir istemci kütüphanesi 429 kodunu hız sınırı (rate limit) olarak raporlar ve bütçe sıfırlanana kadar geri gelmeyecek bir limit için üstel geri çekilme (backoff) ile yeniden deneme yapabilir; 422 kodunu ise işlenemeyen bir istek olarak raporlar. Yanıt gövdesini durum koduyla birlikte günlüğe kaydedin; aksi takdirde bütçe tükenmesi her seferinde farklı bir sorun gibi görünecektir.
Anahtarları aynı yönetim API'si üzerinden inceleyin ve düzenleyin:
curl -s "http://127.0.0.1:4000/key/info?key=sk-..." \
-H "Authorization: Bearer $LITELLM_MASTER_KEY"
curl -s -X POST http://127.0.0.1:4000/key/update \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H 'Content-Type: application/json' \
-d '{"key": "sk-...", "max_budget": 25}'Ağ geçidinde uygulanan bir bütçe, sorun ajanın kendisinden kaynaklansa bile geçerliliğini korur; bu nedenle bütçe yönetimi, VPS üzerinde yapay zeka ajanları için maliyet kontrolü mekanizmasının temelini oluşturur.
Toplu işleri düşük maliyetli bir modele yönlendirme
İstemciyi ağ geçidine (gateway) yönlendirin. Base URL, anahtar ve model adı şu şekildedir:
curl -s http://127.0.0.1:4000/v1/chat/completions \
-H "Authorization: Bearer sk-<the virtual key>" \
-H 'Content-Type: application/json' \
-d '{
"model": "bulk",
"messages": [{"role": "user", "content": "Say hello in five words."}]
}'Herhangi bir OpenAI istemci kütüphanesi aynı şekilde çalışır: base_url değerini https://gateway.example.com/v1 olarak, api_key değerini ise sanal anahtar olarak ayarlayın.
config.yaml dosyasındaki yönlendirme politikası, çağrıyı yapan tarafın haberi olmadan uygulanır. bulk için gelen bir istek, düşük maliyetli modele gider. Eğer bu çağrı yeniden denemelerden sonra başarısız olursa, istek strong üzerinde tekrar denenir. Eğer istem bulk için çok uzunsa, context_window_fallbacks hata döndürmek yerine isteği strong adresine gönderir. Sınıflandırma geçişi veya özetleme birikimi gibi toplu işler varsayılan olarak düşük maliyetle çalışır ve yalnızca zorlu istekler daha yüksek maliyet oluşturur.
Ağ geçidinin araç kullanan aracı (agent) sistemleri için önem kazandığı nokta burasıdır. Aynı VPS üzerinde çalışan bir MCP (model context protocol) sunucusu ve onu yöneten aracı, tek bir uç noktaya işaret edebilir; böylece arkadaki model, herhangi bir yeniden dağıtım (redeployment) gerektirmeden değiştirilebilir.
Yedekleme (fallback) mekanizmasının devreye girdiği nasıl anlaşılır?
Bu, hiçbir şeyin bozuk görünmemesi nedeniyle maliyet yaratan bir hata modudur. Başarılı bir yedekleme işlemi, normal bir yanıt gövdesiyle birlikte HTTP 200 kodu döndürür. Ucuz modeliniz bir gün boyunca kapalı kalabilir, her çağrı sessizce pahalı olan model tarafından karşılanabilir ve elinizdeki ilk kanıt fatura olur.
Kanıtlar yanıt başlıklarında mevcuttur. Bunları kontrol edin:
curl -s -D - -o /dev/null http://127.0.0.1:4000/v1/chat/completions \
-H "Authorization: Bearer sk-<the virtual key>" \
-H 'Content-Type: application/json' \
-d '{"model":"bulk","messages":[{"role":"user","content":"ping"}]}' \
| grep -i '^x-litellm'x-litellm-model-group, isteğin yönlendirildiği modelin adıdır (örneğinbulk).x-litellm-model-id, yanıtı veren dağıtımın kimliğidir (ID); bunu/v1/model/info?litellm_model_id=...ile sorgulayabilirsiniz. Bu kimlik,bulkdağıtımlarınızdan biri olmadığında bir yedekleme gerçekleşmiş demektir.x-litellm-attempted-fallbacksvex-litellm-attempted-retriesbunları sayar. Sağlıklı bir çağrıda her ikisi de 0'dan büyük bir değer göstermez.x-litellm-response-cost, o tekil çağrının ABD doları cinsinden maliyetidir.x-litellm-call-id, aynı çağrıyı loglarınızda bulmak için kullandığınız tanımlayıcıdır.
Her istekte x-litellm-attempted-fallbacks değerini kaydedin ve 0'dan büyük olduğu her durumda uyarı oluşturun. Bu tek sayı, çalışan bir yönlendirme politikası ile sessizce "her zaman pahalı modeli kullan" haline gelmiş bir yönlendirme politikası arasındaki farktır.
Bunun tam sürümü izlemedir (tracing) ve kendi kurulumunu gerektirir: aracı çağrılarını izlemek için self-hosted Langfuse. LiteLLM geri çağırma (callback) işlevini içerir, bu nedenle bağlantıyı kurmak iki satırlık kod ve kimlik bilgilerinden ibarettir.
litellm_settings:
success_callback: ["langfuse"]
failure_callback: ["langfuse"]LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_HOST=https://langfuse.example.comLangfuse v3 ve sonraki sürümler için LiteLLM'in Langfuse sayfası artık langfuse_otel ön ayarını önermektedir; yukarıdaki langfuse geri çağırma işlevi hala belgelenmiştir. failure_callback ve success_callback değerlerini ayarlayın. Bunu atlarsanız, yalnızca hiçbir sorunun yaşanmadığı izleri tutarsınız. Bunlardan bağımsız olarak, LiteLLM her istek için Postgres'e bir harcama satırı yazar ve /ui adresindeki Yönetici Arayüzü bu tabloyu okur. Trafikle birlikte büyüdüğü için küçük bir disk üzerinde izlenmelidir.
Ağ geçidini bir reverse proxy arkasına alın
Sunucu dışından hiçbir trafik 4000 numaralı porta doğrudan erişmemelidir. TLS termination işlemini nginx veya Caddy üzerinde gerçekleştirin ve trafiği loopback adresine yönlendirin.
location / {
proxy_pass http://127.0.0.1:4000;
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_buffering off;
proxy_read_timeout 600s;
}Bu satırlardan ikisi genellikle göz ardı edilir. proxy_buffering off, akış halindeki bir tamamlanma işlemi bir dizi server-sent events (sunucu tarafından gönderilen olaylar) olduğu için önemlidir; nginx üzerinde tamponlama (buffering) etkin olduğunda, veriler istemciye iletilmeden önce tamponlarda birikir ve teslimat gecikir. proxy_read_timeout 600s, nginx'in varsayılan 60 saniyelik süresi tüm yanıtın süresi değil, ağ geçidinden gelen iki okuma işlemi arasında beklediği en uzun süre olduğu için önemlidir. Akış içermeyen bir tamamlanma işlemi, üretim bitene kadar hiçbir veri göndermez; bu nedenle uzun süren bir işlemde 60 saniye boyunca hiçbir bayt ulaşmaz ve istemci 504 hatası alırken hata günlüğüne upstream timed out (110: Connection timed out) while reading response header from upstream kaydedilir. Parçalar halinde gönderim yapan akışlı bir tamamlanma işlemi ise 60 saniyeden çok daha uzun sürebilir; bu zaman aşımı yalnızca modelin belirtilen süre boyunca yanıt vermemesi durumunda tetiklenir.
Sertifika işlemleri için nginx üzerinde Let's Encrypt ile Certbot kullanımı en kısa yoldur. Eğer sunucu halihazırda birden fazla container barındırıyorsa, birden fazla Compose uygulaması önünde Traefik kullanımı yönlendirme ve sertifika işlemlerini tek bir noktadan yönetmenizi sağlar.
Ağ geçidi artık tek bir hata noktasıdır
Kurduğunuz yapının doğası konusunda dürüst olun. Sahip olduğunuz tüm uygulamalar artık tek bir VPS üzerindeki tek bir container'a bağımlıdır. Bu container kapalıyken, tamamen sağlıklı olan sağlayıcılar dahil olmak üzere hiçbir uygulama modele erişemez. Bu durum dört sonucu beraberinde getirir.
- Hatalı bir yapılandırma her şeyi aynı anda devre dışı bırakır.
restart: unless-stoppedçöken bir süreci yeniden başlatır; ancak config.yaml dosyasını ayrıştıramayan bir container'ı sürekli olarak yeniden başlatmaya devam eder. Her yapılandırma değişikliğinden sonradocker compose logs litellmdosyasını okuyun ve yapılandırma değişikliklerini, onları izleyecek vaktiniz olduğunda yapın. - Önbellek isabetsizliği durumunda Postgres istek yolunda yer alır. Sanal anahtar araması, anahtar önbellekte olmadığında veritabanını kullanır; harcama kaydı ise yanıttan sonra asenkron olarak çalışır.
/health/readinessüzerinden 503 hatası almanız, ağ geçidinin çalıştığını ancak her iki işlemi de yapamadığını gösteren bir uyarıdır. - Önce çekirdekleri kullanın, ardından örnekleri (instance) artırın. Projenin örnek başına bir çalışan (
--num_workers 1) şeklindeki üretim kılavuzu, sizin yerinize örnekleri artıran Kubernetes veya başka bir pod autoscaler içindir. Bu örnekteki gibi tek bir VM veya çıplak container için durum tam tersidir: çalışan sayısını makinenin vCPU sayısına ayarlayın. Yukarıdaki 1 vCPU'lu makinede bu değer hala--num_workers 1'dır; daha büyük bir makinede bu sayıyı artırın ve her çalışanın kendi bellek yükünü taşıdığını unutmayın. Yük dengeleyici arkasındaki ikinci bir ağ geçidi, tek container sorununu ortadan kaldırır. Ancak veritabanı sorununu ortadan kaldırmaz. - Yeniden oluşturamayacağınız verileri yedekleyin. Bu veriler
config.yamlve.envdosyaları ile veritabanının birpg_dumpyedeğidir.LITELLM_SALT_KEYdosyasını kaybetmek, veritabanı dökümü içindeki şifrelenmiş sağlayıcı kimlik bilgilerini kullanılamaz hale getirir; bu nedenle env dosyası ve veritabanı dökümü aynı yedekleme işine dahil edilmelidir: restic ile sunucu dışı depolamaya yedekleme.
Yükseltme işlemi, image etiketini düzenleyip docker compose up -d komutunu çalıştırmaktan ibarettir. LiteLLM varsayılan olarak başlangıçta prisma migrate deploy çalıştırır, bu nedenle yeni container ilk açılışında veritabanı şemasını günceller. Etiketi değiştirmeden önce döküm alın; çünkü eski image'ı geri yüklemek, halihazırda çalışmış bir veritabanı göçünü geri almaz.
Sadece ulaştığınız sürümün değil, atladığınız her sürümün sürüm notlarını okuyun. v1.95.0 sürümünden v1.104.0 veya sonraki bir sürüme geçmek, bazı köklü değişiklikleri beraberinde getirir: yukarıda belirtilen bütçe durum kodu, ayarlanmamış, boş veya herkesçe bilinen bir ana anahtar (master key) ile başlamayı reddeden bir proxy ve veritabanı kurulumu başarısız olduğunda kapanan bir proxy. Bu durum restart: unless-stopped altında bir yeniden başlatma döngüsü olarak görünür. v1.102.x veya daha eski bir sürümden geliyorsanız, v1.104.0 notları ayrıca iki adet LiteLLM_SpendLogs indeksini manuel olarak oluşturmanızı ister.
FAQ
LiteLLM her çağrıya fark edilebilir bir gecikme ekler mi?
Proje, Ekim 2026 tarihli README dosyasında belirttiği üzere, saniyede 1000 istekte 95. yüzdelik dilimde 8 ms gecikme süresi bildirmektedir. Bu değeri bir üretici verisi olarak değerlendirin. Gecikmenizi asıl etkileyen değer, uygulamalarınız ile ağ geçidi arasındaki ağ mesafesidir; çünkü her çağrıya bir gidiş-dönüş süresi eklemiş olursunuz. Ağ geçidini, onu çağıran uygulamalarla aynı bölgede çalıştırın ve ardından gerçek bir yanıt üzerinde x-litellm-overhead-duration-ms başlığı ile kendi ek yükünüzü ölçün.
Nginx'i öne koyduktan sonra neden streaming çalışmayı durdurdu?
Çünkü Nginx varsayılan olarak yukarı akış (upstream) yanıtlarını arabelleğe alır ve streaming tamamlanması, sunucu tarafından gönderilen bir dizi olaydan (server-sent events) oluşur. proxy_buffering açıkken Nginx, parçaları istemciye iletmeden önce arabelleklerde toplar ve teslimatı geciktirir. Location bloğunda proxy_buffering off; ayarını yapın. Aynı blokta proxy_read_timeout değerini de yükseltin. Nginx, ağ geçidinden veri gelmediğinde varsayılan olarak 60 saniye sonra bağlantıyı keser; bu süre, streaming olmayan uzun bir üretim süreci için kolayca aşılır ve istemci 504 hatası alır.
Sanal bir anahtarın bütçesi tükendiğinde ne olur?
Çağrı, budget_exceeded türünde bir hata ve Budget has been exceeded! Key=<key> Current cost: <spend>, Max budget: <max_budget> biçiminde bir mesajla başarısız olur. Sabitlenmiş v1.95.0 sürümünde durum kodu HTTP 429'dur; v1.104.0 sürümünden itibaren ise varsayılan değer HTTP 422'dir. Hiçbir kod doğrudan bütçe tükendiğini belirtmez; tuzak buradadır: bir istemci kütüphanesi 429 kodunu hız sınırlaması (rate limit) olarak raporlar ve yeniden deneme yapabilir, bu yüzden kullanıcılar mesajı okumak yerine hız sınırlamasını araştırmaya başlar. Yanıt gövdesini durum koduyla birlikte kaydedin. Ana anahtara karşı /key/info?key=sk-... kullanarak anahtarın gerçek durumunu doğrulayın ve bütçe çok düşük ayarlanmışsa /key/update ile üst sınırı yükseltin.
Ağ geçidi, barındırılan modellerin yanı sıra yerel bir modele de yönlendirme yapabilir mi?
Evet, bu model_list içinde bir giriş daha oluşturur. api_base ile birlikte ollama_chat/ önekini kullanın; örneğin api_base: http://ollama:11434 yanında model: ollama_chat/llama3.1. Compose'un varsayılan ağ yapısında, bir container içindeki localhost o container'ın kendisini ifade eder; bu nedenle asla 127.0.0.1 kullanmayın, bunun yerine Compose servis adını veya Docker ağındaki ana makine adresini kullanın. Container'ın ana makine ağ yığınını paylaştığı host networking modu bu durumun istisnasıdır. Yerel modeli ayağa kaldırmak ayrı bir işlemdir: bkz. Ollama ile VPS üzerinde LLM self-hosting.