Docker Container İçinde Ollama Çalıştırma

Yerel LLM çalıştırmanın en popüler yollarından biri olan Ollama’yı Docker container içinde koşturmak, hem izolasyon hem de taşınabilirlik açısından ciddi avantajlar sunuyor. Bare-metal kurulum yerine containerized bir yaklaşım tercih ettiğinizde, aynı modeli farklı sunuculara dakikalar içinde taşıyabilir, versiyon yönetimini kolaylaştırabilir ve sistem genelinde bağımlılık sorunlarının önüne geçebilirsiniz. Bu yazıda Ollama’yı Docker içinde sıfırdan kuracak, GPU desteğini aktif edecek ve production ortamına uygun bir yapı oluşturacağız.

Neden Docker İçinde Ollama?

Bare-metal kurulum ilk bakışta daha basit görünse de uzun vadede bir kaç sorun çıkarıyor. Farklı Ollama versiyonları arasında geçiş yapmak zorunda kaldığınızda ya da aynı sunucuda birden fazla AI servisi çalıştırmak istediğinizde işler karmaşıklaşıyor. Docker bu noktada devreye giriyor ve şu avantajları getiriyor:

  • İzolasyon: Ollama ve bağımlılıkları sistemin geri kalanından tamamen ayrı çalışır
  • Taşınabilirlik: Geliştirme ortamında test ettiğiniz konfigürasyonu production’a birebir taşırsınız
  • Versiyon kontrolü: İki farklı Ollama versiyonunu aynı anda test edebilirsiniz
  • Temiz kaldırma: Container’ı sildiğinizde sistem üzerinde hiçbir iz kalmaz
  • Kaynak limitleri: CPU ve RAM kullanımını container seviyesinde sınırlandırabilirsiniz

Ön Gereksinimler

Başlamadan önce sistemde şunların kurulu olması gerekiyor:

  • Docker Engine 24.0 veya üzeri
  • Docker Compose v2 (önerilir)
  • GPU kullanacaksanız NVIDIA Container Toolkit (aşağıda detaylı ele alacağız)
  • En az 8GB RAM (küçük modeller için), 16GB+ (7B ve üzeri modeller için)

Docker kurulumunu doğrulamak için:

docker --version
docker compose version
docker run hello-world

CPU ile Temel Kurulum

En hızlı başlangıç noktası resmi Ollama image’ını doğrudan çalıştırmak. GPU olmadan da birçok model çalışıyor, sadece yanıt süreleri daha uzun oluyor.

docker run -d 
  --name ollama 
  -p 11434:11434 
  -v ollama_data:/root/.ollama 
  --restart unless-stopped 
  ollama/ollama:latest

Bu komutla ne yaptık:

  • -d: Arka planda çalıştır
  • –name ollama: Container’a anlamlı bir isim ver
  • -p 11434:11434: API portunu dışarı aç
  • -v ollama_data:/root/.ollama: Model verilerini kalıcı volume’a kaydet
  • –restart unless-stopped: Sunucu yeniden başladığında otomatik çalışsın

Container çalışıyor mu kontrol edelim:

docker ps | grep ollama
docker logs ollama --tail 20

Şimdi bir model çekelim ve test edelim:

# Container içinde model indir
docker exec -it ollama ollama pull llama3.2:3b

# Hızlı test
docker exec -it ollama ollama run llama3.2:3b "Merhaba, kim olduğunu bir cümlede anlat"

# API üzerinden test
curl http://localhost:11434/api/generate 
  -d '{"model": "llama3.2:3b", "prompt": "Docker nedir?", "stream": false}'

GPU Desteği: NVIDIA Container Toolkit

GPU desteği olmadan LLM çalıştırmak mümkün ama ciddi bir performans kaybı yaşarsınız. 7B parametreli bir modelde CPU ile 2-5 token/saniye alırken GPU ile 30-80 token/saniye bandına çıkabilirsiniz.

Önce NVIDIA Container Toolkit kurulumunu yapıyoruz:

