ติดตั้ง Caddy Web Server บน VPS Ubuntu พร้อม HTTPS อัตโนมัติ

Caddy คืออะไร และทำไมถึงดีกว่า Nginx/Apache สำหรับมือใหม่

Caddy Web Server คือ web server รุ่นใหม่ที่เขียนด้วยภาษา Go ออกแบบมาให้ใช้งานง่ายตั้งแต่ต้น จุดเด่นที่ทำให้ Caddy แตกต่างจาก Nginx และ Apache คือ การออก SSL Certificate โดยอัตโนมัติ ผ่าน Let's Encrypt และ ZeroSSL โดยไม่ต้องติดตั้ง Certbot หรือตั้งค่า cron job แม้แต่น้อย

สำหรับมือใหม่ที่เพิ่งเริ่มเช่า VPS การตั้งค่า Nginx พร้อม SSL มักต้องผ่านหลายขั้นตอน ทั้งติดตั้ง Certbot ตั้ง cron job ต่ออายุ และแก้ไฟล์ config ที่ซับซ้อน Caddy แก้ปัญหาทั้งหมดนี้ด้วยไฟล์ config เพียงไฟล์เดียวชื่อ Caddyfile ที่อ่านและแก้ไขได้ง่าย ใช้เวลาตั้งค่าเพียงไม่กี่นาทีก็ได้ HTTPS ที่ใช้งานได้จริงทันที

ข้อกำหนดเบื้องต้นก่อนติดตั้ง

ก่อนเริ่มติดตั้ง Caddy บน VPS ให้เตรียมสิ่งเหล่านี้ให้พร้อม:

ข้อสำคัญ: Caddy ต้องการให้โดเมนชี้มาที่ IP ของ VPS จริงๆ ก่อนที่จะออก SSL ได้ ถ้า DNS ยังไม่อัพเดต ACME challenge จะล้มเหลวและ Caddy จะไม่สามารถออก Certificate ได้

วิธีติดตั้ง Caddy บน Ubuntu ผ่าน Official APT Repository

Caddy แนะนำให้ติดตั้งผ่าน official APT repository เพื่อให้อัพเดตอัตโนมัติเมื่อมีเวอร์ชันใหม่ รันคำสั่งต่อไปนี้ตามลำดับ:

# 1. ติดตั้ง dependencies ที่จำเป็น
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl

# 2. เพิ่ม Caddy GPG key
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
  | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg

# 3. เพิ่ม Caddy apt repository
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
  | sudo tee /etc/apt/sources.list.d/caddy-stable.list

# 4. อัพเดต apt และติดตั้ง Caddy
sudo apt update
sudo apt install caddy

หลังติดตั้งเสร็จ Caddy จะถูกตั้งค่าเป็น systemd service อัตโนมัติ ตรวจสอบสถานะด้วย:

sudo systemctl status caddy

โครงสร้าง Caddyfile พื้นฐาน

ไฟล์ config ของ Caddy ชื่อ Caddyfile อยู่ที่ /etc/caddy/Caddyfile โดย default โครงสร้างพื้นฐานมีดังนี้:

# /etc/caddy/Caddyfile

# ตัวอย่าง: serve static site พร้อม HTTPS อัตโนมัติ
example.com {
    root * /var/www/html
    file_server
}

# รองรับ www subdomain ด้วย
www.example.com {
    redir https://example.com{uri} permanent
}

แค่นี้พอ! Caddy จะออก SSL Certificate ให้ example.com อัตโนมัติและ redirect HTTP ไป HTTPS ทันที ไม่ต้องเพิ่ม directive อื่นเลย ต่างจาก Nginx ที่ต้องสร้าง server block แยกสำหรับ HTTP/HTTPS และแก้ไฟล์ certbot config เพิ่มเติม

ตัวอย่าง Caddyfile: Static Site และ Reverse Proxy

Static Website (HTML ธรรมดา)

# /etc/caddy/Caddyfile

mywebsite.com {
    root * /var/www/mywebsite
    file_server
    encode gzip
    log {
        output file /var/log/caddy/mywebsite.log
    }
}

Reverse Proxy ไปยัง Node.js App (port 3000)

app.mywebsite.com {
    reverse_proxy localhost:3000
}

Reverse Proxy ไปยัง PHP-FPM

php.mywebsite.com {
    root * /var/www/phpapp
    php_fastcgi unix//run/php/php8.2-fpm.sock
    file_server
}

Reverse Proxy ไปยัง Python/Flask (port 5000)

api.mywebsite.com {
    reverse_proxy localhost:5000 {
        header_up Host {host}
        header_up X-Real-IP {remote}
    }
}

Caddyfile รองรับ virtual hosting หลายโดเมนในไฟล์เดียว เพียงแค่เพิ่ม block ใหม่ต่อท้าย Caddy จะออก SSL ให้ทุกโดเมนโดยอัตโนมัติ

