الدرس 20 من 22

النشر للإنتاج

نشر Docker

3 دقيقة للقراءة

انشر Ollama في حاويات لبنية تحتية محلية لنماذج اللغة قابلة للتكرار، معزولة، وقابلة للتوسع.

لماذا Docker لـ Ollama؟

┌─────────────────────────────────────────────────────────────────┐
│                   فوائد نشر Docker                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  الفائدة           │ الوصف                                      │
│  ───────────────────│──────────────────────────────────────     │
│  العزل             │ منفصل عن نظام المضيف                       │
│  قابلية التكرار   │ نفس البيئة في كل مكان                      │
│  تمرير GPU         │ وصول كامل لـ GPU في الحاوية               │
│  سهولة التحديث    │ اسحب صورة جديدة، أعد التشغيل               │
│  حدود الموارد      │ تحكم في CPU، الذاكرة، تخصيص GPU           │
│  التنسيق          │ يعمل مع Kubernetes، Swarm                  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

إعداد Docker الأساسي لـ Ollama

# شغّل حاوية Ollama (CPU فقط)
docker run -d \
  --name ollama \
  -p 11434:11434 \
  -v ollama:/root/.ollama \
  ollama/ollama

# اسحب نموذج داخل الحاوية
docker exec ollama ollama pull llama3.2

# اختبر API
curl http://localhost:11434/api/generate -d '{
  "model": "llama3.2",
  "prompt": "مرحباً من Docker!",
  "stream": false
}'

Docker مع GPU (NVIDIA)

# ثبّت NVIDIA Container Toolkit أولاً
# https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html

# شغّل بدعم GPU
docker run -d \
  --name ollama-gpu \
  --gpus all \
  -p 11434:11434 \
  -v ollama:/root/.ollama \
  ollama/ollama

# تحقق أن GPU متاح
docker exec ollama-gpu nvidia-smi

تكوين Docker Compose

# docker-compose.yml
version: '3.8'

services:
  ollama:
    image: ollama/ollama:latest
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
      - ./models:/models  # اختياري: ربط نماذج محلية
    environment:
      - OLLAMA_KEEP_ALIVE=24h
      - OLLAMA_NUM_PARALLEL=4
      - OLLAMA_MAX_LOADED_MODELS=2
    restart: unless-stopped
    # ألغِ التعليق لدعم GPU
    # deploy:
    #   resources:
    #     reservations:
    #       devices:
    #         - driver: nvidia
    #           count: all
    #           capabilities: [gpu]

volumes:
  ollama_data:
# ابدأ الحزمة
docker compose up -d

# اعرض السجلات
docker compose logs -f ollama

# أوقف
docker compose down

تحميل النماذج مسبقاً عند البدء

# docker-compose.yml مع تحميل النماذج مسبقاً
version: '3.8'

services:
  ollama:
    image: ollama/ollama:latest
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
    restart: unless-stopped

  # حاوية تهيئة لسحب النماذج
  ollama-init:
    image: ollama/ollama:latest
    container_name: ollama-init
    depends_on:
      - ollama
    entrypoint: >
      /bin/sh -c "
        sleep 5 &&
        ollama pull llama3.2 &&
        ollama pull nomic-embed-text &&
        echo 'النماذج جاهزة!'
      "
    environment:
      - OLLAMA_HOST=ollama:11434
    restart: "no"

volumes:
  ollama_data:

Dockerfile مخصص مع النماذج

# Dockerfile.ollama
FROM ollama/ollama:latest

# عيّن البيئة
ENV OLLAMA_KEEP_ALIVE=24h
ENV OLLAMA_NUM_PARALLEL=4

# انسخ Modelfiles المخصصة
COPY modelfiles/ /modelfiles/

# أنشئ سكربت نقطة الدخول
COPY <<EOF /entrypoint.sh
#!/bin/bash
ollama serve &
sleep 5

# اسحب النماذج الأساسية
ollama pull llama3.2
ollama pull nomic-embed-text

# أنشئ نماذج مخصصة من Modelfiles
for f in /modelfiles/*.Modelfile; do
  name=\$(basename \$f .Modelfile)
  ollama create \$name -f \$f
done

# أبقِ الحاوية تعمل
wait
EOF

RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
# ابنِ صورة مخصصة
docker build -f Dockerfile.ollama -t my-ollama:latest .

# شغّل بنماذج محمّلة مسبقاً
docker run -d --name my-ollama -p 11434:11434 my-ollama:latest

فحوصات الصحة

# docker-compose.yml مع فحص الصحة
services:
  ollama:
    image: ollama/ollama:latest
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:11434/api/version"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    restart: unless-stopped

عميل Python لـ Ollama في Docker

import ollama
import os

# كوّن العميل لنشر Docker
client = ollama.Client(
    host=os.getenv("OLLAMA_HOST", "http://localhost:11434")
)

def check_ollama_health():
    """تحقق إذا كانت حاوية Ollama سليمة."""
    try:
        # قائمة النماذج للتحقق من الاتصال
        models = client.list()
        return {
            "healthy": True,
            "models": [m["name"] for m in models.get("models", [])]
        }
    except Exception as e:
        return {"healthy": False, "error": str(e)}

def ensure_model(model_name: str):
    """تأكد أن النموذج متاح، اسحب إذا لزم."""
    try:
        client.show(model_name)
        return True
    except:
        print(f"سحب {model_name}...")
        client.pull(model_name)
        return True

# الاستخدام
health = check_ollama_health()
print(f"Ollama سليم: {health['healthy']}")

if health["healthy"]:
    ensure_model("llama3.2")
    response = client.generate(model="llama3.2", prompt="مرحباً من Python!")
    print(response["response"])

حدود الموارد

# docker-compose.yml مع حدود الموارد
services:
  ollama:
    image: ollama/ollama:latest
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
    deploy:
      resources:
        limits:
          cpus: '4'
          memory: 16G
        reservations:
          cpus: '2'
          memory: 8G
          # حجز GPU
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

تطبيق متعدد الحاويات

# حزمة كاملة مع Ollama، API، وواجهة
version: '3.8'

services:
  ollama:
    image: ollama/ollama:latest
    volumes:
      - ollama_data:/root/.ollama
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

  api:
    build: ./api
    ports:
      - "8000:8000"
    environment:
      - OLLAMA_HOST=http://ollama:11434
    depends_on:
      - ollama

  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    depends_on:
      - api

volumes:
  ollama_data:

اعتبارات الأمان

# إعدادات أمان جاهزة للإنتاج
services:
  ollama:
    image: ollama/ollama:latest
    ports:
      - "127.0.0.1:11434:11434"  # اربط بـ localhost فقط
    volumes:
      - ollama_data:/root/.ollama:rw
    read_only: false  # Ollama يحتاج صلاحية كتابة
    security_opt:
      - no-new-privileges:true
    # لا تشغّل كـ root في الإنتاج
    # user: "1000:1000"  # ألغِ التعليق عندما يدعمها Ollama

Docker يوفر الأساس للنشر الإنتاجي. بعد ذلك، سنستكشف استراتيجيات التوسع للتعامل مع مستخدمين متعددين. :::

اختبار

الوحدة 6: النشر للإنتاج

خذ الاختبار