نحوه نصب وبسرور Caddy با HTTPS خودکار
Caddy را روی Ubuntu از مخزن رسمی نصب کنید، برای سایت ایستا و پروکسی معکوس Caddyfile بنویسید، گواهی خودکار، systemd، لاگ و اشتباههای رایج هنگام مهاجرت از Nginx را بفهمید.

Caddy وبسروری است که بهصورت پیشفرض گواهی TLS میگیرد و تمدید میکند. برای VPS کوچکی که یک یا دو دامنه میزبانی میکند، کل کلاس تایمر Certbot و فایلهای قطعهٔ Nginx را حذف میکند. زبان پیکربندی (Caddyfile) کوتاه است. پروکسی معکوس، gzip و HTTP/2 ویژگی عادیاند، نه آخر هفتهای از ماژول اضافه.
Nginx هنوز برای بعضی تیمها انتخاب درست است: کانفیگ جنگآزموده دارید، یا به ماژول خیلی خاصی نیاز دارید. این راهنما برای حالت رایج دیگر است — HTTPS میخواهید که روی VPS تازهٔ Hiddence بدون حفظ قطعهٔ include کار کند. Caddy را از مخزن رسمی apt نصب میکنیم، توضیح میدهیم چطور با Let's Encrypt حرف میزند، سایت ایستا سرو میکنیم، برنامهٔ محلی را پروکسی میکنیم، چند دامنه میزبانی میکنیم، لاگ را میبینیم و دعواهای معمول پورت 80 با Apache یا Nginx قدیمی را پوشش میدهیم.
چه وقت Caddy مناسب است
HTTPS خودکار تیتر است، اما برد روزانه قطعات متحرک کمتر است. Caddy روی 80 و 443 گوش میدهد، HTTP را به HTTPS هدایت میکند و گواهیها را در پوشهٔ داده نگه میدارد. هنوز به دامنهای که به VPS اشاره کند نیاز دارید. هنوز نباید ACME را بشکنید (فایروال 80/tcp، هیچ فرایند دیگری :80 را ندزدد). گواهی wildcard به ماژول ارائهدهندهٔ DNS نیاز دارد — مسیری بلندتر از گواهی تکمیزبان.
- HTTP→HTTPS خودکار و تمدید گواهی
- Caddyfile خوانا بهجای بلوک سرور بلند
- پروکسی معکوس توانا برای Node، Python، PHP-FPM با کانفیگ اضافه، یا بکاند Docker
- HTTP/2 و پیشفرض TLS مدرن بدون صفحهٔ گستردهٔ رمز
- واحد systemd از بستهٔ رسمی
پیشنیازها
قبل از اینکه Caddy بتواند ACME HTTP-01 را ثابت کند دامنه باید به این VPS resolve شود. اگر DNS هنوز در حال انتشار است صدور شکست میخورد و دوباره تلاش میکند؛ شبیه «Caddy خراب است» به نظر میرسد در حالی که فقط DNS است. اگر Apache یا Nginx پورت 80/443 را دارند اول آنها را متوقف کنید.
- Ubuntu 22.04 یا 24.04
- رکورد A دامنه به IP سرور (و اگر IPv6 دارید AAAA)
- پورتهای 80 و 443 آزاد و در فایروال مجاز
- Root یا sudo
گام ۱: Caddy را از مخزن رسمی نصب کنید
اگر رفتار فعلی TLS و ACME میخواهید Caddy کهنهٔ تصادفی از universe پیشفرض Ubuntu نصب نکنید. پروژهٔ Caddy منبع apt را مستند کرده. بعد از نصب کاربر caddy وجود دارد و سرویس فعال است.
ssh root@YOUR_VPS_IP
apt update && apt -y install debian-keyring debian-archive-keyring apt-transport-https curl gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
apt update
apt -y install caddy
caddy version
systemctl status caddy --no-pagerگام ۲: اولین Caddyfile — سایت ایستا
Caddyfile پیشفرض /etc/caddy/Caddyfile است. آن را با دامنهٔ خود عوض کنید. اگر نام میزبان localhost نباشد بهمحض بار شدن کانفیگ Caddy سعی میکند گواهی بگیرد. فایلهای سایت را در پوشهای بگذارید که کاربر caddy بخواند (اغلب مجوز بهسبک www-data، اما بسته از کاربر caddy استفاده میکند).
mkdir -p /var/www/example
echo '<h1>It works</h1>' > /var/www/example/index.html
chown -R caddy:caddy /var/www/example
cat >/etc/caddy/Caddyfile <<'EOF'
example.com {
root * /var/www/example
file_server
encode gzip
}
EOF
caddy validate --config /etc/caddy/Caddyfile
systemctl reload caddy
# Watch issuance:
journalctl -u caddy -fگام ۳: برنامهٔ محلی را پروکسی معکوس کنید
اگر Gunicorn، Node یا Docker روی 127.0.0.1:8000 گوش میدهد Caddy باید تنها فرایند عمومی باشد. دستور reverse_proxy هدرهای Host و X-Forwarded-* را برای بیشتر برنامهها معقول جلو میفرستد. اگر برنامه URL مطلق HTTP میسازد پرچم پروکسی مورد اعتماد / HTTPS را در برنامه تنظیم کنید (Django SECURE_PROXY_SSL_HEADER، Express trust proxy و مانند آن).
app.example.com {
encode gzip
reverse_proxy 127.0.0.1:8000
}
# Several hosts in one file are normal:
# blog.example.com {
# root * /var/www/blog
# file_server
# }گام ۴: فایروال و systemd
80 و 443 را اجازه دهید. واحد Caddy برابر caddy.service است؛ اگر فرایند سالم باشد بعد از ویرایش Caddyfile همان reload کافی است. اگر متغیر محیط برای افزونهٔ DNS عوض کردید ریاستارت کامل روشنتر است. گواهیها بهطور پیشفرض زیر /var/lib/caddy/.local/share/caddy/ زندگی میکنند — اگر هنگام نصب مجدد به محدودیت نرخ اهمیت میدهید آن مسیر را در پشتیبان بگنجانید.
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
systemctl enable --now caddy
systemctl reload caddy
# Backup cert storage (path may vary slightly by version):
ls -la /var/lib/caddy/گام ۵: لاگ، فشردهسازی و هدر
لاگ دسترسی وقتی ربات مسیری را میکوبد یا 404 را اشکالزدایی میکنید کمک میکند. میتوانید بهازای سایت لاگ بگیرید. اگر برنامهٔ مرورگر میزبانی میکنید هدر امنیتی اضافه کنید؛ بستهٔ عظیم هدر را بدون فهم HSTS کپی نکنید (وقتی max-age بلند بگذارید مرورگرها یادشان میماند).
example.com {
root * /var/www/example
file_server
encode gzip
log {
output file /var/log/caddy/example.log
}
header {
X-Content-Type-Options nosniff
Referrer-Policy no-referrer-when-downgrade
-Server
}
}
mkdir -p /var/log/caddy
chown caddy:caddy /var/log/caddy
systemctl reload caddyگام ۶: PHP و اضافههای دیگر
Caddy با دستور php_fastcgi میتواند با PHP-FPM حرف بزند. برای بسیاری از میزبانهای WordPress یا Laravel کافی است، اما هنوز باید php-fpm نصب باشد و مسیر سوکت جور باشد. اگر کانفیگ PHP مربوط به Nginx بینقص دارید مهاجرت در یک عصر اختیاری است — Caddy بیشتر روی پروکسی معکوس + ایستا + TLS خودکار میدرخشد.
example.com {
root * /var/www/example
php_fastcgi unix//run/php/php8.3-fpm.sock
file_server
}
# Confirm FPM is running:
systemctl status php8.3-fpmمهاجرت از Nginx بدون غافلگیری قطعی
قبل از شروع Caddy، Nginx را متوقف کنید وگرنه سر 80/443 میجنگند. اگر IP هم جابهجا میکنید روز قبل TTL مربوط به DNS را پایین بیاورید. با curl --resolve آزمایش کنید تا قبل از عوض کردن رکورد A به VPS جدید بزنید. کانفیگ Nginx را یک هفته در git نگه دارید اگر لازم شد برگردید.
- systemctl stop nginx && systemctl disable nginx
- Caddy را نصب کنید، Caddyfile را اعتبارسنجی کنید، Caddy را شروع کنید
- curl -I --resolve example.com:443:NEW_IP https://example.com
- فقط اگر IP جدید است بعد DNS را عوض کنید
- صدور دوباره خودکار است؛ Certbot را هم روی همان نام میزبان اجرا نکنید
عیبیابی
شکست ACME تقریباً همیشه DNS، فایروال یا سرویس دیگر روی پورت 80 است. خطوط لاگ Caddy از tls.obtain حرف میزنند. اگر سایت روی HTTP کار میکند نه HTTPS، صدور هرگز تمام نشده. اگر گواهی زیاد میبینید به محدودیت نرخ Let's Encrypt خوردهاید — هنگام آزمایش از CA مرحلهای استفاده کنید نه تولید.
- شکست validate: نحو Caddyfile، آکولاد گمشده
- permission denied روی root: برای پوشهٔ سایت chown caddy
- bind: address already in use — ss -tulpn | grep -E ':80|:443'
- مهلت گواهی: از VPS برای دامنه dig +short، ufw allow 80
- 502 reverse_proxy: بکاند پایین است، یا از شبکهٔ کانتینر اشتباه به localhost پروکسی کردهاید
نکات امنیتی
پیشفرض TLS در Caddy محافظهکار است. کار شما امنیت برنامه و SSH است. API مدیریت Caddy را روی رابط عمومی روشن نکنید. نقطهٔ مدیریت پیشفرض محلی است؛ همانطور بگذارید. اگر Caddyfile از اینترنت میگیرید هر matcher را بخوانید — قطعهای که /* را به IP داخلی reverse_proxy کند میتواند پروکسی باز شود.
- API مدیریت را در معرض نگذارید
- بسته را بهروز نگه دارید
- HSTS فقط بعد از اطمینان که HTTPS برای همهٔ نام میزبان کار میکند
- نام میزبان آزمایش و تولید را جدا کنید تا محدودیت نرخ ACME حفظ شود
نکات
- caddy fmt --overwrite /etc/caddy/Caddyfile فایل را خوانا نگه میدارد
- وقتی سایت مشابه زیاد دارید از قطعهٔ import استفاده کنید
- برای Docker ایمیج caddy:alpine با Caddyfile سوارشده رایج است
- گواهی wildcard به ماژول DNS و توکن API نیاز دارد — آن توکن را محافظت کنید
- قبل از بازنویسی کل فایل journalctl -u caddy را بخوانید
Caddy روی VPS این است: بستهٔ رسمی، Caddyfile کوتاه، پورت 80/443 باز، DNS که از قبل به سرور اشاره میکند، و systemd reload بعد از ویرایش. بهعنوان سرور فایل ایستا یا پروکسی معکوس جلوی Gunicorn، Node یا Docker استفاده کنید. HTTPS خودکار وقتی کار میکند که ACME بتواند روی پورت 80 جواب بدهد؛ اگر صدور شکست، قبل از سرزنش Caddy، DNS و تداخل پورت را درست کنید. اگر زیاد نصب مجدد میکنید از /var/lib/caddy پشتیبان بگیرید.