วิธีติดตั้งเว็บเซิร์ฟเวอร์ Caddy พร้อม HTTPS อัตโนมัติ
ติดตั้ง Caddy บน Ubuntu จากที่เก็บทางการ เขียน Caddyfile สำหรับไซต์สแตติกและรีเวิร์สพร็อกซี เข้าใจใบรับรองอัตโนมัติ systemd ล็อก และความผิดพลาดทั่วไปเมื่อย้ายจาก Nginx

Caddy คือเว็บเซิร์ฟเวอร์ที่ขอและต่ออายุใบรับรอง TLS เป็นค่าเริ่มต้น สำหรับ VPS เล็กที่โฮสต์โดเมนหนึ่งหรือสองชื่อ นั่นตัดทั้งชั้นของตัวจับเวลา Certbot และไฟล์ snippet Nginx ภาษาคอนฟิก (Caddyfile) สั้น รีเวิร์สพร็อกซี gzip และ HTTP/2 เป็นฟีเจอร์ปกติ ไม่ใช่สุดสัปดาห์ของโมดูลเพิ่ม
Nginx ยังเป็นตัวเลือกถูกสำหรับบางร้าน: คุณมีคอนฟิกที่ผ่านสนามรบแล้ว หรือต้องการโมดูลเฉพาะมาก คู่มือนี้สำหรับกรณีทั่วไปอีกแบบ — คุณต้องการ HTTPS ที่ใช้ได้บน VPS Hiddence ใหม่โดยไม่ต้องท่อง include snippet เราจะติดตั้ง Caddy จากที่เก็บ apt ทางการ อธิบายว่ามันคุยกับ Let's Encrypt อย่างไร ให้บริการไซต์สแตติก พร็อกซีแอปท้องถิ่น โฮสต์หลายโดเมน ดูล็อก และจัดการการแย่งพอร์ต 80 กับ Apache หรือ Nginx เก่า
เมื่อใดที่ Caddy เหมาะ
HTTPS อัตโนมัติเป็นหัวข้อ แต่ชัยชนะรายวันคือชิ้นส่วนที่ขยับน้อยลง Caddy ฟัง 80 และ 443 เปลี่ยน HTTP ไป HTTPS และเก็บใบรับรองในไดเรกทอรีข้อมูล คุณยังต้องมีโดเมนชี้ไป VPS คุณยังต้องไม่ทำ ACME พัง (ไฟร์วอลล์ 80/tcp ไม่มีโปรเซสอื่นขโมย :80) ใบรับรองไวลด์การ์ดต้องมีโมดูลผู้ให้บริการ DNS — นั่นเส้นยาวกว่าใบรับรองโฮสต์เดียว
- HTTP→HTTPS อัตโนมัติและการต่ออายุใบรับรอง
- Caddyfile อ่านง่ายแทนบล็อก server ยาว
- รีเวิร์สพร็อกซีที่ทำได้สำหรับ Node, Python, PHP-FPM ผ่านคอนฟิกเพิ่ม หรือแบ็กเอนด์ Docker
- HTTP/2 และค่าเริ่มต้น TLS สมัยใหม่โดยไม่มีสเปรดชีตไซเฟอร์
- ยูนิต systemd จากแพ็กเกจทางการ
ความต้องการ
โดเมนต้องแก้ไปที่ VPS นี้ก่อนที่ Caddy จะพิสูจน์ ACME HTTP-01 ได้ ถ้า DNS ยังแพร่ Caddy จะออกใบรับรองไม่สำเร็จแล้วลองใหม่ ดูเหมือน 'Caddy พัง' ทั้งที่เป็นแค่ DNS หยุด Apache หรือ Nginx ก่อนถ้าพวกมันครอง 80/443
- Ubuntu 22.04 หรือ 24.04
- เรคคอร์ด A ของโดเมนไป IP ของ VPS (และ AAAA ถ้าใช้ IPv6)
- พอร์ต 80 และ 443 ว่างและอนุญาตในไฟร์วอลล์
- Root หรือ sudo
ขั้นตอนที่ 1: ติดตั้ง Caddy จากที่เก็บทางการ
อย่าติดตั้ง Caddy เก่าสุ่มจาก Ubuntu universe เริ่มต้นถ้าต้องการพฤติกรรม TLS และ ACME ปัจจุบัน โครงการ 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ขั้นตอนที่ 2: Caddyfile แรก — ไซต์สแตติก
Caddyfile เริ่มต้นคือ /etc/caddy/Caddyfile แทนที่ด้วยโดเมนของคุณ Caddy จะพยายามได้ใบรับรองทันทีที่คอนฟิกโหลดถ้าชื่อโฮสต์ไม่ใช่ localhost วางไฟล์ไซต์ในไดเรกทอรีที่ผู้ใช้ 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ขั้นตอนที่ 3: รีเวิร์สพร็อกซีแอปพลิเคชันท้องถิ่น
ถ้า 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
# }ขั้นตอนที่ 4: ไฟร์วอลล์และ systemd
อนุญาต 80 และ 443 ยูนิตของ Caddy คือ caddy.service reload พอหลังแก้ Caddyfile ถ้าโปรเซสสุขภาพดี ถ้าเปลี่ยนตัวแปรสภาพแวดล้อมสำหรับปลั๊กอิน 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/ขั้นตอนที่ 5: ล็อก การบีบอัด และส่วนหัว
ล็อกการเข้าถึงช่วยเมื่อบอตทุบพาธหรือเมื่อคุณดีบัก 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ขั้นตอนที่ 6: PHP และส่วนเพิ่มอื่น
Caddy พูดกับ PHP-FPM ได้ด้วยคำสั่ง php_fastcgi พอสำหรับโฮสต์ WordPress หรือ Laravel หลายแห่ง แต่คุณยังต้องติดตั้ง php-fpm และพาธซ็อกเก็ตที่ตรงกัน ถ้าคุณมีคอนฟิก Nginx PHP ที่สมบูรณ์แล้ว การย้ายในหนึ่งคืนเป็นทางเลือก — 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 โดยไม่เซอร์ไพรส์ downtime
หยุด Nginx ก่อนเริ่ม Caddy ไม่งั้นพวกมันแย่ง 80/443 ลด TTL ของ DNS วันก่อนถ้าคุณย้าย IP ด้วย ทดสอบด้วย curl --resolve เพื่อยิง VPS ใหม่ก่อนสลับเรคคอร์ด A เก็บคอนฟิก Nginx ใน git หนึ่งสัปดาห์เผื่อต้องย้อน
- systemctl stop nginx && systemctl disable nginx
- ติดตั้ง Caddy ตรวจ Caddyfile เริ่ม Caddy
- curl -I --resolve example.com:443:NEW_IP https://example.com
- ค่อยเปลี่ยน DNS ถ้า IP ใหม่
- การออกใหม่เป็นอัตโนมัติ อย่ารัน Certbot กับชื่อโฮสต์เดียวกันด้วย
แก้ปัญหา
ความล้มเหลว ACME เกือบเสมอคือ DNS ไฟร์วอลล์ หรือบริการอื่นบนพอร์ต 80 บรรทัดล็อก Caddy พูดถึง tls.obtain ถ้าไซต์ใช้ได้บน HTTP แต่ไม่ HTTPS การออกไม่เสร็จ ถ้าเห็นใบรับรองมากเกินไป คุณชนขีดจำกัดอัตรา Let's Encrypt — ใช้ CA staging ตอนทดสอบ ไม่ใช่โปรดักชัน
- validate ล้มเหลว: ไวยากรณ์ Caddyfile วงเล็บหาย
- permission denied บน root: chown caddy สำหรับไดเรกทอรีไซต์
- bind: address already in use — ss -tulpn | grep -E ':80|:443'
- หมดเวลาใบรับรอง: dig +short โดเมนจาก VPS, ufw allow 80
- 502 reverse_proxy: แบ็กเอนด์ล่ม หรือคุณพร็อกซีไป localhost จากเครือข่ายคอนเทนเนอร์ผิด
บันทึกความปลอดภัย
ค่าเริ่มต้น TLS ของ Caddy อนุรักษ์นิยม งานของคุณคือความปลอดภัยแอปพลิเคชันและ SSH อย่าเปิด API ผู้ดูแลของ Caddy บนอินเทอร์เฟซสาธารณะ จุดปลายผู้ดูแลเริ่มต้นเป็นท้องถิ่น ปล่อยไว้แบบนั้น ถ้าใช้ Caddyfile จากอินเทอร์เน็ต ให้อ่านทุก matcher — snippet ที่ reverse_proxy /* ไป IP ภายในอาจกลายเป็นพร็อกซีเปิด
- อย่าเปิดเผย API ผู้ดูแล
- อัปเดตแพ็กเกจอยู่เสมอ
- HSTS หลังมั่นใจว่า HTTPS ใช้ได้กับทุกชื่อโฮสต์เท่านั้น
- แยกชื่อโฮสต์ทดสอบกับโปรดักชันเพื่อปกป้องขีดจำกัดอัตรา ACME
เคล็ดลับ
- caddy fmt --overwrite /etc/caddy/Caddyfile ทำให้ไฟล์อ่านง่าย
- ใช้ snippet import เมื่อมีไซต์คล้ายกันหลายแห่ง
- สำหรับ Docker อิมเมจ caddy:alpine พร้อม Caddyfile ที่เมานต์เป็นเรื่องธรรมดา
- ใบรับรองไวลด์การ์ดต้องมีโมดูล DNS และโทเค็น API — ปกป้องโทเค็นนั้น
- อ่าน journalctl -u caddy ก่อนเขียนไฟล์ทั้งก้อนใหม่
Caddy บน VPS คือ แพ็กเกจทางการ Caddyfile สั้น พอร์ต 80/443 เปิด DNS ชี้เซิร์ฟเวอร์แล้ว และ systemd reload หลังแก้ ใช้เป็นเซิร์ฟเวอร์ไฟล์สแตติกหรือรีเวิร์สพร็อกซีหน้า Gunicorn, Node หรือ Docker HTTPS อัตโนมัติทำงานเมื่อ ACME ตอบบนพอร์ต 80 ได้ ถ้าออกไม่สำเร็จ ให้แก้ DNS กับพอร์ตชนก่อนโทษ Caddy สำรอง /var/lib/caddy ถ้าคุณติดตั้งใหม่บ่อย