# Repository ekle
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | 
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | 
  sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | 
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

# Kur
sudo apt update
sudo apt install -y nvidia-container-toolkit

# Docker'ı yeniden yapılandır
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

GPU erişimini test et:

docker run --rm --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi

Bu komut GPU bilgilerini gösteriyorsa her şey yolunda. Şimdi Ollama’yı GPU desteğiyle çalıştıralım:

docker run -d 
  --name ollama-gpu 
  --gpus all 
  -p 11434:11434 
  -v ollama_data:/root/.ollama 
  --restart unless-stopped 
  ollama/ollama:latest

Belirli bir GPU’yu atamak için --gpus '"device=0"' şeklinde de kullanabilirsiniz. Birden fazla GPU’nuz varsa ve yükü dağıtmak istiyorsanız --gpus '"device=0,1"' ile iki GPU’yu birlikte kullanabilirsiniz.

Docker Compose ile Yapılandırma

Production ortamı için docker run komutları yerine Docker Compose kullanmak çok daha iyi bir pratik. Konfigürasyonu versiyon kontrolüne alabilir, kolay güncelleyebilir ve başka servislerle birlikte yönetebilirsiniz.

mkdir -p /opt/ollama
cd /opt/ollama
nano docker-compose.yml
# docker-compose.yml
services:
  ollama:
    image: ollama/ollama:latest
    container_name: ollama
    restart: unless-stopped
    ports:
      - "127.0.0.1:11434:11434"
    volumes:
      - ollama_data:/root/.ollama
      - ./modelfiles:/modelfiles
    environment:
      - OLLAMA_HOST=0.0.0.0
      - OLLAMA_KEEP_ALIVE=24h
      - OLLAMA_NUM_PARALLEL=2
      - OLLAMA_MAX_LOADED_MODELS=2
    deploy:
      resources:
        limits:
          memory: 16G
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:11434/api/version"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    restart: unless-stopped
    ports:
      - "3000:8080"
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
    volumes:
      - open_webui_data:/app/backend/data
    depends_on:
      ollama:
        condition: service_healthy

volumes:
  ollama_data:
    driver: local
  open_webui_data:
    driver: local

Dikkat edin, port binding’i 127.0.0.1:11434:11434 olarak ayarladım. Bu şekilde Ollama API’si doğrudan internete açılmıyor, sadece localhost üzerinden erişilebiliyor. Güvenlik açısından önemli bir detay.

Ortamı başlat:

docker compose up -d
docker compose ps
docker compose logs -f ollama

Ortam Değişkenleri ile İnce Ayar

Ollama’nın davranışını kontrol eden birkaç kritik ortam değişkeni var:

  • OLLAMA_HOST: Dinlenecek adres ve port (varsayılan: 127.0.0.1:11434)
  • OLLAMA_KEEP_ALIVE: Model bellekte ne kadar süre kalsın (örn: 5m, 1h, 24h, -1 = süresiz)
  • OLLAMA_NUM_PARALLEL: Eş zamanlı istek sayısı
  • OLLAMA_MAX_LOADED_MODELS: Aynı anda bellekte tutulacak maksimum model sayısı
  • OLLAMA_FLASH_ATTENTION: Flash attention aktif et (GPU bellek optimizasyonu)
  • OLLAMA_GPU_MEMORY_FRACTION: GPU belleğinin ne kadarını kullan (0.0-1.0)
  • OLLAMA_DEBUG: Debug logları aktif et

OLLAMA_KEEP_ALIVE değeri özellikle dikkat gerektiriyor. Varsayılan değer 5 dakika, yani 5 dakika istek gelmezse model bellekten kaldırılıyor. Bir sonraki istekte tekrar yüklenmesi zaman alıyor. Sürekli kullanım senaryolarında bu değeri artırmak mantıklı.

Özel Model Oluşturma: Modelfile Kullanımı

