Спочатку налаштування мого блогу планувалося як суто IPv6-проєкт через WireGuard, оскільки все це працює на домашньому сервері (до речі, безкоштовні IPv6-адреси можна отримати на route64.org). Щоб покращити доступність, я додав зовнішній IPv4-проксі (дякую @Larvitz).
Однак одразу виникли проблеми з SSL: оскільки спочатку і запис A, і запис AAAA проходили через проксі, перевірка Let's Encrypt на моєму сервері не вдалася.
Рішення: «IPv6-хак»
Рішення полягало в тому, щоб спрямувати запис 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'!)

Планувався повністю автоматичний переклад у реальному часі на основі розпізнавання мови браузера. Спойлер: це спрацювало лише частково. Стає зрозуміло: ШІ вражає, але він ще не зовсім «там», де нам хотілося б.
Рішення: тепер я просто заздалегідь перекладаю кожен допис на всі визначені мови, що також значно краще для пошукових систем (SEO). Якщо автоматичне розпізнавання раптом не спрацює, ви можете вручну вибрати бажану мову за допомогою іконки глобуса, яка потім легко збережеться через cookie.
Переклади тепер виконуються за допомогою Gemini 3 Flash, що дає напрочуд гарні результати. Однак за ШІ варто пильно стежити: під час першого масового прогону помилково були перекладені й теги, що, звісно, не планувалося.
Код, як і раніше, доступний (якщо цікаво — просто напишіть мені) 👍 Але зауважте, що системі тепер потрібен власний Gemini API Key 🔑.
Я без вагань перевів свій блог з WriteFreely на власну розробку: MD-Blog (MD, звісно, означає Markdown). Приводом стало невдале оновлення старої системи — але зрештою це стало ідеальним поштовхом, щоб радикально все спростити та отримати повний контроль над дизайном.
Основою є прості Markdown-файли в папці data/, які під час виконання перетворюються на сучасний HTML. Результат працює блискавично, не потребує бази даних і завдяки власній системі дизайну (включаючи темний режим) тепер виглядає саме так, як я собі уявляв. Навіть сучасна кнопка «Поділитися в Mastodon» тепер інтегрована безпосередньо.
Якщо вас цікавить код або цей лаконічний сетап, зв'яжіться зі мною через Mastodon!
Насправді ідея #Winboat чудова, але реалізація наразі здається дещо нестабільною. З моменту встановлення на початку року система працювала, але сьогодні програмне забезпечення повністю відмовилося функціонувати.
Образ раптово повідомив про недостатню кількість оперативної пам'яті (RAM). Я намагався виправити проблему вручну, але це, на жаль, остаточно вивело систему з ладу. Замість того, щоб витрачати більше часу на пошук помилок, я одразу перейшов на Windows-образ Dockurr — він і так є технічною основою 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 дійсно дозволяє легко та чисто налаштовувати такі сервіси, зберігаючи їх відтворюваність.