در ابتدا، تنظیمات وبلاگ من به عنوان یک پروژه صرفاً IPv6 از طریق WireGuard برنامهریزی شده بود، زیرا کل سیستم روی یک سرور خانگی اجرا میشود (ضمناً میتوانید آدرسهای IPv6 رایگان را از route64.org دریافت کنید). برای افزایش دسترسیپذیری، اکنون یک پروکسی IPv4 خارجی اضافه کردهام (با تشکر از @Larvitz).
با این حال، بلافاصله مشکلات SSL به وجود آمد: از آنجایی که در ابتدا هر دو رکورد A و AAAA از طریق پروکسی عبور میکردند، اعتبارسنجی Let's Encrypt روی سرور من با شکست مواجه شد.
راه حل: «هک IPv6»
راه حل این بود که رکورد AAAA را به طور صریح مستقیماً به IP وایرگارد (WireGuard) سرورم هدایت کنم، به جای اینکه آن را هم از طریق پروکسی بفرستم.
- دامنه:
blog.burningboard.org
- رکورد A (پروکسی):
194.28.98.217
- رکورد AAAA (سرور):
2a11:6c7:f05:a8::2 (WireGuard)
از طریق این رکورد مستقیم AAAA به IP وایرگارد من، Let’s Encrypt همچنان مستقیماً از طریق IPv6 به سرور من دسترسی پیدا میکند (زیرا رکورد AAAA به طور پیشفرض اولویت دارد) و گواهی SSL را صادر میکند. ترافیک IPv4 توسط پروکسی به صورت رمزگذاری شده به من منتقل میشود.
پیکربندی نهایی
برای اینکه ارتباط بدون مشکل برقرار شود، مجبور شدیم سرورهای Caddy را تنظیم کنیم:
۱. روی سرور من (NixOS، blog.nix)
برای اینکه IPهای واقعی بازدیدکنندگان به درستی دریافت شوند و توسط IP پروکسی جایگزین نشوند، باید پروکسی به عنوان قابل اعتماد (trusted) علامتگذاری شود:
services.caddy.globalConfig = ''
servers {
trusted_proxies static 2a06:9801:1c:1000::10
}
'';
۲. روی پروکسی خارجی (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 ساده باقی میماند.
🌍 جهانیتر از همیشه: وبلاگ من اکنون از ترجمه به ۴۳ زبان پشتیبانی میکند. بله، حتی زبان کلینگون! 🖖 (Qapla'!)

برنامه این بود که یک ترجمه کاملاً خودکار و آنی بر اساس تشخیص زبان مرورگر داشته باشیم. اسپویلر: فقط تا حدودی جواب داد. مشخص است که: هوش مصنوعی خیرهکننده است، اما هنوز دقیقاً به آن نقطهای که ما میخواهیم نرسیده است.
راهکار: اکنون من هر پست را از قبل به تمام زبانهای تعیینشده ترجمه میکنم که برای موتورهای جستجو (SEO) نیز بسیار بهتر است. اگر تشخیص خودکار عمل نکرد، میتوانید از طریق آیکون کره زمین، زبان مورد نظر خود را به صورت دستی انتخاب کنید که سپس به سادگی از طریق کوکی ذخیره میشود.
ترجمهها اکنون با Gemini 3 Flash انجام میشوند که نتایج فوقالعاده خوبی ارائه میدهد. البته باید حواستان به هوش مصنوعی باشد: در اولین اجرای دستهجمعی، تگها هم به اشتباه ترجمه شدند که قطعاً طبق برنامه نبود.
کد همچنان در دسترس است (اگر علاقهمند بودید، کافیست به من پیام بدهید) 👍 اما توجه داشته باشید که سیستم اکنون به یک کلید اختصاصی Gemini API 🔑 نیاز دارد.
من به سرعت وبلاگم را از WriteFreely به یک سیستم توسعهیافته توسط خودم تغییر دادم: MD-Blog (که MD طبیعتاً مخفف Markdown است). محرک این کار، یک بهروزرسانی ناموفق در سیستم قدیمی بود – اما در نهایت، این اتفاق انگیزه کاملی شد تا همه چیز را به طور ریشهای ساده کنم و کنترل کامل روی طراحی را به دست آورم.
هسته اصلی این سیستم، فایلهای ساده Markdown در پوشه data/ هستند که در زمان اجرا به HTML مدرن تبدیل میشوند. نتیجه کار بسیار سریع است، نیازی به پایگاه داده ندارد و به لطف سیستم طراحی اختصاصی (شامل حالت تیره یا Dark Mode)، اکنون دقیقاً همانطور است که تصور میکردم. حتی یک دکمه اشتراکگذاری Mastodon مدرن نیز اکنون مستقیماً در آن تعبیه شده است.
اگر به کدها یا این راهاندازی ساده و سبک علاقه دارید، خوشحال میشوم از طریق Mastodon با من در تماس باشید!
در واقع ایده پشت #Winboat عالی است، اما به نظر میرسد پیادهسازی آن در حال حاضر کمی ناپایدار باشد. از زمان نصب در ابتدای سال، سیستم به خوبی کار میکرد، اما امروز نرمافزار کاملاً از کار افتاد.
ایمیج ناگهان خطای کمبود حافظه رم (RAM) داد. سعی کردم مشکل را به صورت دستی حل کنم، اما متأسفانه این کار باعث شد سیستم در نهایت کاملاً غیرقابل استفاده شود. به جای صرف زمان بیشتر برای عیبیابی، مستقیماً به ایمیج ویندوز Dockurr مهاجرت کردم – که در هر صورت پایه فنی Winboat را تشکیل میدهد.

۱. آمادهسازی
از آنجایی که من از Podman استفاده میکنم، ابتدا دایرکتوریهای مورد نیاز را در سیستم میزبان خود ایجاد کردم. به این ترتیب، در صورت نیاز به بازسازی کانتینر، یکپارچگی دادهها حفظ میشود:
mkdir -p $HOME/Windows/System
mkdir -p $HOME/Windows/Shared
۲. دستور اجرا
نکته مهم: در متغیرهای -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
به محض اینکه کانتینر فعال شد، میتوانید نمونه ویندوز را مستقیماً از طریق مرورگر خود باز کنید:
http://127.0.0.1:8006

۳. جمعبندی
من فقط یک بار نیاز به اجرای دستور بالا داشتم. در استفاده روزمره، اکنون میتوان محیط ویندوز را به راحتی با این دستورات کوتاه مدیریت کرد:
- شروع:
podman start windows
- توقف:
podman stop windows (یا خاموش کردن مستقیم از داخل ویندوز)
- بررسی وضعیت:
podman ps -a
لینکهای مفید:
من یک وبلاگ شخصی برای خودم راهاندازی کردم — عمدتاً برای اینکه با #NixOS بیشتر آشنا شوم. بهطور غافلگیرکنندهای، همه چیز خیلی ساده پیش رفت.
WriteFreely برای این کار واقعاً مناسب است: مینیمال، با راهاندازی سریع و بدون بار اضافی. گزینهای عالی برای شروع ساده و یادگیری در حین کار. پیکربندی آن بهطرز دلپذیری واضح است. چند گزینه را تنظیم کردم، دایرکتوری را آماده کردم، یک Reverse Proxy جلوی آن قرار دادم — و تمام.
پیکربندی فعلی 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}
}
'';
}
اساساً کل ماجرا همین بود. NixOS واقعاً پیکربندی تمیز و بازتولیدپذیر چنین سرویسهایی را بسیار آسان میکند.