Ollama’nın güçlü özelliklerinden biri özel model konfigürasyonları oluşturabilmek. Bir sistem prompt’u eklemek, parametreleri değiştirmek ya da fine-tuned bir model kullanmak için Modelfile kullanıyorsunuz.

Önce modelfiles dizinini oluşturalım ve bir örnek yazalım:

mkdir -p /opt/ollama/modelfiles
cat > /opt/ollama/modelfiles/turkce-asistan << 'EOF'
FROM llama3.2:3b

PARAMETER temperature 0.7
PARAMETER top_p 0.9
PARAMETER num_ctx 4096
PARAMETER repeat_penalty 1.1

SYSTEM """
Sen Türkçe konuşan yardımcı bir yapay zeka asistanısın. 
Her zaman Türkçe yanıt ver. 
Teknik konularda pratik ve anlaşılır açıklamalar yap.
Kod örnekleri verirken her zaman açıklama ekle.
"""
EOF

Container içinde bu Modelfile’dan yeni bir model oluştur:

# Modelfile'ı container içine kopyala
docker exec ollama mkdir -p /modelfiles

# Model oluştur
docker exec ollama ollama create turkce-asistan -f /modelfiles/turkce-asistan

# Çalışıp çalışmadığını test et
docker exec -it ollama ollama run turkce-asistan "Linux'ta disk kullanımını nasıl kontrol ederim?"

# Oluşturulan modeli listele
docker exec ollama ollama list

Model Yönetimi ve Otomasyon

Yeni bir sunucu kurduğunuzda modelleri tek tek çekmek zahmetli oluyor. Bu işlemi otomatize eden bir script hazırlayalım:

#!/bin/bash
# /opt/ollama/scripts/init-models.sh

set -e

OLLAMA_HOST="http://localhost:11434"
MODELS=(
  "llama3.2:3b"
  "llama3.2:7b"
  "mistral:7b"
  "nomic-embed-text:latest"
)

echo "Ollama servisi bekleniyor..."
until curl -sf "$OLLAMA_HOST/api/version" > /dev/null; do
  sleep 2
done
echo "Ollama hazır."

for model in "${MODELS[@]}"; do
  echo "Model indiriliyor: $model"
  if docker exec ollama ollama list | grep -q "${model%%:*}"; then
    echo "$model zaten mevcut, atlanıyor."
  else
    docker exec ollama ollama pull "$model"
    echo "$model başarıyla indirildi."
  fi
done

# Özel modeli oluştur
echo "Özel model oluşturuluyor..."
docker exec ollama ollama create turkce-asistan 
  -f /modelfiles/turkce-asistan 2>/dev/null || true

echo "Tüm modeller hazır."
docker exec ollama ollama list
chmod +x /opt/ollama/scripts/init-models.sh
bash /opt/ollama/scripts/init-models.sh

Nginx ile Reverse Proxy

Ollama API’sini dışarıya açmak istiyorsanız, doğrudan port expose etmek yerine Nginx arkasına almanız şart. Hem SSL terminasyonu hem de rate limiting ekleyebilirsiniz.

# /etc/nginx/conf.d/ollama.conf
server {
    listen 443 ssl;
    server_name ollama.sirketiniz.com;

    ssl_certificate /etc/letsencrypt/live/ollama.sirketiniz.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ollama.sirketiniz.com/privkey.pem;

    # Rate limiting
    limit_req_zone $binary_remote_addr zone=ollama_api:10m rate=10r/m;
    limit_req zone=ollama_api burst=20 nodelay;

    # Temel auth (opsiyonel ama önerilir)
    auth_basic "Ollama API";
    auth_basic_user_file /etc/nginx/.htpasswd;

    location / {
        proxy_pass http://127.0.0.1:11434;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_read_timeout 300s;
        proxy_connect_timeout 75s;
        
        # Streaming yanıtlar için
        proxy_buffering off;
        proxy_cache off;
        chunked_transfer_encoding on;
    }
}

Streaming yanıtlar için proxy_buffering off kritik. Bu ayar olmadan model yanıtları tek seferde geliyor, gerçek zamanlı akış çalışmıyor.

