> ## Content Index
> Fetch the complete content index at: https://arabroot.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# التعلم دون إنترنت في المدارس النائية مع Kolibri
- URL: https://arabroot.io/articles/التعلم-دون-انترنت-للمدارس-النائية-مع-kolibri/
- Published: 2026-10-14T10:00:00.000Z
- Updated: 2026-10-25T08:50:14.000Z
- Description: شغل منصة Kolibri على سيرفر المدرسة، وانقل المحتوى إلى الفصول عبر الشبكة المحلية أو ذاكرة USB، وزامن بيانات الطلاب دون إنترنت.
- Author: فريق عرب رووت
- Tags: الأدلة التقنية, التعليم والبحث العلمي, الاستضافة الذاتية, Kolibri

كل ما شرحناه في [أنظمة إدارة التعلم LMS](https://arabroot.io/articles/%D8%A7%D9%86%D8%B8%D9%85%D8%A9-%D8%A7%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D8%AA%D8%B9%D9%84%D9%85-lms-%D9%85%D8%A7%D8%B0%D8%A7-%D8%AA%D8%AD%D8%AA%D8%A7%D8%AC-%D9%85%D9%86%D9%87%D8%A7-%D9%85%D8%A4%D8%B3%D8%B3%D8%AA%D9%83/) و[دليل Moodle](https://arabroot.io/articles/%D8%AA%D8%AB%D8%A8%D9%8A%D8%AA-moodle-%D9%85%D9%86%D8%B5%D8%A9-%D8%A7%D9%84%D8%AA%D8%B9%D9%84%D9%85-%D8%B9%D9%84%D9%89-%D8%B3%D9%8A%D8%B1%D9%81%D8%B1%D9%83/) يفترض شيئاً واحداً، وهو أن الطالب يصل إلى المنصة عبر الإنترنت، أو على الأقل أن المعلم يرفع المحتوى من الإنترنت. ولكن لنفرض أن لديك مدرسة في قرية جبلية أو في منطقة صحراوية، والإنترنت فيها ضعيف ومكلف أو غير موجود، والكهرباء تنقطع أحياناً، فماذا تفعل؟ هنا يأتي Kolibri، وهو منصة تعلم مفتوحة المصدر برخصة MIT من مؤسسة [Learning Equality](https://learningequality.org/kolibri/?ref=arabroot.io)، صممت من البداية لتعمل دون إنترنت Offline-first، فتشغلها على جهاز واحد في المدرسة، ويفتحها الطلاب من أجهزتهم على الشبكة المحلية LAN، والمحتوى ينتقل إليها مرة واحدة من الإنترنت أو من ذاكرة USB.

وفي هذا المقال سوف نتناول:

- ما الذي يقدمه Kolibri، ومتى تختاره بدلاً من Moodle، ومتى لا يناسبك.
- مختبر على Docker فيه جهازان: سيرفر المدرسة الذي يصل إلى الإنترنت، وجهاز فصل على شبكة داخلية لا يصل إليه الإنترنت أبداً.
- نقل المحتوى بثلاث طرق: من الإنترنت إلى سيرفر المدرسة، ومن سيرفر المدرسة إلى الفصل عبر الشبكة المحلية، ثم عبر ذاكرة USB، مع الأحجام والأوقات التي قسناها.
- الطلاب والفصول من ملف CSV، ومزامنة بياناتهم في الاتجاهين بين الجهازين دون إنترنت.
- ثلاثة أشياء وجدناها في التجربة يجب أن تعرفها قبل أول يوم: محتوى لا يظهر للطلاب، ودخول الطلاب دون كلمة مرور، واستيراد ينتظر الإنترنت إلى الأبد.

## ما هو Kolibri، ومتى تختاره بدلاً من Moodle؟

Kolibri منصة تعلم تعمل في المتصفح، فيها جانب للطالب اسمه «تعلم» Learn يتصفح فيه المكتبة ويقرأ ويشاهد ويحل التمارين، وجانب للمعلم اسمه «التدريب» Coach ينشئ فيه الدروس Lessons والاختبارات Quizzes ويتابع تقدم الطلاب، وجانب للمدير لإدارة الجهاز والمستخدمين. والفرق الجوهري عن Moodle في مصدر المحتوى وفي الاتصال، والجدول التالي يلخص الفرق:

| السؤال                                       | Kolibri                                                                                                                                                                    | Moodle                                                         |
| -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| من أين يأتي المحتوى؟                         | قنوات Channels جاهزة من مكتبة [Kolibri Studio](https://studio.learningequality.org/?ref=arabroot.io)، أو قنوات تبنيها المؤسسة فيها                                         | المعلم يرفع ملفاته وينشئ أنشطته داخل المقرر                    |
| هل يحتاج إنترنت؟                             | مرة واحدة لجلب القناة، أو لا يحتاجه أبداً إذا جاءت القناة على USB                                                                                                          | يحتاج اتصالاً دائماً بين الطالب والسيرفر، وغالباً عبر الإنترنت |
| كيف تنتقل بيانات الطلاب؟                     | مزامنة Sync بين الأجهزة في الاتجاهين متى اتصلت ببعضها                                                                                                                      | كلها في قاعدة بيانات واحدة على السيرفر                         |
| العتاد                                       | جهاز بسيط يكفي، و[صفحة المتطلبات](https://kolibri.readthedocs.io/en/latest/install/system%5Frequirements.html?ref=arabroot.io) تذكر أن Raspberry Pi يكفي لأقل من 30 جهازاً | سيرفر حقيقي يكبر مع عدد الطلاب                                 |
| الواجبات المكتوبة والمنتديات والتقييم المفصل | محدودة، فالتركيز على المحتوى والتمارين والاختبارات القصيرة                                                                                                                 | كاملة                                                          |

لذلك فالقاعدة: إذا كان الاتصال متوفراً ومستقراً فاختر Moodle، وإذا كان الاتصال هو المشكلة فاختر Kolibri، ولا يمنع ذلك أن تشغل المؤسسة الاثنين، فالمدارس المتصلة على Moodle، والمدارس النائية على Kolibri.

## كيف يصل المحتوى إلى مدرسة بلا إنترنت؟

المحتوى في Kolibri يأتي في قنوات، والقناة حزمة فيها شجرة من المواضيع والموارد (مستندات، فيديو، تمارين)، ولها معرف من 32 حرفاً ورقم إصدار. وبعد أن تصل القناة إلى أي جهاز Kolibri، يستطيع هذا الجهاز أن يعطيها لغيره، والشكل التالي يبين الطرق الثلاث التي سوف نجربها:

![مخطط: سحابة Kolibri Studio ترسل القنوات مرة واحدة إلى سيرفر المدرسة في المدرسة الرئيسية عندما يتوفر الإنترنت، وسيرفر المدرسة يخدم أجهزة الطلاب عبر Wi-Fi محلي، ثم ينقل القنوات إلى جهاز فصل بلا إنترنت على الشبكة نفسها بالخيار baseurl، وإلى فصل بعيد بلا شبكة عبر ذاكرة USB بالأمرين exportcontent وimportcontent disk](https://arabroot.io/content/images/2026/10/kolibri-01-offline-school.webp)

الإنترنت يلزم جهازاً واحداً ومرة واحدة لكل قناة، وكل الأجهزة الأخرى تأخذ من الشبكة المحلية أو من USB

وقبل أن تختار القنوات، تصفح المكتبة العامة في Studio، فقد استعلمنا عن القنوات العربية في [واجهة Studio العامة](https://studio.learningequality.org/?ref=arabroot.io) في 21 أكتوبر 2026 فوجدنا 22 قناة، وأحجامها تختلف كثيراً، فمنها ما حجمه 4.2MB، ومنها ما يتجاوز 20GB لأنه مبني على الفيديو، لذلك احسب مساحة القرص من حجم القنوات التي تختارها وليس من حجم Kolibri نفسه، وفي المختبر اخترنا قناتين صغيرتين:

| القناة                            | المعرف                           | الموارد | الحجم في Studio |
| --------------------------------- | -------------------------------- | ------- | --------------- |
| Living Values Education (العربية) | 27bb0abc24d44dd9896be50d47b2357e | 5       | 4.2MB           |
| منظمة تعليم الطفولة الدولية       | ec9d846adc4c4e778678e7e5d5cbfee2 | 9       | 38.6MB          |

## المتطلبات

- **سيرفر المدرسة:** [صفحة المتطلبات الرسمية](https://kolibri.readthedocs.io/en/latest/install/system%5Frequirements.html?ref=arabroot.io) توصي بـ 1GB من الذاكرة على Linux و2GB أو أكثر على Windows، ومعالج 1GHz، والقرص بحسب القنوات. وفي مختبرنا كان سيرفر المدرسة يستخدم 275MB من الذاكرة بعد كل التجارب، وجهاز الفصل 182MB.
- **أجهزة الطلاب:** أي جهاز فيه متصفح حديث، أو [تطبيق Kolibri لنظام Android](https://learningequality.org/download/?ref=arabroot.io)، والصفحة نفسها تذكر أنه مجرب على Android 8 وما بعده.
- **الشبكة:** نقطة وصول Wi-Fi محلية أو Switch، ولا يلزم أن تكون متصلة بالإنترنت.
- **طريقة التثبيت في الإنتاج:** على Ubuntu وDebian من [المستودع الرسمي PPA](https://kolibri.readthedocs.io/en/latest/install/ubuntu-debian.html?ref=arabroot.io)، والصفحة نفسها توصي بالحزمة `kolibri-server` للأجهزة متعددة الأنوية لأنها تضيف ذاكرة مؤقتة للملفات الثابتة وتستخدم المعالج بشكل أفضل.

## المختبر: سيرفر المدرسة وجهاز فصل بلا إنترنت

لا يوجد Docker Image رسمي لـ Kolibri، والطريقة الرسمية الأقرب لل Container هي التثبيت بال pip، لذلك بنينا Docker Image صغيراً بالملف التالي:

```dockerfile
FROM python:3.13.16-slim
RUN pip install --no-cache-dir kolibri==0.19.5 \
 && useradd -m -u 1000 kolibri \
 && mkdir -p /home/kolibri/.kolibri /media/usb \
 && chown kolibri:kolibri /home/kolibri/.kolibri /media/usb
USER kolibri
ENV KOLIBRI_HOME=/home/kolibri/.kolibri KOLIBRI_HTTP_PORT=8080
EXPOSE 8080
CMD ["kolibri", "start", "--foreground"]
```

ولاحظ سطر `mkdir` و`chown`، فقد بنينا المرة الأولى بدونه، فرفض Kolibri العمل برسالة `PermissionError: [Errno 13] Permission denied: '/home/kolibri/.kolibri/logs'`، والسبب أن ال Volume الجديد يأخذ مالك المجلد من ال Image، والمجلد لم يكن موجوداً فيه، فأنشأه Docker مملوكاً للمستخدم root. ثم الملف `compose.yaml`:

```yaml
name: edu3-kol
services:
  school:
    image: edu3-kolibri:0.19.5
    container_name: edu3-kol-school
    networks: [internet, lan]
    ports: ["127.0.0.1:29180:8080"]
    volumes: ["school:/home/kolibri/.kolibri", "usb:/media/usb"]
    mem_limit: 1g
  classroom:
    image: edu3-kolibri:0.19.5
    container_name: edu3-kol-classroom
    networks: [lan]
    volumes: ["classroom:/home/kolibri/.kolibri", "usb:/media/usb"]
    mem_limit: 1g
networks:
  internet: { name: edu3-kol-internet }
  lan: { name: edu3-kol-lan, internal: true }
volumes:
  school: { name: edu3-kol-school }
  classroom: { name: edu3-kol-classroom }
  usb: { name: edu3-kol-usb }
```

في الإعداد أعلاه لاحظ التالي:

- **الشبكة `lan` داخلية `internal: true`:** Docker لا يعطي ال Containers على هذه الشبكة أي طريق إلى الخارج، فجهاز الفصل `classroom` لا يصل إلى الإنترنت فعلاً، ويصل إلى سيرفر المدرسة فقط، وهذا هو الفصل في القرية.
- **سيرفر المدرسة على الشبكتين:** `internet` ليجلب القنوات من Studio، و`lan` ليخدم الفصل.
- **ال Volume `usb`:** مربوط بالجهازين، ويقوم بدور ذاكرة USB ينقلها المعلم من المدرسة إلى الفصل البعيد.
- **قاعدة البيانات:** Kolibri يستخدم SQLite افتراضياً داخل `KOLIBRI_HOME`، فكل بيانات الجهاز في مجلد واحد، وهذا ما يجعل النسخ الاحتياطي بسيطاً كما سيأتي.

```bash
docker build -t edu3-kolibri:0.19.5 .
docker compose up -d
```

### تجهيز الجهاز بالعربية

في المتصفح يظهر معالج الإعداد Setup Wizard عند أول فتح، ومن سطر الأوامر نستخدم `provisiondevice`، فننشئ المرفق التعليمي Facility، وهو في Kolibri المدرسة أو المركز الذي ينتمي إليه المستخدمون، ونختار اللغة العربية والإعداد المسبق `formal` المخصص للمدارس:

```bash
docker exec edu3-kol-school kolibri manage --skip-update provisiondevice \
  --facility "مدرسة الوادي" --superusername admin --superuserpassword 'Lab-Admin-2026!' \
  --preset formal --language_id ar --noinput
```

```text
WARNING  The 'provisiondevice' command is experimental, and the API and behavior will change in a future release
```

والتحذير صريح، فإذا كتبت سكربتاً يجهز عشرات الأجهزة بهذا الأمر فاختبره مع كل إصدار جديد. والخيار `--skip-update` يمنع الأمر من تشغيل إجراءات الترقية في كل مرة، فقد طبع أول أمر شغلناه قبل أن ينتهي تشغيل السيرفر عشرات الأسطر من الترحيل Migrations وتحديث الإضافات.

### الطريقة الأولى: من الإنترنت إلى سيرفر المدرسة

الاستيراد خطوتان، الأولى تجلب قاعدة بيانات القناة، أي الشجرة والعناوين والأوصاف، والثانية تجلب الملفات نفسها، و[صفحة سطر الأوامر](https://kolibri.readthedocs.io/en/latest/manage/command%5Fline.html?ref=arabroot.io) تنبه أن المعرف هو المعرف ذو 32 حرفاً وليس رمز القناة Token:

```bash
docker exec edu3-kol-school kolibri manage --skip-update importchannel network 27bb0abc24d44dd9896be50d47b2357e
docker exec edu3-kol-school kolibri manage --skip-update importcontent network 27bb0abc24d44dd9896be50d47b2357e
docker exec edu3-kol-school kolibri manage --skip-update listchannels
```

```text
Pos       ID                                      Name
---       --                                      ----
1         27bb0abc24d44dd9896be50d47b2357e        Living Values Education (العربيّة)
```

واستغرقت الخطوتان 19 ثانية و21 ثانية، وأغلب هذا الوقت بدء تشغيل الأمر نفسه، فالملفات 4.1MB في خمسة ملفات. ثم استوردنا القناة الثانية بالطريقة نفسها في 31 ثانية للخطوتين، والسجل أكد أن 15 ملفاً أصبحت متاحة.

### ماذا يحدث إذا حاول الفصل الاستيراد من الإنترنت؟

قبل أن نوجه جهاز الفصل إلى سيرفر المدرسة، شغلنا عليه الأمر نفسه كما هو، وهو ما سيفعله أي شخص ينسخ الأوامر من دليل:

```bash
docker exec edu3-kol-classroom kolibri manage --skip-update importchannel network 27bb0abc24d44dd9896be50d47b2357e
```

لم يفشل الأمر ولم ينته، وبقي ينتظر، وهذا ما وجدناه في سجل Kolibri:

```text
ERROR 2026-10-21 20:46:39,153 kolibri.utils.file_transfer Error reading download stream: HTTPSConnectionPool(host='studio.learningequality.org', port=443): Max retries exceeded with url: /content/databases/27bb0abc24d44dd9896be50d47b2357e.sqlite3 (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7fa1eb71de80>: Failed to establish a new connection: [Errno -3] Temporary failure in name resolution'))
INFO 2026-10-21 20:46:39,182 kolibri.utils.file_transfer Waiting 30s before retrying import: https://studio.learningequality.org/content/databases/27bb0abc24d44dd9896be50d47b2357e.sqlite3
```

بعد 22 دقيقة كان في السجل 46 محاولة، كل واحدة بعد 30 ثانية من سابقتها، فأوقفنا الأمر بأنفسنا. وهذا السلوك مفيد في مدرسة ينقطع فيها الإنترنت دقائق ثم يعود، لأن الاستيراد يكمل وحده، ولكنه مضلل في مدرسة لا يوجد فيها إنترنت أصلاً، لأن الشاشة لا تقول شيئاً. لذلك إذا بدا لك أن الاستيراد متوقف فلا تنتظر، وافتح السجل `$KOLIBRI_HOME/logs/kolibri.txt` وابحث عن `Waiting 30s before retrying`.

### الطريقة الثانية: من سيرفر المدرسة عبر الشبكة المحلية

الأمر نفسه، مع الخيار `--baseurl` الذي يوجه الاستيراد إلى أي جهاز Kolibri على الشبكة بدلاً من Studio:

```bash
docker exec edu3-kol-classroom kolibri manage --skip-update importchannel network 27bb0abc24d44dd9896be50d47b2357e --baseurl http://edu3-kol-school:8080/
docker exec edu3-kol-classroom kolibri manage --skip-update importcontent network 27bb0abc24d44dd9896be50d47b2357e --baseurl http://edu3-kol-school:8080/
```

```text
INFO     2026-10-21 21:11:19,329 Channel 27bb0abc24d44dd9896be50d47b2357e successfully imported into the database
INFO     2026-10-21 21:11:33,378 Invoking command importcontent network 27bb0abc24d44dd9896be50d47b2357e --baseurl http://edu3-kol-school:8080/
INFO     2026-10-21 21:11:34,607 Attempting connections to variations of the URL: http://edu3-kol-school:8080/
INFO     2026-10-21 21:11:34,722 Attempting connection to: http://edu3-kol-school:8080/
INFO     2026-10-21 21:11:35,536 Success! We connected to: http://edu3-kol-school:8080/api/public/info/?v=3
```

واستغرقت الخطوتان 20 ثانية و18 ثانية، وأصبح في مجلد المحتوى على جهاز الفصل 4.1MB، أي الملفات نفسها التي في سيرفر المدرسة، دون أن يخرج الجهاز إلى الإنترنت. وفي الإنتاج يكون العنوان عنوان سيرفر المدرسة على الشبكة المحلية، مثل `http://192.168.1.10:8080/`، ومن الواجهة تجد السيرفر في قائمة الأجهزة المجاورة عند الاستيراد، بشرط ألا يمنعه جدار حماية Firewall كما تنبه [صفحة المرافق](https://kolibri.readthedocs.io/en/latest/manage/facilities.html?ref=arabroot.io).

### الطريقة الثالثة: عبر ذاكرة USB

للفصل البعيد الذي لا تصله شبكة المدرسة، نصدر القناة من سيرفر المدرسة إلى ذاكرة USB، ثم نستوردها في الجهاز البعيد من القرص:

```bash
docker exec edu3-kol-school kolibri manage --skip-update exportchannel ec9d846adc4c4e778678e7e5d5cbfee2 /media/usb/KOLIBRI_DATA
docker exec edu3-kol-school kolibri manage --skip-update exportcontent ec9d846adc4c4e778678e7e5d5cbfee2 /media/usb/KOLIBRI_DATA
docker exec edu3-kol-school sh -c 'du -sh /media/usb/KOLIBRI_DATA; ls /media/usb/KOLIBRI_DATA/content'
```

```text
37M	/media/usb/KOLIBRI_DATA
databases
manifest.json
storage
```

```bash
docker exec edu3-kol-classroom kolibri manage --skip-update importchannel disk ec9d846adc4c4e778678e7e5d5cbfee2 /media/usb/KOLIBRI_DATA
docker exec edu3-kol-classroom kolibri manage --skip-update importcontent disk ec9d846adc4c4e778678e7e5d5cbfee2 /media/usb/KOLIBRI_DATA
```

```text
INFO     2026-10-21 21:17:15,513 Channel ec9d846adc4c4e778678e7e5d5cbfee2 successfully imported into the database
```

في الأوامر أعلاه لاحظ التالي:

- استغرق التصدير 51 ثانية والاستيراد 45 ثانية، وأصبح مجلد المحتوى في جهاز الفصل 41MB، أي القناتين معاً.
- داخل `KOLIBRI_DATA` أنشأ Kolibri مجلد `content` وفيه ملف `manifest.json` الذي يحدد ما الذي صدرناه من القناة، وصفحة سطر الأوامر تطلب أن يكون `KOLIBRI_DATA` في المجلد الرئيسي للذاكرة، مثل `Z:\KOLIBRI_DATA` على Windows، حتى تجده الواجهة تلقائياً.
- ذاكرة واحدة تكفي لعدة قنوات، فالتصدير يضيف إلى ما فيها، فجهز ذاكرة لكل مدرسة نائية بالقنوات التي تحتاجها، وحدثها في كل زيارة.

والصورة التالية لقائمة القنوات في سيرفر المدرسة كما يراها المدير، وفيها حجم كل قناة على القرص:

![صفحة الجهاز في Kolibri بالعربية، تبويب القنوات التعليمية، وفيها قناتان: Living Values Education العربية بالإصدار 4 وحجم 4 ميغا بايت وخمسة موارد، ومنظمة تعليم الطفولة الدولية بالإصدار 4 وحجم 38 ميغا بايت، وأمام كل منهما زر إدارة، وفي الأعلى زرا الخيارات والاستيراد](https://arabroot.io/content/images/2026/10/kolibri-04-device-channels.webp)

القنوات على سيرفر المدرسة: رقم الإصدار والحجم على القرص لكل قناة

## الطلاب والفصول من ملف CSV

إنشاء الحسابات واحداً واحداً لا يصلح لمدرسة، والأمر `bulkimportusers` ينشئ المستخدمين والفصول من ملف CSV. وأسهل طريقة لمعرفة الأعمدة أن تصدر الملف من جهاز جديد بالأمر `bulkexportusers` ثم تملأه، وهذا ملفنا:

```text
UUID,USERNAME,PASSWORD,FULL_NAME,USER_TYPE,IDENTIFIER,BIRTH_YEAR,GENDER,ENROLLED_IN,ASSIGNED_TO
,t_huda,Lab-Teach-2026,هدى الشهري,CLASS_COACH,T-0101,,,,الصف الخامس
,s501,Lab-Stud-2026,محمد العمري,LEARNER,501,,,الصف الخامس,
,s502,Lab-Stud-2026,نورة الزهراني,LEARNER,502,,,الصف الخامس,
,s503,Lab-Stud-2026,سعد القرني,LEARNER,503,,,الصف الخامس,
```

```bash
docker cp users.csv edu3-kol-school:/tmp/users.csv
docker exec edu3-kol-school kolibri manage --skip-update bulkimportusers /tmp/users.csv
```

وقبل أن يعمل الملف ظهرت لنا ثلاثة أخطاء، وكل واحد منها درس:

1. **أعمدة ناقصة:** بدأنا بالأعمدة التي نحتاجها فقط، فرفض الملف كله: `The column 'UUID' is required` ومثلها `BIRTH_YEAR` و`GENDER`، فالأعمدة كلها مطلوبة حتى لو بقيت قيمها فارغة.
2. **النقطة في اسم المستخدم:** اسم المعلمة `t.huda` رفض بالرسالة `Username only can contain characters, numbers and underscores`، بينما أنشئ الطلاب الثلاثة والفصل. وهذا يهم من يربط أسماء Kolibri بأسماء حسابات المدرسة في أنظمة أخرى، فاستخدم الشرطة السفلية `t_huda`.
3. **إعادة الرفع بلا UUID:** عند رفع الملف المصحح رفض الطلاب الثلاثة بالرسالة `Username is duplicated`، وأنشئت المعلمة فقط، لأن عمود UUID الفارغ يعني «مستخدم جديد». فإذا أردت تعديل مستخدمين موجودين فصدر الملف أولاً، وعدل عليه، والمعرف في عمود UUID.

```text
INFO     Data errors: [{'row': 1, 'message': 'Username only can contain characters, numbers and underscores', 'field': 'USERNAME', 'value': 't.huda'}]
INFO     Classes report: {'created': 1, 'updated': 0, 'cleared': 0}
INFO     Users report: {'created': 3, 'updated': 0, 'deleted': 0}
```

## مزامنة بيانات الطلاب بين الجهازين

في Kolibri نوعان من البيانات، ولكل نوع طريقة انتقال مختلفة، والشكل التالي يوضح الفرق:

![مخطط: سيرفر المدرسة وفيه القنوات والمرفق التعليمي مدرسة الوادي والطلاب والتقدم، وجهاز الفصل بلا إنترنت وفيه نسخة من القنوات ونسخة من المرفق وطالب جديد أضيف هنا s504. سهم أزرق للمحتوى باتجاه واحد من السيرفر إلى الفصل بالأمرين importchannel وimportcontent، وسهمان برتقاليان لبيانات المرفق في الاتجاهين بالأمر kolibri manage sync، ونزل 14 سجلاً وصعد الطالب الجديد](https://arabroot.io/content/images/2026/10/kolibri-05-two-way-sync.webp)

الاستيراد ينقل القنوات فقط، والمزامنة تنقل بيانات المرفق فقط

والمزامنة تحتاج حساب مدير المرفق أو المدير العام على الجهاز الآخر، كما في [صفحة المرافق](https://kolibri.readthedocs.io/en/latest/manage/facilities.html?ref=arabroot.io)، وفي سطر الأوامر الأمر `sync` مع معرف المرفق:

```bash
docker exec edu3-kol-classroom kolibri manage --skip-update sync \
  --baseurl http://edu3-kol-school:8080/ --facility ade37d7711fd97354ab9af8e826fae90 \
  --username admin --password 'Lab-Admin-2026!' --noninteractive
```

```text
Receiving data (0/14, 0B)
Locally integrating received data
Locally preparing data to send
No records transferred
Remotely integrating data
```

نزلت إلى جهاز الفصل 14 سجلاً، وهي المرفق والفصل والمستخدمون، ولم يصعد شيء لأن جهاز الفصل لم يكن فيه بعد ما يخص هذا المرفق. واستغرقت المزامنة الأولى 91 ثانية. وبعدها أصبح في جهاز الفصل مرفقان: «صف مؤقت» الذي أنشأه معالج الإعداد عند تجهيزه، و«مدرسة الوادي» بمستخدميها الخمسة.

ثم لنفرض أن طالباً جديداً انضم إلى الفصل البعيد، فأضفناه على جهاز الفصل نفسه، وهو بلا إنترنت، بملف من سطر واحد مع الخيار `--facility`، ثم زامنا مرة أخرى:

```bash
docker exec edu3-kol-classroom kolibri manage --skip-update bulkimportusers /tmp/new-learner.csv --facility ade37d7711fd97354ab9af8e826fae90
```

```text
Remotely integrating data
Remotely preparing data
Sending data (0/2, 0B)
```

صعد سجلان، وعند سؤال سيرفر المدرسة عن مستخدميه كان الطالب الجديد بينهم:

```text
['admin:admin', 's501:محمد العمري', 's502:نورة الزهراني', 's503:سعد القرني', 's504:عبدالله الغامدي', 't_huda:هدى الشهري']
```

و[صفحة المرافق](https://kolibri.readthedocs.io/en/latest/manage/facilities.html?ref=arabroot.io) تذكر أن الغرض من استيراد المرفق هو مزامنة تقدم الطلاب Progress بشكل دوري، فما يسجله الطالب على جهاز الفصل يصعد إلى سيرفر المدرسة في أول مزامنة، فيراه المشرف في المدرسة الرئيسية، ولكنه لا يصل قبل المزامنة، لذلك حدد للفصل البعيد موعداً ثابتاً للمزامنة، كأن تكون في كل زيارة للمشرف.

## ما الذي يراه الطالب؟ ثلاثة أشياء قبل أول يوم

فتحنا سيرفر المدرسة في المتصفح، فظهرت صفحة الدخول بالعربية واسم المرفق:

![صفحة دخول Kolibri بالعربية: شعار كوليبري واسم المرفق مدرسة الوادي وحقل اسم المستخدم وزر التالي ورابط استكشاف المنصة دون إنشاء حساب، وفي الأسفل قائمة اللغات وأولها العربية، ورقم الإصدار 0.19.5](https://arabroot.io/content/images/2026/10/kolibri-02-signin.webp)

صفحة الدخول تطلب اسم المستخدم أولاً، وفيها رابط لاستكشاف المنصة دون حساب

ودخلنا بحساب الطالب `s501`، وهنا ظهرت الملاحظات الثلاث التالية:

1. **الطالب دخل دون كلمة مرور:** بعد كتابة اسم المستخدم والضغط على «التالي» دخل مباشرة، ولم تظهر صفحة كلمة المرور. وعندما سألنا قاعدة البيانات عن إعدادات المرفق وجدنا `preset formal` ومعه `learner_can_login_with_no_password True`. وهذا مقبول لطفل في الصف الأول على جهاز في الفصل، ولكنه غير مقبول على سيرفر يخدم المدرسة كلها، لأن أي طالب يستطيع الدخول باسم زميله إذا عرف اسم المستخدم. والخيار في إعدادات المرفق، و[صفحة المرفق](https://kolibri.readthedocs.io/en/latest/manage/facility.html?ref=arabroot.io) تسميه «الدخول دون كلمة مرور (للطلاب فقط)»، فقرره بنفسك ولا تتركه على القيمة التي جاءت.
2. **قناة لا تظهر للطلاب:** مكتبة الطالب فيها قناة واحدة فقط، بينما الجهاز فيه قناتان، والسبب أن موارد قناة Living Values الخمسة كلها معلمة أنها محتوى للمعلمين Coach Content، أي أدلة للمربي والميسر، فلا يراها إلا المعلم. فتأكد من نوع المحتوى في القناة قبل أن تعد بها الطلاب.
3. **رسالة الترحيب نصفها إنجليزي:** ظهرت للطالب نافذة عنوانها «مرحبا بك في كوليبري!» ونصها «Welcome to your learning facility. Your class materials can be found on the home page.»، فالترجمة العربية للواجهة جيدة في أغلبها، ولكنها ليست كاملة.

![صفحة المكتبة للطالب s501 في Kolibri بالعربية: عنوان مكتبتك وفيها قناة واحدة هي منظمة تعليم الطفولة الدولية بوصفها، ثم قسم مكتبات أخرى برسالة لا يوجد مكتبات أخرى حولك حالياً، وعلى اليمين البحث والأنشطة وفلتر اللغة العربية](https://arabroot.io/content/images/2026/10/kolibri-03-library.webp)

مكتبة الطالب: قناة واحدة من اثنتين، لأن الأخرى محتوى للمعلمين فقط

## النسخ الاحتياطي والترقية

- **ما الذي يستحق النسخ؟** القنوات يمكن استيرادها من جديد، أما المستخدمون والتقدم فلا يمكن، وكلها في قاعدة بيانات SQLite داخل `KOLIBRI_HOME`. وصفحة سطر الأوامر تذكر الأمرين `kolibri manage dbbackup` و`kolibri manage dbrestore --latest`، فشغل الأول بشكل دوري وانسخ الناتج خارج الجهاز، كما في [النسخ الاحتياطي بقاعدة 3-2-1](https://arabroot.io/articles/%D8%A7%D9%84%D9%86%D8%B3%D8%AE-%D8%A7%D9%84%D8%A7%D8%AD%D8%AA%D9%8A%D8%A7%D8%B7%D9%8A-%D8%A8%D9%82%D8%A7%D8%B9%D8%AF%D8%A9-3-2-1-%D9%88%D8%A7%D8%AE%D8%AA%D8%A8%D8%A7%D8%B1-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D8%A7%D8%AF%D8%A9/).
- **المزامنة نسخة إضافية:** كل جهاز فصل زامن مع سيرفر المدرسة يحمل نسخة من بيانات المرفق، فإذا تعطل جهاز الفصل لم يضع إلا ما سجله بعد آخر مزامنة، وهذا سبب آخر لموعد المزامنة الثابت.
- **الترقية Upgrade:** قم بترقية سيرفر المدرسة وأجهزة الفصول إلى الإصدار نفسه، وجرب المزامنة بين جهازين بعد الترقية قبل أن توزعها على كل المدارس، والسبب أن الأجهزة النائية قد تبقى شهوراً على إصدار قديم حتى زيارتها التالية.

## مشكلات شائعة وحلولها

| ما تراه                                                       | السبب                                              | الحل                                                                |
| ------------------------------------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------- |
| الاستيراد لا ينتهي ولا يطبع شيئاً                             | لا يوجد إنترنت، وKolibri يعيد المحاولة كل 30 ثانية | ابحث في logs/kolibri.txt عن Waiting 30s، واستخدم \--baseurl أو disk |
| PermissionError على مجلد logs                                 | مجلد KOLIBRI\_HOME مملوك لمستخدم آخر               | اجعل المجلد ملكاً للمستخدم الذي يشغل Kolibri                        |
| قناة مستوردة لا تظهر للطلاب                                   | مواردها محتوى للمعلمين Coach Content               | اختر قناة للطلاب، أو استخدمها المعلم في الفصل                       |
| الطالب يدخل دون كلمة مرور                                     | إعداد المرفق يسمح بذلك                             | عطل الدخول دون كلمة مرور من إعدادات المرفق                          |
| Username only can contain characters, numbers and underscores | نقطة أو شرطة في اسم المستخدم                       | استخدم الشرطة السفلية                                               |
| Username is duplicated عند إعادة رفع CSV                      | عمود UUID فارغ فيعامل الصف كمستخدم جديد            | صدر الملف بالأمر bulkexportusers وعدل عليه                          |
| سيرفر المدرسة لا يظهر في قائمة الأجهزة المجاورة               | جدار حماية أو شبكة تمنع الاكتشاف                   | اكتب عنوانه يدوياً، أو افتح المنفذ 8080 على الشبكة المحلية          |

## تنظيف المختبر

```bash
docker compose down -v
docker image rm edu3-kolibri:0.19.5
```

## تدريب عملي

- عطل الدخول دون كلمة مرور في إعدادات المرفق على سيرفر المدرسة، ثم زامن جهاز الفصل، وتأكد هل انتقل الإعداد إليه أم لا.
- أنشئ درساً Lesson بحساب المعلمة `t_huda` من قناة منظمة تعليم الطفولة الدولية، ثم زامن، وادخل بحساب طالب على جهاز الفصل وتأكد أن الدرس ظهر له.

## الخلاصة

وصلنا لنهاية الموضوع، وأهم ما فيه:

- Kolibri منصة تعلم مصممة للعمل دون إنترنت، يحتاج الإنترنت جهاز واحد فيها ومرة واحدة لكل قناة، وكل الأجهزة الأخرى تأخذ من الشبكة المحلية بالخيار `--baseurl` أو من ذاكرة USB بالأمر `disk`.
- الاستيراد بلا إنترنت لا يفشل بل ينتظر ويعيد المحاولة كل 30 ثانية، فالسجل هو المكان الذي تعرف منه ما يحدث.
- القنوات تنتقل بالاستيراد في اتجاه واحد، وبيانات المرفق من مستخدمين وتقدم تنتقل بالمزامنة في الاتجاهين، وفي تجربتنا نزل 14 سجلاً وصعد الطالب الذي أضيف دون إنترنت.
- قبل أول يوم: قرر الدخول دون كلمة مرور بنفسك، وتأكد أن القنوات التي اخترتها للطلاب وليست للمعلمين فقط، واستخدم أسماء مستخدمين بلا نقاط.
- انسخ قاعدة البيانات احتياطياً، فالقنوات تعود بالاستيراد، أما تقدم الطلاب فلا يعود.

## سجل التحديثات

- أكتوبر 2026: كتابة المقال وتجربته على Kolibri 0.19.5 وPython 3.13.16.