నా బ్లాగ్ // డిజిటల్ ఆర్కైవ్

ఆలోచనలు, ప్రాజెక్టులు మరియు సాంకేతిక గమనికలు

నేను ఇప్పుడు నా NixOS హోమ్ సర్వర్ బ్యాకప్‌ను మార్చాను మరియు సాధారణ రోజువారీ స్క్రిప్ట్‌కు బదులుగా గంటవారీ బ్యాకప్‌కు మార్చాను. నా స్నేహితుడు నిర్వహించే మాస్టోడాన్ (Mastodon) ఇన్‌స్టన్స్‌లో ఉన్నంత అద్భుతంగా ఇది లేదు – అక్కడ ప్రతి 20 నిమిషాలకు ఒక ZFS స్నాప్‌షాట్ ఉంటుంది – కానీ ఈ పరిష్కారంతో కూడా నేను సంతృప్తిగా ఉన్నాను. మరియు నేను చెప్పాలి, NixOS నాకు రోజురోజుకూ మరింత నచ్చుతోంది. AI (కృత్రిమ మేధస్సు) లేకుండా, నేను అర్థం చేసుకోలేనంత క్లిష్టంగా ఇది ఉండేది, కానీ ఇప్పుడు నేను కనీసం సిద్ధంగా ఉన్న Nix ఫైల్‌లను చదవగలుగుతున్నాను. సర్వర్‌ను సాధారణ లైనక్స్‌కు మార్చాలని ఒకప్పుడు అనుకున్నాను, కానీ ఇది ఇంత బాగా పనిచేస్తున్నంత కాలం...

  1. /etc/nixos: మొత్తం NixOS కాన్ఫిగరేషన్ (అన్ని .nix ఫైల్‌లు).

  2. /opt/minecraft: Minecraft సర్వర్ యొక్క అన్ని ప్రపంచాలు మరియు డేటా.

  3. /opt/satisfactory: Satisfactory సర్వర్ యొక్క గేమ్ సేవ్స్ మరియు కాన్ఫిగరేషన్.

  4. /opt/Blog: బ్లాగ్ యొక్క సోర్స్ కోడ్ మరియు కంటెంట్.

  5. /opt/ui: Mastodon-UI ఫైల్‌లు.

  6. /opt/audiobookshelf: ఆడియోబుక్స్ మరియు దానికి సంబంధించిన డేటాబేస్.

ఇదంతా RClone ద్వారా మౌంట్ చేయబడిన S3 స్టోరేజ్‌లో సేవ్ చేయబడుతుంది.

NixOS కాన్ఫిగరేషన్


{ config, pkgs, ... }:

{
  # BorgBackup కాన్ఫిగరేషన్
  services.borgbackup.jobs.hourly = {
    # S3-మౌంట్‌లో రిపోజిటరీ పాత్
    repo = "/opt/S3/Backup/NixOSHomeServer_Borg";

    # పాస్‌వర్డ్ అవసరం లేదు
    encryption.mode = "none";

    # మరింత స్థలాన్ని ఆదా చేయడానికి కంప్రెషన్
    compression = "auto,zstd";

    # బ్యాకప్ చేయవలసిన పాత్‌లు
    paths = [
      "/etc/nixos"
      "/opt/minecraft"
      "/opt/satisfactory"
      "/opt/Blog"
      "/opt/ui"
      "/opt/audiobookshelf"
    ];

    # గంటవారీ అమలు
    startAt = "hourly";

    # రిపోజిటరీ లేకపోతే ఆటోమేటిక్‌గా ఇనిషియలైజ్ చేయండి
    doInit = true;

    # నిలుపుదల నియమాలు (Pruning)
    prune.keep = {
      within = "1d"; # గత 24 గంటల అన్ని స్నాప్‌షాట్‌లు
      daily = 7;
      weekly = 4;
      monthly = 12;
    };
  };

  # Borg ప్రారంభమయ్యే ముందు S3-మౌంట్ సిద్ధంగా ఉందని నిర్ధారించుకోండి
  systemd.services.borgbackup-job-hourly = {
    requires = [ "rclone-s3-mount.service" ];
    after = [ "rclone-s3-mount.service" ];
  };
}

