الاستضافة الذاتية
لا يثبّت الموقع العام نسخة تعمل دون اتصال داخل المتصفح. وبدلًا من ذلك يوجد خياران للاستضافة الذاتية: صورة Docker لشركة تستضيف الأدوات على شبكتها الخاصة، وملف zip يعمل دون اتصال مع خادم محلي صغير.
الصورة المستضافة ذاتيًا
Section titled “الصورة المستضافة ذاتيًا”تحتوي الصورة على الموقع المبني، ويقدّمه server.mjs تمامًا كما تقدّم Cloudflare Pages الموقع العام (الملفان _headers و_redirects نفسهما، والعناوين النظيفة، وصفحة 404)، وذلك في صورة Node.js من نوع distroless تعمل بمستخدم غير جذر. لا يفعل الخادم سوى تسليم الملفات، ولا يخزّن شيئًا، ولا يتضمن أي تحليلات أو تتبع، ولا يتصل بالإنترنت أبدًا. ويجري كل العمل في متصفح كل مستخدم.
ما يحتاجه المثبّت
Section titled “ما يحتاجه المثبّت”- خادم Linux أو آلة افتراضية عليها Docker Engine الإصدار 23 أو أحدث وDocker Compose v2 (الأمر
docker compose). - نحو 1 GB من المساحة الحرة على القرص و256 MB من الذاكرة (يُستخدم نحو 150 MB أثناء التشغيل).
- لا حاجة إلى اتصال بالإنترنت، لا أثناء التثبيت ولا بعده.
- للمستخدمين: إصدار حديث من Chrome أو Edge أو Firefox.
بناء حزمة إصدار
Section titled “بناء حزمة إصدار”يتطلب البناء Docker 23 أو أحدث وgit. من المستودع:
node scripts/build/build-container.mjs # version: today's datenode 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؛ راجع مفاتيح الميزات.
التثبيت
Section titled “التثبيت”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/، لا تحت مسار فرعي.
ب. شهادتك الخاصة على الحاوية.
- أنشئ مجلدًا باسم
certsبجوارcompose.yaml. - انسخ الشهادة إليه باسم
cert.pem(تتبعها أي شهادات وسيطة) والمفتاح الخاص باسمkey.pem. يجب أن يكون الملفان بصيغة PEM ودون كلمة مرور. - تعمل الحاوية بالمستخدم 65532، لذا يجب أن يستطيع هذا المستخدم قراءة المفتاح:
نافذة طرفيّة sudo chown 65532 certs/key.pemsudo chmod 400 certs/key.pem - في
compose.yaml، أزل#من الأسطر الخمسة تحت “HTTPS with your own certificate”، وغيّر سطر المنفذ إلى- "443:8080"(أو أبقِ 8080 واستخدمhttps://<server>:8080/). - أعد التشغيل:
نافذة طرفيّة docker compose up -d
الإعدادات
Section titled “الإعدادات”كلها اختيارية. اضبطها تحت environment: في compose.yaml.
| الإعداد | وظيفته | الافتراضي |
|---|---|---|
PORT |
المنفذ داخل الحاوية | 8080 |
TLS_CERT, TLS_KEY |
مساران إلى الشهادة والمفتاح، لتقديم HTTPS | غير مضبوط: HTTP |
ACCESS_LOG |
القيمة 1 تطبع سطرًا لكل طلب (الأسلوب والعنوان والحالة) في سجل الحاوية |
متوقف |
التحديث
Section titled “التحديث”- حمّل الملف الجديد:
docker load -i developer-tools-<new version>.tar.gz - في
compose.yaml، غيّرimage: developer-tools:<old version>إلى الإصدار الجديد. - شغّل
docker compose up -d. فيستبدل النسخة العاملة في ثوانٍ.
وللرجوع، أعد رقم الإصدار القديم وشغّل docker compose up -d مرة أخرى. وتبقى الصورة القديمة على الخادم إلى أن تزيلها.
التشغيل دون حزمة إصدار
Section titled “التشغيل دون حزمة إصدار”لبناء الصورة وتشغيلها من نسخة مستنسخة من المستودع:
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.mjsSITE_DIR=dist node container/server.mjs # http://localhost:8080/ملاحظات أمنية
Section titled “ملاحظات أمنية”- لا حركة مرور صادرة: الأدوات لا تتصل بأي جهة، فيمكنك حجب كل الحركة الصادرة للحاوية في جدار الحماية.
- لا يُخزَّن شيء على الخادم: لا حسابات ولا قاعدة بيانات. وما يكتبه الناس يبقى في متصفحاتهم.
- تعمل الحاوية بمستخدم عادي، ولا يمكن تغيير ملفاتها أثناء التشغيل، ولا تملك أي صلاحيات Linux خاصة. ولا تحتوي الصورة على shell ولا مدير حزم.
- افتراضيًا تسجّل الحاوية عند بدء تشغيلها وعند حدوث خلل فقط.
- تُرسل ترويسات الأمان نفسها التي يرسلها الموقع العام مع كل صفحة، ومنها Content-Security-Policy صارمة وحماية من تضمين الموقع في إطارات على مواقع أخرى.
Kubernetes
Section titled “Kubernetes”شغّل الصورة مع منفذ الحاوية 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 وأرسله إلى مورّدك مع وصف للمشكلة. |
التحقق والاختبارات
Section titled “التحقق والاختبارات”يختبر المستودع الخادم مقارنةً بسلوك Cloudflare (scripts/tests/container-server-test.mjs: العناوين النظيفة، وكل قاعدة في _redirects، وكل قيمة في _headers، وصفحات 404، وETags، وgzip، وHTTPS، و--health، والإيقاف). ويبني التكامل المستمر (CI) فيه الصورة الحقيقية ويشغّلها بقيود مشددة، ثم يشغّل security-smoke.mjs وheaders-check.mjs عليها عبر HTTP وHTTPS. والمجلد container/ ليس جزءًا من الموقع العام ولا يقدّمه الموقع.
حزمة zip دون اتصال
Section titled “حزمة zip دون اتصال”وبصورة منفصلة، ينتج الأمر 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.