النشر للإنتاج
نشر 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 يوفر الأساس للنشر الإنتاجي. بعد ذلك، سنستكشف استراتيجيات التوسع للتعامل مع مستخدمين متعددين. :::