ప్రారంభంలో నా బ్లాగ్ సెటప్ హోమ్ సర్వర్‌పై నడుస్తున్నందున వైర్‌గార్డ్ (WireGuard) ద్వారా కేవలం IPv6-ప్రాజెక్ట్ గా ప్లాన్ చేయబడింది (మీరు route64.org నుండి ఉచిత IPv6 అడ్రస్‌లను పొందవచ్చు). యాక్సెసిబిలిటీని పెంచడానికి, నేను ఇప్పుడు ఒక ఎక్స్‌టర్నల్ IPv4 ప్రాక్సీని జోడించాను (@Larvitz కి ధన్యవాదాలు).

అయితే, దీనివల్ల వెంటనే SSL సమస్యలు తలెత్తాయి: మొదట A మరియు AAAA రికార్డ్‌లు రెండూ ప్రాక్సీ ద్వారా వెళ్లడం వల్ల, నా సర్వర్‌పై Let's Encrypt వ్యాలిడేషన్ విఫలమైంది.

పరిష్కారం: „IPv6-హ్యాక్“

దీనికి పరిష్కారం ఏమిటంటే, AAAA-రికార్డ్ ను ప్రాక్సీ ద్వారా పంపకుండా నేరుగా నా సర్వర్ యొక్క వైర్‌గార్డ్ IPకి పంపడం.

  • డొమైన్: blog.burningboard.org
  • A-రికార్డ్ (ప్రాక్సీ): 194.28.98.217
  • AAAA-రికార్డ్ (సర్వర్): 2a11:6c7:f05:a8::2 (WireGuard)

నా వైర్‌గార్డ్ IPకి ఈ డైరెక్ట్ AAAA-రికార్డ్ ద్వారా, 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 ఫైళ్లే ప్రాతిపదికగా ఉంటాయి – ఈ సరళమైన పరిష్కారం అంటే నాకు చాలా ఇష్టం. కానీ లోపల చాలా మార్పులు జరిగాయి:

నేను సెటప్‌లో కొన్ని మార్పులు చేశాను:

📂 MD-ఫైళ్లు: బ్లాగ్ నిర్మాణం మార్క్‌డౌన్ ఆధారంగా సరళంగానే ఉంటుంది.

