مدونتي // الأرشيف الرقمي

أفكار ومشاريع وملاحظات تقنية

في الأصل، كان إعداد مدونتي مخططاً له كمشروع IPv6 خالص عبر WireGuard، حيث يتم تشغيل النظام بالكامل على خادم منزلي (بالمناسبة، يمكنك الحصول على عناوين IPv6 مجانية من route64.org). ولزيادة إمكانية الوصول، قمت الآن بإضافة بروكسي IPv4 خارجي (شكراً لـ @Larvitz).

ومع ذلك، ظهرت مشاكل في SSL على الفور: نظرًا لأن كلا السجلين A و AAAA كانا يمران عبر البروكسي في البداية، فقد فشل التحقق من Let's Encrypt على خادمي.

الحل: «خدعة IPv6»

كان الحل هو توجيه سجل AAAA صراحةً وبشكل مباشر إلى عنوان IP الخاص بـ WireGuard على خادمي، بدلاً من تمريره عبر البروكسي أيضاً.

  • النطاق (Domain): blog.burningboard.org
  • سجل A (البروكسي): 194.28.98.217
  • سجل AAAA (الخادم): 2a11:6c7:f05:a8::2 (WireGuard)

من خلال سجل AAAA المباشر هذا إلى عنوان IP الخاص بـ WireGuard، لا يزال بإمكان Let’s Encrypt الوصول إلى خادمي مباشرة عبر IPv6 (بما أن سجل AAAA يحظى بالأولوية افتراضياً) وإصدار شهادة SSL. أما حركة مرور IPv4 فيتم تمريرها إليّ مشفرة من قبل البروكسي.

الإعداد النهائي

لضمان سير الاتصال بسلاسة، كان علينا تعديل خوادم Caddy:

1. على خادمي (NixOS، blog.nix)

لكي تصل عناوين IP الحقيقية للزوار بشكل صحيح ولا يتم استبدالها بعنوان IP الخاص بالبروكسي، يجب تحديد البروكسي كجهة موثوقة:

services.caddy.globalConfig = ''
  servers {
      trusted_proxies static 2a06:9801:1c:1000::10
  }
'';

2. على البروكسي الخارجي (Caddy)

لكي يتواصل البروكسي مع خادمي بشكل صحيح عبر HTTPS، يجب عليه إرسال اسم المضيف (SNI):

reverse_proxy [https://[2a11:6c7:f05:a8::2]:443](https://[2a11:6c7:f05:a8::2]:443) {
    header_up Host {host}
    transport http {
        tls_server_name blog.burningboard.org
    }
}

المدونة الآن متاحة عبر IPv4 و IPv6، ومشفرة بشكل آمن، ومع ذلك يظل عنوان IP المنزلي الخاص بي خاصاً! 🚀

الأهم أولاً: تظل ملفات Markdown المعتادة هي الأساس – فأنا ببساطة من كبار المعجبين بهذا الحل غير المعقد. ولكن تحت الغطاء، حدث الكثير:

لقد قمت ببعض التعديلات على الإعدادات:

📂 ملفات MD: تظل بنية المدونة بسيطة وتعتمد على Markdown.

🌍 عالمية أكثر من أي وقت مضى: تدعم مدونتي الآن الترجمة إلى 43 لغة. نعم، بما في ذلك لغة الكلينجون! 🖖 (Qapla'!)

كان المخطط له هو توفير ترجمة فورية مؤتمتة بالكامل بناءً على التعرف على لغة المتصفح. تنبيه (Spoiler): لقد نجح الأمر جزئياً فقط. نلاحظ أن: الذكاء الاصطناعي مثير للإعجاب، لكنه لم يصل تماماً بعد إلى المستوى الذي نتمناه.

الحل: أقوم الآن ببساطة بترجمة كل مقال مسبقاً إلى جميع اللغات المحددة، وهو أمر أفضل بكثير لمحركات البحث (SEO). في حال لم يعمل التعرف التلقائي، يمكنك تحديد لغتك المفضلة يدوياً عبر أيقونة الكرة الأرضية، والتي سيتم حفظها بعد ذلك بكل سهولة عبر ملفات تعريف الارتباط (Cookie).

تتم الترجمات الآن باستخدام Gemini 3 Flash، والذي يقدم نتائج جيدة بشكل مذهل. ومع ذلك، يجب مراقبة الذكاء الاصطناعي بدقة: في أول عملية ترجمة جماعية، تمت ترجمة الوسوم (Tags) عن طريق الخطأ أيضاً، وهو ما لم يكن مخططاً له بالطبع.

الكود لا يزال متاحاً (فقط أرسل لي رسالة إذا كنت مهتماً) 👍 لكن يرجى ملاحظة أن النظام يتطلب الآن مفتاح API خاص بـ Gemini 🔑.

قمت فجأة بتحويل مدونتي من WriteFreely إلى تطوير خاص بي: MD-Blog (يرمز MD بالطبع إلى Markdown). كان السبب هو فشل تحديث النظام القديم - ولكن في النهاية كان ذلك الحافز المثالي لتبسيط كل شيء بشكل جذري واكتساب التحكم الكامل في التصميم.

يعتمد جوهر النظام على ملفات Markdown بسيطة في مجلد data/ يتم تحويلها إلى HTML حديث أثناء التشغيل. النتيجة سريعة للغاية، وتعمل بدون قاعدة بيانات، وبفضل نظام التصميم الخاص بي (بما في ذلك الوضع الداكن)، تبدو الآن تماماً كما تخيلتها. حتى أن هناك زر مشاركة Mastodon حديث مدمج الآن بشكل مباشر.

إذا كنتم مهتمين بالكود أو بالإعداد البسيط، فلا تترددوا في التواصل معي عبر Mastodon!

في الواقع، الفكرة وراء #Winboat ممتازة، لكن التنفيذ يبدو حاليًا غير مستقر بعض الشيء. منذ التثبيت في بداية العام، كان النظام يعمل، ولكن اليوم توقف البرنامج تمامًا عن العمل.

أبلغت الصورة فجأة عن نقص في ذاكرة الوصول العشوائي (RAM). حاولت إصلاح المشكلة يدويًا، لكن للأسف أدى ذلك إلى جعل النظام غير صالح للاستخدام نهائيًا. بدلاً من استثمار المزيد من الوقت في استكشاف الأخطاء وإصلاحها، انتقلت مباشرة إلى صورة Dockurr Windows - والتي تشكل في الأساس القاعدة التقنية لـ Winboat.

رسالة خطأ

1. التحضير

نظرًا لأنني أستخدم Podman، قمت أولاً بإنشاء المجلدات المطلوبة على نظام المضيف الخاص بي. بهذه الطريقة، يتم الحفاظ على سلامة البيانات في حال احتجت إلى إعادة إنشاء الحاوية:

mkdir -p $HOME/Windows/System
mkdir -p $HOME/Windows/Shared

2. أمر التشغيل

ملاحظة هامة: استبدل العناصر النائبة في المتغيرات -e USERNAME و -e PASSWORD ببيانات اعتمادك الشخصية.

podman run -d \
  --name windows \
  -p 8006:8006 \
  --device=/dev/kvm \
  --cap-add NET_ADMIN \
  -e RAM_SIZE="8G" \
  -e USERNAME="Carsten" \
  -e PASSWORD="1234" \
  -e LANGUAGE="German" \
  -v $HOME/Windows/System:/storage:Z \
  -v $HOME/Windows/Shared:/shared:Z \
  --stop-timeout 120 \
  dockurr/windows

بمجرد أن تصبح الحاوية نشطة، يمكنك الوصول إلى نسخة Windows مباشرة عبر متصفحك:

http://127.0.0.1:8006

الحاوية قيد التشغيل

3. الخلاصة

كان عليّ تنفيذ الأمر المذكور أعلاه مرة واحدة فقط. في التشغيل اليومي، يمكن الآن التحكم في بيئة Windows بسهولة تامة عبر هذه الأوامر السريعة:

  • التشغيل: podman start windows
  • الإيقاف: podman stop windows (أو إيقاف التشغيل مباشرة من داخل Windows)
  • التحقق من الحالة: podman ps -a

روابط إضافية:

قمت بإنشاء مدونتي الخاصة — بشكل أساسي للتعرف على #NixOS بشكل أفضل. والمفاجأة أن الأمر كان بسيطاً للغاية وغير معقد.

منصة WriteFreely مناسبة جداً لهذا الغرض: فهي بسيطة، سريعة الإعداد، وخالية من الإضافات غير الضرورية. إنها مثالية للبدء فوراً وتعلم شيء جديد في نفس الوقت. الإعدادات واضحة ومنظمة بشكل مريح؛ مجرد ضبط بعض الخيارات، وتجهيز المجلد، ووضع بروكسي عكسي (Reverse Proxy) أمامها — وانتهى الأمر.

إليك كيف يبدو تكوين NixOS الحالي الخاص بي لهذا الغرض:

{ config, pkgs, ... }:

{
  services.writefreely = {
    enable = true;
    host = "blog.burningboard.org"; 
    settings = {
      server = {
        port = 8080;
        min_log_level = "debug";
      };
      app = {
        host = "https://blog.burningboard.org";
        single_user = true;
        landing = "/read";
        wf_modesty = true;
        federation = true;
        public_stats = true;
        theme = "write";
      };
    };
    stateDir = "/opt/writefreely";
  };

  # Fix für die ActivityPub-Schlüsselgenerierung: Föderation erfordert openssl
  systemd.services.writefreely.path = [ pkgs.openssl ];

  # Automatisches Erstellen des Datenverzeichnisses mit den korrekten Berechtigungen
  systemd.tmpfiles.rules = [
    "d /opt/writefreely 0700 writefreely writefreely -"
  ];

  services.caddy.virtualHosts."blog.burningboard.org".extraConfig = ''
    reverse_proxy 127.0.0.1:8080 {
      header_up Host {host}
      header_up X-Real-IP {remote_host}
      header_up X-Forwarded-For {remote_host}
      header_up X-Forwarded-Proto {scheme}
    }
  '';
}

هذا هو كل شيء باختصار. يجعل NixOS من السهل حقاً تكوين مثل هذه الخدمات بشكل نظيف والحفاظ عليها قابلة لإعادة الإنتاج (reproducible).