最初,我的博客设置是作为一个纯 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 让这类服务的配置变得非常整洁,并且易于保持可重现性。