تخطَّ إلى المحتوى

الاستضافة الذاتية

لا يثبّت الموقع العام نسخة تعمل دون اتصال داخل المتصفح. وبدلًا من ذلك يوجد خياران للاستضافة الذاتية: صورة Docker لشركة تستضيف الأدوات على شبكتها الخاصة، وملف zip يعمل دون اتصال مع خادم محلي صغير.

الصورة المستضافة ذاتيًا

Section titled “الصورة المستضافة ذاتيًا”

تحتوي الصورة على الموقع المبني، ويقدّمه server.mjs تمامًا كما تقدّم Cloudflare Pages الموقع العام (الملفان _headers و_redirects نفسهما، والعناوين النظيفة، وصفحة 404)، وذلك في صورة Node.js من نوع distroless تعمل بمستخدم غير جذر. لا يفعل الخادم سوى تسليم الملفات، ولا يخزّن شيئًا، ولا يتضمن أي تحليلات أو تتبع، ولا يتصل بالإنترنت أبدًا. ويجري كل العمل في متصفح كل مستخدم.

  • خادم Linux أو آلة افتراضية عليها Docker Engine الإصدار 23 أو أحدث وDocker Compose v2 (الأمر docker compose).
  • نحو 1 GB من المساحة الحرة على القرص و256 MB من الذاكرة (يُستخدم نحو 150 MB أثناء التشغيل).
  • لا حاجة إلى اتصال بالإنترنت، لا أثناء التثبيت ولا بعده.
  • للمستخدمين: إصدار حديث من Chrome أو Edge أو Firefox.

يتطلب البناء Docker 23 أو أحدث وgit. من المستودع:

نافذة طرفيّة
node scripts/build/build-container.mjs # version: today's date
node scripts/build/build-container.mjs 2026.11.02 # or name it

يكتب هذا المجلد release/developer-tools-container-<version>/: الصورة بصيغة .tar.gz، والملف compose.yaml مضبوطًا على ذلك الإصدار، وINSTALL.md وSHA256SUMS. أرسل إلى العميل ذلك المجلد. ولاستبعاد وحدات لعميل بعينه، اذكرها أولًا تحت "disabled" في features.json؛ راجع مفاتيح الميزات.

1. تحقق من الملفات. في المجلد الذي يحوي الملفات:

نافذة طرفيّة
sha256sum -c SHA256SUMS

يجب أن ينتهي كل سطر بـOK. وإن لم يكن كذلك فاطلب نسخة جديدة.

2. حمّل الصورة في Docker.

نافذة طرفيّة
docker load -i developer-tools-<version>.tar.gz

يطبع Docker الرسالة Loaded image: developer-tools:<version>.

3. شغّلها.

نافذة طرفيّة
docker compose up -d

افتح http://<server name or address>:8080/. ينبغي أن يُظهر docker compose ps الخدمة بالحالة running، ثم healthy خلال دقيقة.

يُوصى باستخدام HTTPS. فعبر http:// العادي لا تعمل بعض ميزات المتصفح: أدوات التجزئة والمفاتيح والشهادات، وأزرار النسخ، وحفظ العمل في مجلد. وهناك طريقتان لتوفيره.

أ. وكيل عكسي أو موازن حمل يدعم HTTPS (nginx أو IIS أو F5 أو Traefik وغيرها). وجّهه إلى المنفذ 8080 وقدّم الأدوات في جذر اسمها الخاص، مثل https://devtools.example.local/، لا تحت مسار فرعي.

ب. شهادتك الخاصة على الحاوية.

  1. أنشئ مجلدًا باسم certs بجوار compose.yaml.
  2. انسخ الشهادة إليه باسم cert.pem (تتبعها أي شهادات وسيطة) والمفتاح الخاص باسم key.pem. يجب أن يكون الملفان بصيغة PEM ودون كلمة مرور.
  3. تعمل الحاوية بالمستخدم 65532، لذا يجب أن يستطيع هذا المستخدم قراءة المفتاح:
    نافذة طرفيّة
    sudo chown 65532 certs/key.pem
    sudo chmod 400 certs/key.pem
  4. في compose.yaml، أزل # من الأسطر الخمسة تحت “HTTPS with your own certificate”، وغيّر سطر المنفذ إلى - "443:8080" (أو أبقِ 8080 واستخدم https://<server>:8080/).
  5. أعد التشغيل:
    نافذة طرفيّة
    docker compose up -d

كلها اختيارية. اضبطها تحت environment: في compose.yaml.

