我的博客 // 数字存档

想法、项目和技术笔记

最初,我的博客设置是作为一个纯 IPv6 项目通过 WireGuard 运行的,因为整个系统部署在家庭服务器上(顺便提一下,你可以在 route64.org 获取免费的 IPv6 地址)。为了提高可访问性,我现在增加了一个外部 IPv4 代理(感谢 @Larvitz)。

但这立即引发了 SSL 问题:由于最初 A 记录和 AAAA 记录都指向代理,导致我服务器上的 Let's Encrypt 验证失败。

解决方案:“IPv6 Hack”

解决方案是将 AAAA 记录显式地直接指向我服务器的 WireGuard IP,而不是也通过代理转发。

  • 域名: blog.burningboard.org
  • A 记录 (代理): 194.28.98.217
  • AAAA 记录 (服务器): 2a11:6c7:f05:a8::2 (WireGuard)

通过将 AAAA 记录直接指向我的 WireGuard IP,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'!)

原计划是基于浏览器语言识别实现全自动实时翻译。剧透一下:只成功了一部分。你会发现:AI 确实令人印象深刻,但还没有完全达到我们预期的水平。

解决方案:我现在预先将每篇文章翻译成所有设定的语言,这对搜索引擎优化 (SEO) 也大有裨益。如果自动识别失效,你可以通过地球图标手动设置首选语言,该设置将通过 Cookie 简单地保存。

翻译现在使用 Gemini 3 Flash 完成,效果出奇地好。不过,还是得盯着点 AI:在第一次批量处理中,标签也被错误地翻译了,这显然不在计划之内。

代码仍然可用(感兴趣的话直接给我发消息)👍 但请注意,系统现在需要一个独立的 Gemini API Key 🔑。

我果断地将我的博客从 WriteFreely 切换到了自主开发的系统:MD-Blog(MD 自然代表 Markdown)。触发点是旧系统的一次更新失败——但最终,这成为了彻底简化一切并获得对设计完全控制权的完美契机。

核心是 data/ 文件夹中简单的 Markdown 文件,它们在运行时被转换为现代 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 非常适合这个需求:极简、部署迅速且没有多余的负担。它是快速上手并顺便学习新知识的完美选择。配置过程也非常清晰明了:设置几个选项,准备好目录,配置好反向代理——大功告成。

这是我目前的 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 让这类服务的配置变得非常整洁,并且易于保持可重现性。