เปรียบเทียบ Caddy กับ Nginx และ Apache

ก่อนตัดสินใจเลือก web server ควรเข้าใจข้อดีข้อเสียของแต่ละตัวเพื่อให้เหมาะกับงาน เพราะแต่ละตัวมีจุดแข็งที่ต่างกัน

คุณสมบัติ Caddy Nginx Apache
SSL อัตโนมัติ ✓ ในตัว ต้องใช้ Certbot ต้องใช้ Certbot
ความยากของ Config ง่ายมาก ปานกลาง ปานกลาง-ยาก
HTTP/3 (QUIC) ✓ ในตัว ต้องตั้งค่าเพิ่ม ต้อง Module เพิ่ม
ประสิทธิภาพสูง ดี ดีเยี่ยม ดี
Plugin/Extension จำกัด มาก มากที่สุด
เหมาะกับมือใหม่ ดีที่สุด ปานกลาง ปานกลาง

โดยสรุปคือ Caddy เป็นทางเลือกที่ดีที่สุดสำหรับผู้ที่ต้องการ HTTPS ทันทีโดยไม่ยุ่งยาก ส่วน Nginx เหมาะกับผู้ที่ต้องการ performance สูงสุดและมีความรู้ด้าน server configuration ขั้นสูงแล้ว Apache เป็นตัวเลือกที่มี ecosystem กว้างที่สุด เหมาะกับเว็บที่ใช้งาน .htaccess มาก

การตั้งค่า Caddy ขั้นสูง: Header, Rate Limiting และ Basic Auth

นอกจาก serve static file และ reverse proxy แล้ว Caddy ยังมี directive สำคัญที่ช่วยเพิ่มความปลอดภัยและประสิทธิภาพของเว็บ

เพิ่ม Security Headers

mywebsite.com {
    root * /var/www/mywebsite
    file_server
    header {
        # ป้องกัน clickjacking
        X-Frame-Options "SAMEORIGIN"
        # บังคับ HTTPS
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        # ป้องกัน MIME sniffing
        X-Content-Type-Options "nosniff"
        # ซ่อน server header
        -Server
    }
}

ตั้ง Basic Authentication สำหรับพื้นที่ส่วนตัว

สร้าง hashed password ก่อนด้วยคำสั่ง caddy hash-password แล้วนำ hash ที่ได้มาใส่ใน Caddyfile:

admin.mywebsite.com {
    reverse_proxy localhost:8080
    basicauth {
        # username: admin, รหัสผ่าน hash จาก caddy hash-password
        admin JDJhJDEyJGF....(hash)
    }
}

Redirect HTTP ไป HTTPS สำหรับ IP address โดยตรง

# ใช้ wildcard ครอบ port 80 ทั้งหมดและ redirect ไป HTTPS
:80 {
    redir https://{host}{uri} permanent
}

directive เหล่านี้ใช้ได้ทันทีโดยไม่ต้องติดตั้ง module เพิ่ม ซึ่งต่างจาก Apache ที่ต้องเปิด mod_headers และ mod_auth_basic แยกต่างหาก

การ Monitor Caddy และแก้ปัญหาเบื้องต้น

เมื่อ Caddy ทำงานบน production server การตรวจสอบ log และ certificate status สม่ำเสมอช่วยป้องกันปัญหาก่อนที่ผู้ใช้จะเจอ

ดู Certificate ที่ Caddy จัดการอยู่

# ดูรายการ certificate ทั้งหมด
sudo caddy list-certificates

# ตรวจสอบ syntax ของ Caddyfile ก่อน reload
sudo caddy validate --config /etc/caddy/Caddyfile

Log ที่ควรดูเมื่อมีปัญหา

ตั้ง Log แบบ JSON สำหรับ Production

{
    log {
        format json
        output file /var/log/caddy/access.log {
            roll_size 100mb
            roll_keep 5
        }
    }
}

mywebsite.com {
    root * /var/www/mywebsite
    file_server
}

Global block (ส่วน { ... } บนสุดก่อนชื่อโดเมน) ตั้งค่าที่ใช้ร่วมกันทุก site ใน Caddyfile คำสั่ง roll_size และ roll_keep ป้องกัน disk เต็มจาก log ที่สะสม

จัดการ Caddy Service ด้วย systemctl

Caddy ทำงานเป็น systemd service คำสั่งที่ใช้บ่อยในการจัดการ:

# เริ่ม Caddy (ถ้ายังไม่รัน)
sudo systemctl start caddy

# หยุด Caddy
sudo systemctl stop caddy

# Reload config หลังแก้ Caddyfile (ไม่ต้อง restart)
sudo systemctl reload caddy

# ตรวจสอบ status และ log
sudo systemctl status caddy

