Originally, my blog setup was planned as a pure IPv6 project via WireGuard, as the whole thing is hosted on a home server (by the way, you can get free IPv6 addresses at route64.org). To increase accessibility, I have now added an external IPv4 proxy (thanks to @Larvitz).
However, this immediately caused SSL issues: since both the A and AAAA records were originally routed through the proxy, the Let's Encrypt validation on my server failed.
The Solution: The "IPv6 Hack"
The solution was to explicitly point the AAAA record directly to my server's WireGuard IP instead of routing it through the proxy as well.
- Domain:
blog.burningboard.org
- A-Record (Proxy):
194.28.98.217
- AAAA-Record (Server):
2a11:6c7:f05:a8::2 (WireGuard)
With this direct AAAA record pointing to my WireGuard IP, Let's Encrypt continues to reach my server directly via IPv6 (since the AAAA record is prioritized by default) and issues the SSL certificate. IPv4 traffic is forwarded to me by the proxy in encrypted form.
The Final Configuration
To ensure smooth communication, we had to adjust the Caddy servers:
1. On my server (NixOS, blog.nix)
To ensure that the real visitor IPs arrive correctly and are not overwritten by the proxy's IP, the proxy must be marked as trusted:
services.caddy.globalConfig = ''
servers {
trusted_proxies static 2a06:9801:1c:1000::10
}
'';
2. On the external proxy (Caddy)
To ensure the proxy addresses my server correctly via HTTPS, it must send the hostname (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
}
}
The blog is now accessible via IPv4 and IPv6, securely encrypted, and my home IP remains private! ๐
First things first: The familiar Markdown files remain the foundation โ I'm simply a big fan of this straightforward solution. But under the hood, a lot has changed:
I've tweaked the setup quite a bit:
๐ MD-Files: The blog structure remains simple, based on Markdown.
๐ More global than ever: My blog now supports translations in 43 languages. Yes, including Klingon! ๐ (Qapla'!)

The plan was to have fully automated real-time translation based on browser language detection. Spoiler: It only partially worked. You can tell: AI is impressive, but not quite "there" yet where we'd like it to be.
The solution: I now simply pre-translate every post into all specified languages, which is also much better for search engines (SEO). If the automatic detection doesn't work, you can manually set your preferred language via the globe icon, which is then easily saved via a cookie.
The translations are now performed using Gemini 3 Flash, which delivers surprisingly good results. However, you have to keep a close eye on the AI: In the first bulk run, the tags were mistakenly translated as well, which of course wasn't the plan.
The code is still available (just send me a message if you're interested) ๐ But please note that the system now requires its own Gemini API Key ๐.
I have quickly switched my blog from WriteFreely to a custom development: MD-Blog (the MD naturally stands for Markdown). The trigger was a failed update of the old system โ but in the end, it was the perfect impetus to radically simplify everything and gain full control over the design.
The core consists of simple Markdown files in the data/ folder, which are converted into modern HTML at runtime. The result is lightning fast, works without a database, and thanks to a custom design system (including dark mode), it now looks exactly as I imagined. Even a modern Mastodon share button is now directly on board.
If you are interested in the code or the lean setup, feel free to reach out to me via Mastodon!