gijl commited on
Commit
329c852
·
verified ·
1 Parent(s): 475e27b

Upload 2 files

Browse files
Files changed (2) hide show
  1. Dockerfile +25 -0
  2. run.sh +171 -0
Dockerfile ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # استخدام الصورة المدمجة الرسمية
2
+ FROM ghcr.io/open-webui/open-webui:ollama
3
+
4
+ # إعداد وتوجيه كافة متغيرات البيئة إلى المخزن الدائم
5
+ ENV OLLAMA_MODELS=/data/ollama
6
+ ENV DATA_DIR=/data/webui
7
+ ENV HF_HOME=/data/.hf_cache
8
+ ENV PORT=7860
9
+ ENV HOST=0.0.0.0
10
+ ENV OLLAMA_BASE_URL=http://localhost:11434
11
+
12
+ # السطر الأهم: إجبار Ollama على إبقاء النماذج محملة في الذاكرة دائماً
13
+ ENV OLLAMA_KEEP_ALIVE=-1
14
+
15
+ # تثبيت curl للفحص الذكي، وتحديث أداة huggingface_hub مع تنظيف المخلفات لتقليص الحجم
16
+ RUN apt-get update && apt-get install -y curl && \
17
+ pip install --no-cache-dir -U huggingface_hub && \
18
+ rm -rf /var/lib/apt/lists/*
19
+
20
+ # نسخ سكريبت التشغيل وضبط الصلاحيات
21
+ COPY run.sh /app/run.sh
22
+ RUN chmod +x /app/run.sh
23
+
24
+ # نقطة الانطلاق السليمة
25
+ CMD ["/app/run.sh"]
run.sh ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ # ============================================================
5
+ # المتغيرات الأساسية
6
+ # ============================================================
7
+ MODELS_DIR="/data/models"
8
+ MODEL_FILE="gemma-4-E2B-it-UD-Q5_K_XL.gguf"
9
+ OLLAMA_MODEL_NAME="my-gemma"
10
+ OLLAMA_URL="http://localhost:11434"
11
+ HEARTBEAT_INTERVAL=120 # إرسال نبضة كل 120 ثانية للإبقاء على النموذج محملاً
12
+ MAX_WAIT=60 # أقصى انتظار لـ Ollama بالثواني
13
+
14
+ # ============================================================
15
+ # دالة التسجيل الموحّد مع الطابع الزمني
16
+ # ============================================================
17
+ log() {
18
+ echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
19
+ }
20
+
21
+ # ============================================================
22
+ # إنشاء المجلدات المطلوبة
23
+ # ============================================================
24
+ mkdir -p "$MODELS_DIR" /data/ollama /data/webui
25
+
26
+ # ============================================================
27
+ # تشغيل Ollama في الخلفية مع إعادة التشغيل التلقائي عند الفشل
28
+ # ============================================================
29
+ start_ollama() {
30
+ log "Starting Ollama server..."
31
+ OLLAMA_MODELS=/data/ollama ollama serve >> /data/ollama.log 2>&1 &
32
+ echo $!
33
+ }
34
+
35
+ wait_for_ollama() {
36
+ local waited=0
37
+ log "Waiting for Ollama to be ready..."
38
+ until curl -sf "$OLLAMA_URL/api/tags" > /dev/null 2>&1; do
39
+ if [ $waited -ge $MAX_WAIT ]; then
40
+ log "ERROR: Ollama did not start within ${MAX_WAIT}s. Check /data/ollama.log"
41
+ return 1
42
+ fi
43
+ sleep 2
44
+ waited=$((waited + 2))
45
+ done
46
+ log "Ollama is ready after ${waited}s."
47
+ }
48
+
49
+ # ============================================================
50
+ # تنزيل النموذج إن لم يكن موجوداً
51
+ # ============================================================
52
+ download_model() {
53
+ if [ ! -f "$MODELS_DIR/$MODEL_FILE" ]; then
54
+ log "Model not found. Downloading from HuggingFace..."
55
+ huggingface-cli download gijl/gemma-4-E2B-it-GGUF "$MODEL_FILE" \
56
+ --local-dir "$MODELS_DIR" \
57
+ --local-dir-use-symlinks False
58
+
59
+ huggingface-cli download gijl/gemma-4-E2B-it-GGUF mmproj-BF16.gguf \
60
+ --local-dir "$MODELS_DIR" \
61
+ --local-dir-use-symlinks False
62
+
63
+ log "Download complete."
64
+ else
65
+ log "Model already exists. Skipping download."
66
+ fi
67
+ }
68
+
69
+ # ============================================================
70
+ # إنشاء Modelfile وتسجيل النموذج في Ollama
71
+ # ============================================================
72
+ register_model() {
73
+ # إعادة التسجيل دائماً للتأكد من تطابق الإعدادات
74
+ log "Creating Modelfile..."
75
+ cat > "$MODELS_DIR/Modelfile" <<EOF
76
+ FROM $MODELS_DIR/$MODEL_FILE
77
+
78
+ PARAMETER num_ctx 8192
79
+ PARAMETER num_thread 2
80
+ PARAMETER num_keep -1
81
+ EOF
82
+
83
+ log "Registering model with Ollama..."
84
+ if ollama create "$OLLAMA_MODEL_NAME" -f "$MODELS_DIR/Modelfile"; then
85
+ log "Model registered successfully."
86
+ else
87
+ log "ERROR: Failed to register model."
88
+ return 1
89
+ fi
90
+ }
91
+
92
+ # ============================================================
93
+ # تحميل النموذج في الذاكرة مع keep_alive = -1
94
+ # ============================================================
95
+ preload_model() {
96
+ log "Preloading model into memory (keep_alive=-1)..."
97
+ local response
98
+ response=$(curl -sf -X POST "$OLLAMA_URL/api/generate" \
99
+ -H "Content-Type: application/json" \
100
+ -d "{\"model\": \"$OLLAMA_MODEL_NAME\", \"prompt\": \"\", \"keep_alive\": -1}" 2>&1) || true
101
+
102
+ if echo "$response" | grep -q "error"; then
103
+ log "WARNING: Preload returned an error: $response"
104
+ else
105
+ log "Model preloaded successfully."
106
+ fi
107
+ }
108
+
109
+ # ============================================================
110
+ # دالة النبضة القلبية: تُشغَّل في الخلفية لإبقاء النموذج حياً
111
+ # وتعيد تشغيل Ollama تلقائياً إن سقط
112
+ # ============================================================
113
+ heartbeat_loop() {
114
+ log "Heartbeat loop started (interval: ${HEARTBEAT_INTERVAL}s)."
115
+ while true; do
116
+ sleep "$HEARTBEAT_INTERVAL"
117
+
118
+ # التحقق من أن Ollama لا يزال يعمل
119
+ if ! curl -sf "$OLLAMA_URL/api/tags" > /dev/null 2>&1; then
120
+ log "WARNING: Ollama is not responding. Restarting..."
121
+ start_ollama
122
+ sleep 5
123
+ wait_for_ollama || continue
124
+ preload_model
125
+ continue
126
+ fi
127
+
128
+ # إرسال طلب فارغ للإبقاء على النموذج محملاً في الذاكرة
129
+ local status
130
+ status=$(curl -sf -o /dev/null -w "%{http_code}" \
131
+ -X POST "$OLLAMA_URL/api/generate" \
132
+ -H "Content-Type: application/json" \
133
+ -d "{\"model\": \"$OLLAMA_MODEL_NAME\", \"prompt\": \"\", \"keep_alive\": -1}" 2>/dev/null) || status="000"
134
+
135
+ if [ "$status" = "200" ]; then
136
+ log "Heartbeat OK — model is alive in memory."
137
+ else
138
+ log "WARNING: Heartbeat failed (HTTP $status). Attempting reload..."
139
+ preload_model
140
+ fi
141
+ done
142
+ }
143
+
144
+ # ============================================================
145
+ # التنظيف عند إيقاف الحاوية (SIGTERM / SIGINT)
146
+ # ============================================================
147
+ cleanup() {
148
+ log "Shutdown signal received. Stopping services gracefully..."
149
+ kill "$HEARTBEAT_PID" 2>/dev/null || true
150
+ kill "$OLLAMA_PID" 2>/dev/null || true
151
+ log "Cleanup done. Goodbye."
152
+ exit 0
153
+ }
154
+ trap cleanup SIGTERM SIGINT
155
+
156
+ # ============================================================
157
+ # التسلسل الرئيسي للتشغيل
158
+ # ============================================================
159
+ OLLAMA_PID=$(start_ollama)
160
+ wait_for_ollama
161
+ download_model
162
+ register_model
163
+ preload_model
164
+
165
+ # تشغيل حلقة النبضة في الخلفية
166
+ heartbeat_loop &
167
+ HEARTBEAT_PID=$!
168
+
169
+ log "All services up. Starting Open WebUI..."
170
+ cd /app/backend
171
+ exec bash start.sh