# ดู log แบบ real-time
sudo journalctl -u caddy -f

# ตั้งให้ Caddy start อัตโนมัติเมื่อ server reboot
sudo systemctl enable caddy

คำสั่งที่ใช้บ่อยที่สุดคือ sudo systemctl reload caddy เมื่อแก้ Caddyfile เสร็จ Caddy จะโหลด config ใหม่โดยไม่ปิด connection เดิม ทำให้ไม่มี downtime

การใช้ Caddy กับ Docker และ Kubernetes

Caddy เป็น web server ที่เหมาะกับ containerized environment มาก เพราะ binary เดี่ยว ไม่มี dependency และรองรับ config ผ่าน environment variable ได้สะดวก ทำให้ใช้งานกับ Docker และ Kubernetes ได้ง่ายกว่า Nginx ที่ต้องใช้ Alpine + certbot เพิ่มเติม

ตัวอย่าง docker-compose.yml กับ Caddy

services:
  caddy:
    image: caddy:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config

  app:
    image: node:20-alpine
    command: node server.js
    expose:
      - "3000"

volumes:
  caddy_data:
  caddy_config:

ใน Caddyfile ให้ชี้ reverse proxy ไปยัง service name ของ Docker แทน localhost เพราะ Docker network ใช้ชื่อ service เป็น hostname:

# Caddyfile สำหรับ Docker Compose
myapp.com {
    reverse_proxy app:3000
}

Caddy จะออก SSL Certificate สำหรับ myapp.com อัตโนมัติเหมือนกัน ตราบใดที่โดเมนชี้มาที่ IP ของเครื่องที่รัน Docker และ port 80/443 เปิดอยู่ ข้อดีของการใช้ Caddy บน Docker คือ certificate จะถูกเก็บใน volume caddy_data ทำให้ไม่หายเมื่อ restart container

ปรับแต่ง Performance: Compression และ Cache Headers

Caddy มี built-in directive สำหรับเพิ่มประสิทธิภาพการส่งไฟล์ที่ช่วยลด bandwidth และเพิ่มความเร็วในการโหลดหน้าเว็บ โดยไม่ต้องติดตั้ง module เพิ่มเติมเลย

เปิด Gzip และ Zstandard Compression

mywebsite.com {
    root * /var/www/mywebsite
    file_server

    # เปิด compression อัตโนมัติ (zstd ก่อน, gzip fallback)
    encode zstd gzip
}

ตั้ง Cache-Control Headers

mywebsite.com {
    root * /var/www/mywebsite
    file_server

    # cache รูปและ CSS 1 ปี, HTML ไม่ cache
    @static {
        path *.css *.js *.jpg *.jpeg *.png *.webp *.svg *.woff2
    }
    header @static Cache-Control "public, max-age=31536000, immutable"
    header *.html Cache-Control "no-cache, no-store, must-revalidate"
}

เปิด HTTP Strict Transport Security (HSTS)

mywebsite.com {
    root * /var/www/mywebsite
    file_server
    header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
}

การเปิด HSTS บอก browser ว่าเว็บของคุณรองรับ HTTPS เท่านั้น ตลอดระยะเวลา 1 ปี ช่วยป้องกัน SSL stripping attack และเพิ่มความน่าเชื่อถือในสายตาของ Google Search ด้วย เพราะ HTTPS เป็นหนึ่งในปัจจัย Ranking ของ Google

ข้อควรระวัง: โดเมนต้องชี้มาที่ VPS ก่อน

ระบบ Auto HTTPS ของ Caddy ทำงานผ่าน ACME challenge ซึ่งต้องการให้ Let's Encrypt เชื่อมต่อมายัง server ของคุณผ่าน port 80 ได้ ถ้าเงื่อนไขต่อไปนี้ไม่ครบ SSL จะออกไม่ได้:

ถ้าพบ error เกี่ยวกับ ACME ให้รัน sudo journalctl -u caddy -n 50 เพื่อดู log และตรวจสอบสาเหตุ จากนั้นแก้ไขปัญหาแล้ว reload Caddy ใหม่

จุดเด่นสำคัญ: Caddy ต่ออายุ SSL Certificate อัตโนมัติทุก 60 วัน ไม่ต้องตั้ง cron job หรือรัน Certbot เอง ตราบใดที่ Caddy service ยังรันอยู่ SSL จะต่ออายุให้เองก่อน Certificate หมดอายุ ลดภาระงาน admin ได้มาก

เช่า VPS สำหรับรัน Caddy

VPS AsiaGB พร้อม Public IP เริ่มต้น 500 บาท/เดือน รองรับ Ubuntu 20.04/22.04 เปิด port 80/443 ได้ทันที เหมาะสำหรับทดลองติดตั้ง Caddy และ deploy แอปพลิเคชัน

ดูแพ็กเกจ VPS