🌍 ఎప్పటికంటే ఎక్కువగా గ్లోబల్: నా బ్లాగ్ ఇప్పుడు 43 భాషల్లో అనువాదాలకు సపోర్ట్ చేస్తుంది. అవును, క్లింగన్ (Klingon) భాషతో సహా! 🖖 (Qapla'!)

బ్రౌజర్ భాషా గుర్తింపు ఆధారంగా పూర్తి ఆటోమేటిక్ రియల్-టైమ్ అనువాదాన్ని ప్లాన్ చేశాను. స్పాయిలర్: ఇది పాక్షికంగా మాత్రమే పనిచేసింది. ఒకటి అర్థమవుతోంది: AI ఆకట్టుకునేలా ఉంది, కానీ మనం కోరుకున్న స్థాయికి ఇంకా చేరుకోలేదు.

పరిష్కారం: నేను ఇప్పుడు ప్రతి పోస్ట్‌ను ముందుగానే అన్ని నిర్ణీత భాషల్లోకి అనువదిస్తున్నాను, ఇది సెర్చ్ ఇంజన్ల (SEO) కోసం కూడా చాలా మంచిది. ఒకవేళ ఆటోమేటిక్ గుర్తింపు పనిచేయకపోతే, మీరు గ్లోబ్ ఐకాన్ ద్వారా మీకు నచ్చిన భాషను మాన్యువల్‌గా ఎంచుకోవచ్చు, అది కుకీ (Cookie) ద్వారా సులభంగా సేవ్ చేయబడుతుంది.

అనువాదాలు ఇప్పుడు Gemini 3 Flashతో చేయబడుతున్నాయి, ఇది అద్భుతమైన ఫలితాలను ఇస్తోంది. అయితే, AI పనితీరును జాగ్రత్తగా గమనించాలి: మొదటి బల్క్ రన్‌లో పొరపాటున ట్యాగ్‌లు (Tags) కూడా అనువదించబడ్డాయి, ఇది నేను అనుకున్నది కాదు.

కోడ్ ఇంకా అందుబాటులో ఉంది (ఆసక్తి ఉంటే నాకు మెసేజ్ చేయండి) 👍 అయితే, ఈ సిస్టమ్‌కు ఇప్పుడు సొంత Gemini API Key 🔑 అవసరమని గమనించండి.

నేను నా బ్లాగును WriteFreely నుండి నా సొంతంగా అభివృద్ధి చేసిన MD-Blogకి మార్చాను (ఇక్కడ MD అంటే సహజంగానే Markdown). పాత సిస్టమ్ అప్‌డేట్ విఫలం కావడమే దీనికి కారణం – కానీ చివరికి, ప్రతిదీ సరళీకరించడానికి మరియు డిజైన్‌పై పూర్తి నియంత్రణను పొందడానికి ఇది ఒక గొప్ప అవకాశంగా మారింది.

దీని ప్రధాన భాగం data/ ఫోల్డర్‌లోని సాధారణ Markdown ఫైల్‌లు, ఇవి రన్-టైమ్‌లో ఆధునిక HTMLగా మార్చబడతాయి. దీని ఫలితం చాలా వేగంగా ఉంటుంది, దీనికి ఎటువంటి డేటాబేస్ అవసరం లేదు మరియు నా స్వంత డిజైన్ సిస్టమ్ (డార్క్ మోడ్‌తో సహా) కారణంగా ఇప్పుడు నేను ఊహించినట్లే కనిపిస్తోంది. ఇప్పుడు ఇందులో ఆధునిక Mastodon-Share-Button కూడా నేరుగా అందుబాటులో ఉంది.

మీకు కోడ్ లేదా ఈ సింపుల్ సెటప్ గురించి ఆసక్తి ఉంటే, Mastodon ద్వారా నన్ను సంప్రదించండి!

నిజానికి #Winboat వెనుక ఉన్న ఆలోచన అద్భుతమైనది, కానీ ప్రస్తుతం దాని అమలు కొంచెం అస్థిరంగా ఉన్నట్లు అనిపిస్తోంది. ఈ ఏడాది ప్రారంభంలో ఇన్‌స్టాల్ చేసినప్పటి నుండి సిస్టమ్ బాగానే నడిచింది, కానీ ఈ రోజు సాఫ్ట్‌వేర్ పూర్తిగా పనిచేయడం మానేసింది.

ఇమేజ్ అకస్మాత్తుగా సరిపోని మెమరీ (RAM) గురించి హెచ్చరించింది. నేను సమస్యను మాన్యువల్‌గా పరిష్కరించడానికి ప్రయత్నించాను, కానీ దురదృష్టవశాత్తు అది సిస్టమ్‌ను పూర్తిగా పనికిరాకుండా చేసింది. లోపాలను వెతకడానికి మరింత సమయం వృథా చేయకుండా, నేను నేరుగా Dockurr Windows-Imageకి మారాను – ఇది ఎలాగూ 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 చాలా బాగా సరిపోతుంది: ఇది మినిమలిస్టిక్, త్వరగా సెటప్ చేయవచ్చు మరియు అనవసరమైన హంగులు ఏవీ ఉండవు. పనిని ప్రారంభించడానికి మరియు నేర్చుకోవడానికి ఇది సరైనది. దీని కాన్ఫిగరేషన్ చాలా స్పష్టంగా ఉంటుంది. కొన్ని ఆప్షన్లను సెట్ చేయడం, డైరెక్టరీని సిద్ధం చేయడం, రివర్స్ ప్రాక్సీని జోడించడం — అంతే, పని పూర్తయింది.

దీని కోసం నా ప్రస్తుత 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}
    }
  '';
}

ముఖ్యంగా చెప్పాలంటే ఇంతే. ఇటువంటి సర్వీసులను చక్కగా కాన్ఫిగర్ చేయడానికి మరియు వాటిని రీప్రొడ్యూసిబుల్ (reproducible) గా ఉంచడానికి NixOS నిజంగా చాలా సులభతరం చేస్తుంది.