الإعداد وظيفته الافتراضي
PORT المنفذ داخل الحاوية 8080
TLS_CERT, TLS_KEY مساران إلى الشهادة والمفتاح، لتقديم HTTPS غير مضبوط: HTTP
ACCESS_LOG القيمة 1 تطبع سطرًا لكل طلب (الأسلوب والعنوان والحالة) في سجل الحاوية متوقف
  1. حمّل الملف الجديد: docker load -i developer-tools-<new version>.tar.gz
  2. في compose.yaml، غيّر image: developer-tools:<old version> إلى الإصدار الجديد.
  3. شغّل docker compose up -d. فيستبدل النسخة العاملة في ثوانٍ.

وللرجوع، أعد رقم الإصدار القديم وشغّل docker compose up -d مرة أخرى. وتبقى الصورة القديمة على الخادم إلى أن تزيلها.

لبناء الصورة وتشغيلها من نسخة مستنسخة من المستودع:

نافذة طرفيّة
docker build -f container/Dockerfile -t developer-tools .
docker compose -f container/compose.yaml up -d # http://localhost:8080/

وبدون Docker، يعمل الخادم نفسه على بناء مباشرة:

نافذة طرفيّة
node scripts/build/build-pages.mjs
SITE_DIR=dist node container/server.mjs # http://localhost:8080/
  • لا حركة مرور صادرة: الأدوات لا تتصل بأي جهة، فيمكنك حجب كل الحركة الصادرة للحاوية في جدار الحماية.
  • لا يُخزَّن شيء على الخادم: لا حسابات ولا قاعدة بيانات. وما يكتبه الناس يبقى في متصفحاتهم.
  • تعمل الحاوية بمستخدم عادي، ولا يمكن تغيير ملفاتها أثناء التشغيل، ولا تملك أي صلاحيات Linux خاصة. ولا تحتوي الصورة على shell ولا مدير حزم.
  • افتراضيًا تسجّل الحاوية عند بدء تشغيلها وعند حدوث خلل فقط.
  • تُرسل ترويسات الأمان نفسها التي يرسلها الموقع العام مع كل صفحة، ومنها Content-Security-Policy صارمة وحماية من تضمين الموقع في إطارات على مواقع أخرى.

شغّل الصورة مع منفذ الحاوية 8080 وأبقِ هذه الإعدادات:

  • securityContext: runAsNonRoot: true وreadOnlyRootFilesystem: true وallowPrivilegeEscalation: false وcapabilities: {drop: ["ALL"]}
  • الفحوص (Probes): طلب HTTP GET على /، المنفذ 8080.
  • HTTPS: أنهِه عند ingress لديك، أو ركّب الشهادة كسر (secret) واضبط TLS_CERT وTLS_KEY.

استكشاف الأخطاء وإصلاحها

Section titled “استكشاف الأخطاء وإصلاحها”
ما تراه ما تفعله
يقول docker compose up إن المنفذ محجوز بالفعل برنامج آخر يستخدم ذلك المنفذ. غيّر الرقم الأيسر في سطر ports، مثل "8081:8080".
لا تفعل بعض الأدوات أو أزرار النسخ شيئًا العنوان هو http://. فعّل HTTPS.
تعيد الحاوية التشغيل ويذكر السجل permission denied للملف key.pem شغّل الأمرين chown وchmod من قسم HTTPS.
أي شيء آخر اطلع على السجل بالأمر docker compose logs وأرسله إلى مورّدك مع وصف للمشكلة.

يختبر المستودع الخادم مقارنةً بسلوك Cloudflare (scripts/tests/container-server-test.mjs: العناوين النظيفة، وكل قاعدة في _redirects، وكل قيمة في _headers، وصفحات 404، وETags، وgzip، وHTTPS، و--health، والإيقاف). ويبني التكامل المستمر (CI) فيه الصورة الحقيقية ويشغّلها بقيود مشددة، ثم يشغّل security-smoke.mjs وheaders-check.mjs عليها عبر HTTP وHTTPS. والمجلد container/ ليس جزءًا من الموقع العام ولا يقدّمه الموقع.

وبصورة منفصلة، ينتج الأمر node scripts/build/build-offline-zip.mjs ملف zip للموقع المبني مع مشغّل خادم محلي صغير (run.sh أو run.bat أو serve.mjs) وملف SHA256SUMS. وبعد التشغيل افتح http://localhost:8080. تحتاج الأدوات إلى أصل HTTP (بسبب Web Workers وWASM)، لذا يقدّم المشغّل الملفات محليًا بدل الاعتماد على file://. وتربط النسخة المقدَّمة من localhost ملف manifest لتطبيق الويب، فيستطيع المتصفح إضافتها كنافذة تطبيق؛ ولا تحتاج إلى service worker.