Yedekleme ve Taşıma

Model verilerini yedeklemek için Docker volume’u export edebilirsiniz. Modeller büyük (genellikle 2-30GB arası) olduğundan bu işlem zaman alıyor:

# Volume'u tar olarak dışa aktar
docker run --rm 
  -v ollama_data:/data 
  -v /backup:/backup 
  alpine tar czf /backup/ollama-data-$(date +%Y%m%d).tar.gz -C /data .

# Başka bir sunucuya restore et
docker run --rm 
  -v ollama_data:/data 
  -v /backup:/backup 
  alpine tar xzf /backup/ollama-data-20241215.tar.gz -C /data

# Boyut kontrolü
du -sh /backup/ollama-data-*.tar.gz

Tüm modelleri yeniden çekmek yerine bu yedekleme yöntemini kullanmak, özellikle yavaş internet bağlantısı olan sunucularda çok zaman kazandırıyor.

İzleme ve Sorun Giderme

Container’ın sağlıklı çalışıp çalışmadığını izlemek için birkaç pratik komut:

# Gerçek zamanlı log takibi
docker compose logs -f ollama

# Container kaynak kullanımı
docker stats ollama --no-stream

# GPU kullanımını izle (NVIDIA)
watch -n 1 nvidia-smi

# Yüklü modelleri listele
docker exec ollama ollama list

# Çalışan modelleri görüntüle
curl http://localhost:11434/api/ps | python3 -m json.tool

# Bellek içindeki modelleri temizle
curl -X DELETE http://localhost:11434/api/delete 
  -d '{"name": "llama3.2:3b"}'

Sık karşılaşılan sorunlar ve çözümleri:

  • “no space left on device” hatası: Model volume’unun dolduğu anlamına geliyor. docker volume inspect ollama_data ile nerede tutulduğunu bulun ve disk alanı açın.
  • GPU bulunamıyor: nvidia-ctk runtime configure --runtime=docker komutunu çalıştırmayı ve Docker’ı yeniden başlatmayı deneyin.
  • Yavaş yanıt süreleri: OLLAMA_NUM_PARALLEL değerini 1’e düşürün, paralel istekler GPU belleğini paylaştığı için tek istek daha hızlı tamamlanır.
  • Container sürekli restart oluyor: docker logs ollama --tail 50 ile son logları inceleyin. Genellikle yetersiz RAM ya da GPU bellek hatası çıkıyor.
  • Model yükleme takılıyor: Model dosyası bozulmuş olabilir. docker exec ollama ollama rm model-adi ile silip yeniden çekin.

Güvenlik Notları

Ollama varsayılan kurulumda herhangi bir kimlik doğrulama mekanizması içermiyor. Bu nedenle:

  • Ollama portunu (11434) asla doğrudan internete açmayın
  • Nginx veya Traefik arkasında çalıştırın, mutlaka kimlik doğrulama ekleyin
  • İç ağda bile kullanıyorsanız firewall kurallarıyla erişimi kısıtlayın
  • Docker Compose’daki port binding’ini 127.0.0.1:11434:11434 olarak bırakın

Sonuç

Docker içinde Ollama çalıştırmak, yerel LLM altyapınızı yönetmenin en temiz yolu. CPU kurulumundan başlayıp GPU desteği eklemeye, özel model oluşturmadan üretim ortamı yapılandırmasına kadar adım adım ilerledik. Bu yapı üzerine Open WebUI gibi arayüzler, LangChain entegrasyonları ya da özel API wrapper’lar inşa edebilirsiniz.

Pratik tavsiye olarak şunu söyleyeyim: İlk kurulumda mutlaka volume yönetimine dikkat edin. Modelleri container içinde bırakıp container’ı yeniden oluşturduğunuzda tüm modelleri kaybetmek sinir bozucu bir deneyim. Volume tanımlamasını doğru yaptığınızdan emin olun, her şey onun üzerine kuruluyor.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir