הבלוג שלי // ארכיון דיגיטלי

מחשבות, פרויקטים והערות טכניות

במקור, הגדרת הבלוג שלי תוכננה כפרויקט IPv6 בלבד דרך WireGuard, מכיוון שהכל פועל על שרת ביתי (אגב, ניתן לקבל כתובות IPv6 בחינם ב-route64.org). כדי לשפר את הזמינות, הוספתי כעת פרוקסי IPv4 חיצוני (תודה ל-@Larvitz).

עם זאת, מיד צצו בעיות SSL: מכיוון שבמקור גם רשומת ה-A וגם רשומת ה-AAAA עברו דרך הפרוקסי, אימות ה-Let's Encrypt בשרת שלי נכשל.

הפתרון: ה-„IPv6-Hack“

הפתרון היה לכוון את רשומת ה-AAAA באופן מפורש ישירות לכתובת ה-WireGuard של השרת שלי, במקום להעביר אותה גם כן דרך הפרוקסי.

  • דומיין: blog.burningboard.org
  • רשומת A (פרוקסי): 194.28.98.217
  • רשומת AAAA (שרת): 2a11:6c7:f05:a8::2 (WireGuard)

באמצעות רשומת ה-AAAA הישירה הזו לכתובת ה-WireGuard שלי, Let’s Encrypt ממשיך להגיע לשרת שלי ישירות דרך IPv6 (מכיוון שרשומת AAAA מקבלת עדיפות כברירת מחדל) ומנפיק את תעודת ה-SSL. תעבורת ה-IPv4 מועברת אליי מהפרוקסי כשהיא מוצפנת.

הקונפיגורציה הסופית

כדי שהתקשורת תעבוד בצורה חלקה, היינו צריכים להתאים את שרתי ה-Caddy:

1. בשרת שלי (NixOS, blog.nix)

כדי שכתובות ה-IP האמיתיות של המבקרים יגיעו בצורה נכונה ולא יידרסו על ידי כתובת ה-IP של הפרוקסי, יש לסמן אותו כנאמן (trusted):

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 המוכרים נשארים הבסיס – אני פשוט מעריץ גדול של הפתרון הפשוט הזה. אבל מתחת למכסה המנוע, הרבה דברים השתנו:

שיניתי כמה דברים בהגדרות (Setup):

📂 קבצי MD: מבנה הבלוג נשאר פשוט ומבוסס על Markdown.

🌍 גלובלי יותר מאי פעם: הבלוג שלי תומך כעת בתרגומים ל-43 שפות. כן, כולל קלינגונית! 🖖 (!Qapla)

התכנון היה תרגום אוטומטי לחלוטין בזמן אמת המבוסס על זיהוי שפת הדפדפן. ספוילר: זה עבד רק באופן חלקי. אפשר לראות שה-AI מרשימה, אבל היא עדיין לא לגמרי "שם", איפה שהיינו רוצים שהיא תהיה.

הפתרון: אני פשוט מתרגם כעת כל פוסט מראש לכל השפות שהוגדרו, מה שגם הרבה יותר טוב לקידום אתרים (SEO). אם הזיהוי האוטומטי לא עובד, תוכלו להגדיר את השפה המועדפת עליכם ידנית דרך אייקון הגלובוס, והיא תישמר בפשטות באמצעות Cookie.

התרגומים מבוצעים כעת באמצעות Gemini 3 Flash, שמספק תוצאות טובות להפליא. עם זאת, כדאי לפקוח עין על ה-AI: בסבב התרגום המסיבי הראשון, גם התגיות תורגמו בטעות, מה שכמובן לא היה מתוכנן.

הקוד עדיין זמין (פשוט שלחו לי הודעה אם אתם מעוניינים) 👍 שימו לב שהמערכת דורשת כעת מפתח API של Gemini משלה 🔑.

החלטתי להעביר את הבלוג שלי מ-WriteFreely לפיתוח עצמי: MD-Blog (ה-MD מייצג כמובן את Markdown). הטריגר היה עדכון שנכשל במערכת הישנה – אבל בסופו של דבר זו הייתה הדחיפה המושלמת לפשט הכל באופן רדיקלי ולהשיג שליטה מלאה על העיצוב.

לב המערכת הוא קבצי Markdown פשוטים בתיקיית data/, שמתורגמים בזמן ריצה ל-HTML מודרני. התוצאה מהירה במיוחד, פועלת ללא מסד נתונים, ובזכות מערכת עיצוב עצמאית (כולל מצב כהה) היא נראית עכשיו בדיוק כפי שדמיינתי. אפילו כפתור שיתוף למסטודון מודרני כבר כלול בפנים.

אם אתם מעוניינים בקוד או בהגדרה (Setup) הרזה, אתם מוזמנים ליצור איתי קשר דרך מסטודון!

הרעיון מאחורי #Winboat הוא מצוין, אבל נראה שהביצוע כרגע עדיין מעט לא יציב. מאז ההתקנה בתחילת השנה המערכת אמנם עבדה, אך היום התוכנה הפסיקה לתפקד לחלוטין.

האימג' (Image) דיווח פתאום על זיכרון עבודה (RAM) לא מספיק. ניסיתי לתקן את הבעיה ידנית, אך לרוע המזל זה הפך את המערכת לבלתי שמישה לחלוטין. במקום להשקיע זמן נוסף באיתור תקלות, עברתי ישירות ל-Dockurr Windows-Image – שבכל מקרה מהווה את הבסיס הטכני של Winboat.

הודעת שגיאה

1. הכנות

מכיוון שאני משתמש ב-Podman, יצרתי תחילה את הספריות הדרושות במערכת המארחת (Host) שלי. כך נשמרת שלמות הנתונים במקרה שיהיה צורך ליצור את הקונטיינר מחדש:

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";
  };

  # תיקון ליצירת מפתחות ActivityPub: פדרציה דורשת openssl
  systemd.services.writefreely.path = [ pkgs.openssl ];

  # יצירה אוטומטית של ספריית הנתונים עם ההרשאות הנכונות
  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 באמת הופכת את ההגדרה של שירותים כאלה לנקיים וקלים לשחזור.