لماذا دفتر تفاعلي على خادمك الخاص
في Jupyter يتوقف ترتيب التنفيذ على نقراتك: متغيّر أُعيد تعريفه في الأسفل، أو خلية منسية، فلا تعود النتائج المعروضة تطابق الشيفرة. وملف .ipynb، وهو JSON مثقل بالمخرجات، صعب المراجعة ويولّد تعارضات في Git مع كل تشغيل.
يحلّل marimo الاعتماديات بين الخلايا. عندما تتغيّر خلية تُعاد حساب كل الخلايا التي تعتمد عليها، وهي وحدها. والدفتر ملف Python عادي: يقرؤه git diff ويشغّله python notebook.py.
استضافته على خادمك الافتراضي تعني إبقاء البيانات على خادم تتحكّم فيه، ومنح الفريق كله البيئة نفسها من المتصفح، واختيار الذاكرة والمعالج اللذين تحتاجهما حساباتك.
ما يقدّمه marimo
- تنفيذ تفاعلي — الخلية المعدّلة تعيد حساب الخلايا التي تعتمد عليها، دون حالة مخفية.
- ملفات .py — دفاتر مقروءة، تُصدَّر في Git وتُشغَّل كسكربتات.
- عناصر واجهة — منزلقات وقوائم وجداول ومخططات مرتبطة بمتغيّرات Python.
- من دفتر إلى تطبيق —
marimo runيقدّم الدفتر للقراءة فقط مع إخفاء الشيفرة. - الانتقال من Jupyter —
marimo convertيحوّل ملف .ipynb. - صورة «data» الرسمية — pandas وpolars وnumpy وaltair مثبّتة مسبقًا.
marimo وJupyter وcode-server
مرّر الجدول أفقيًا
| marimo | JupyterLab | code-server | |
|---|---|---|---|
| صيغة الدفتر | ملف .py | ملف .ipynb (JSON) | ملفات المشروع |
| ترتيب التنفيذ | تفاعلي، حسب الاعتماديات | يدوي، بالنقر | حسب السكربت المشغَّل |
| المراجعة في Git | فرق Python مقروء | فرق JSON مع المخرجات | فرق الشيفرة |
| النشر كتطبيق | نعم، `marimo run` | إضافات من أطراف أخرى | لا |
| الاستخدام الأمثل | التحليل والأدوات الداخلية بلغة Python | تنوّع واسع في النوى | تطوير البرمجيات الكامل |
المتطلبات
خادم افتراضي Ubuntu 24.04 بذاكرة 2 غيغابايت وقرص 20 غيغابايت (خطّط لذاكرة أكبر إن كنت تحمّل مجموعات بيانات كبيرة)، مع Docker وإضافة Compose، ووصول root عبر SSH. نطاق فرعي (مثل notebooks.example.com) يشير إلى الخادم مفيد للوصول عبر HTTPS لكنه ليس ضروريًا: يكفي نفق SSH إذا كنت تعمل وحدك.
تثبيت marimo باستخدام Docker Compose
تحضير المجلد وكلمة المرور
أنشئ مجلد التطبيق وملف
.envيحمل كلمة مرور المحرّر.mkdir -p /opt/marimo && cd /opt/marimo echo "ADMIN_PASSWORD=$(openssl rand -base64 24 | tr -d '/+=')" > .env chmod 600 .envكتابة ملف compose
أنشئ
compose.yaml. تحتوي صورة «data» الرسمية مسبقًا على مكتبات التحليل. يُنشر المنفذ على الواجهة المحلية فقط، وتُمرَّر كلمة المرور عبر ملف بدلًا من سطر الأوامر.services: marimo: image: ghcr.io/marimo-team/marimo:0.25.2-data restart: unless-stopped ports: - "127.0.0.1:2718:8080" environment: ADMIN_PASSWORD: ${ADMIN_PASSWORD:?ADMIN_PASSWORD requis} command: - sh - -c - umask 077 && printf %s "$$ADMIN_PASSWORD" > /tmp/marimo-password && exec marimo edit --headless --skip-update-check --host 0.0.0.0 -p 8080 --token-password-file /tmp/marimo-password /app volumes: - marimo-data:/app volumes: marimo-data: {}التشغيل والتحقق
شغّل الحزمة ثم استعلم عن مسبار الصحة: يجب أن يجيب بالرمز 200.
docker compose up -d docker compose ps curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:2718/healthنشر المحرّر عبر HTTPS
يتواصل marimo مع المتصفح عبر WebSocket: يجب أن يمرّر مضيف nginx الترويستين
UpgradeوConnection، وإلا ظهر المحرّر دون أن تُنفَّذ الخلايا أبدًا.server { server_name notebooks.example.com; location / { proxy_pass http://127.0.0.1:2718; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 3600s; } }certbot --nginx -d notebooks.example.com
لا نطاق لديك؟ استخدم نفق SSH
ينفّذ المحرّر شيفرة Python بصلاحيات الحاوية: لا تعرضه أبدًا دون كلمة مرور. إن كنت تعمل وحدك فلا حاجة لنشره — نفق SSH يفتح المحرّر على http://localhost:2718 من جهازك.
ssh -L 2718:127.0.0.1:2718 root@<vps-ip>تأمين المحرّر
محرّر marimo المفتوح يتيح لكل من يدخله تنفيذ شيفرة Python على خادمك: تلك غايته، ولذلك تفرض بعض القواعد البسيطة نفسها.
كلمة مرور طويلة وفريدة. كلمة المرور في ملف .env عشوائية؛ لا تستبدلها بكلمة مرور تستخدمها في مكان آخر، وغيّرها عندما يغادر المشروع متعاون يعرفها (عدّل .env ثم شغّل docker compose up -d).
منفذ يبقى محليًا. ينشر ملف compose المنفذ على 127.0.0.1 فقط: من الإنترنت لا يصل إليه سوى nginx عبر HTTPS. لا تستبدل هذا العنوان أبدًا بـ 0.0.0.0.
لا أسرار مكشوفة في الدفاتر. الدفتر ملف Python مُصدَّر: مفتاح API مكتوب في خلية ينتهي في سجل Git. اقرأه بدلًا من ذلك من متغيّر بيئة تضيفه إلى ملف compose، أو من ملف خارج المستودع.
سجلات تستحق المراقبة. عند الإقلاع يطبع marimo عنوان الوصول في docker compose logs مع كلمة المرور: يبقى السجل على خادمك، لكن لا تلصقه كما هو في تذكرة أو محادثة.
دفترك التفاعلي الأول
سجّل الدخول بكلمة المرور الموجودة في ملف .env. يفتح المحرّر المجلد /app الذي يحتوي مسبقًا على الدروس الرسمية. أنشئ دفترًا بخليتين: الأولى تعرّف منزلقًا، والثانية ترشّح ملف CSV بقيمته. حرّك المنزلق: تُعاد حساب الخلية الثانية من تلقاء نفسها.
import marimo as mo
import polars as pl
threshold = mo.ui.slider(0, 1000, value=100, label="Minimum amount")
thresholdsales = pl.read_csv("data/sales.csv")
sales.filter(pl.col("amount") >= threshold.value)قراءة بياناتك: CSV وParquet وواجهات API
تغطي صورة «data» معظم أعمال التحليل دون تثبيت أي شيء. تقرأ pandas ملفات CSV وExcel وJSON؛ وتقرأ polars ملفات CSV وParquet بسرعة كبيرة ويمكنها معالجة ملفات أكبر من الذاكرة في الوضع الكسول؛ وترسم altair مخططات تفاعلية تظهر مباشرة تحت الخلية.
ضع ملفاتك في المجلد /app/data من وحدة التخزين، عبر scp إلى الخادم ثم docker compose cp، أو ارفعها من لوحة الملفات في المحرّر. ولواجهة API تكفي مكتبة Python القياسية لتنزيل JSON تحوّله pandas أو polars بعد ذلك إلى جدول.
كل نتيجة خلية كائن حيّ: يظهر DataFrame كجدول قابل للفرز والترشيح، ويمكن للتحديد الذي تجريه في جدول أو مخطط أن يغذّي الخلية التالية. هذه الآلية هي ما يحوّل الاستكشاف إلى أداة قابلة لإعادة الاستخدام.
تحويل دفتر إلى تطبيق
الدفتر المزوّد بعناصر واجهة هو تطبيق أصلًا. الأمر marimo run يقدّمه للقراءة فقط: يستعمل الزوار المنزلقات والقوائم دون رؤية الشيفرة أو تعديلها. انشر هذا المنفذ الثاني خلف مضيفه الخاص، محميًا مثل المحرّر.
docker compose exec marimo marimo run /app/rapport.py --host 0.0.0.0 -p 8081تتحوّل دفاتر Jupyter الحالية بأمر واحد؛ راجع بعدها الخلايا التي كانت تعيد تعريف المتغيّر نفسه، وهو ما يرفضه marimo عن قصد.
docker compose exec marimo marimo convert /app/old.ipynb -o /app/new.pyالعمل الجماعي على الدفاتر نفسها
خادم marimo محرّر مشترك: كل من يملك كلمة المرور يرى الملفات نفسها. للفريق الصغير، أبسط قاعدة هي دفتر لكل شخص ولكل موضوع، ومستودع Git في /app للاحتفاظ بالسجل.
ولأن كل دفتر ملف Python، تنطبق أدوات المطوّر المعتادة: يبيّن git diff بدقة أي خلية تغيّرت، وتُراجَع طلبات الدمج كما تُراجَع الشيفرة، ويعمل عليه مدقّق Python أو أداة تنسيق دون تعديل. بل يمكن استيراد الدفتر كوحدة أو تشغيله كسكربت من مهمة مجدولة لإنتاج التقرير نفسه كل ليلة.
تحديد حجم الخادم الافتراضي
marimo نفسه خفيف؛ بياناتك هي التي تحدّد حجم الخادم. احسب 2 غيغابايت من الذاكرة لاستكشاف ملفات من بضع مئات من الميغابايت باستخدام pandas، وانتقل إلى 4 أو 8 غيغابايت إن كنت تحمّل مجموعات بيانات أكبر أو يعمل عدة أشخاص في الوقت نفسه. يهمّ المعالج خصوصًا في الحسابات الثقيلة: تستغل polars كل الأنوية المتاحة. وأخيرًا خصّص مساحة قرص كافية للصورة (نحو 400 ميغابايت) ولملفات بياناتك التي تكبر أسرع من الدفاتر.
النسخ الاحتياطي والتحديث
تعيش الدفاتر في وحدة التخزين marimo-data. الخيار الأكثر أمانًا هو إصدار /app في مستودع Git؛ وإلا فأرشف وحدة التخزين بانتظام.
docker run --rm -v marimo_marimo-data:/data -v "$PWD":/backup alpine \
tar czf /backup/marimo-$(date +%F).tar.gz -C /data .للتحديث، غيّر وسم الصورة في compose.yaml بعد قراءة ملاحظات إصدار المشروع، ثم شغّل docker compose pull && docker compose up -d. لا تُمسّ الدفاتر، فهي ملفات .py عادية.
تثبيت بنقرة واحدة من متجر ServOrbit
على خادم ServOrbit الافتراضي يُثبَّت marimo من المتجر في مساحة العميل: ينشر السكربت الحاوية الرسمية، ويولّد كلمة مرور المحرّر، وينشئ وحدة تخزين الدفاتر. تظهر كلمة المرور في مساحة العميل. اربط نطاقًا فرعيًا من أحد نطاقاتك، أو النطاق الفرعي المجاني للخادم، لفتح المحرّر عبر HTTPS؛ ومن دون نطاق يعمل نفق SSH الموصوف أعلاه كما هو، مع المنفذ الظاهر في مساحة العميل.