Home > Blog > tech

Caddy คืออะไร? Web Server ที่จัดการ HTTPS อัตโนมัติ ทดแทน Nginx/Apache 2026

caddy web server guide
Caddy Web Server Guide 2026
2026-04-11 | tech | 3400 words

ในโลกของ Web Server มานานหลายทศวรรษ เราคุ้นเคยกับ Apache และ Nginx ที่ครองตลาดมาตลอด แต่ในปี 2026 มี Web Server ตัวใหม่ที่กำลังได้รับความนิยมอย่างมากในหมู่นักพัฒนา นั่นคือ Caddy ซึ่งมีจุดเด่นที่สำคัญที่สุดคือการจัดการ HTTPS แบบอัตโนมัติโดยไม่ต้องตั้งค่าอะไรเลย ไม่ต้องรัน certbot ไม่ต้องตั้ง cron สำหรับ renew certificate ทุกอย่างเกิดขึ้นเองอัตโนมัติ

บทความนี้จะพาคุณรู้จัก Caddy ตั้งแต่พื้นฐาน ไปจนถึงการใช้งานจริงใน Production ครอบคลุมทั้ง Reverse Proxy, Static File Serving, PHP-FPM, Docker, Load Balancing และอื่นๆ อีกมากมาย พร้อมเปรียบเทียบข้อดีข้อเสียกับ Nginx และ Apache เพื่อให้คุณตัดสินใจได้ว่าควรเลือกใช้ตัวไหนในสถานการณ์ใด

Caddy คืออะไร?

Caddy คือ Web Server ที่เขียนด้วยภาษา Go สร้างโดย Matthew Holt เปิดตัวครั้งแรกในปี 2015 และปัจจุบันอยู่ในเวอร์ชัน 2.x จุดเด่นที่ทำให้ Caddy แตกต่างจาก Web Server อื่นคือ:

Caddy ถูกออกแบบมาสำหรับยุคสมัยใหม่ที่ HTTPS เป็นมาตรฐาน ไม่ใช่ option อีกต่อไป การที่ Caddy จัดการ certificate ให้อัตโนมัติทำให้ลดภาระของ DevOps ได้มาก และลดความเสี่ยงจากการลืม renew certificate ซึ่งเป็นปัญหาที่เกิดขึ้นบ่อยมากในระบบ production จริง

เปรียบเทียบ Caddy vs Nginx vs Apache

คุณสมบัติCaddyNginxApache
HTTPS อัตโนมัติมีในตัว (default)ต้องใช้ certbot แยกต้องใช้ certbot แยก
Config syntaxCaddyfile (ง่ายมาก)nginx.conf (ปานกลาง).htaccess / httpd.conf (ซับซ้อน)
ภาษาที่เขียนGoCC
HTTP/2Defaultต้องเปิดต้องเปิด mod
HTTP/3 (QUIC)DefaultExperimentalไม่รองรับ
Reverse Proxyง่ายมาก (1 บรรทัด)ง่ายปานกลาง
Hot Reloadรองรับ (API)รองรับ (signal)รองรับ (graceful)
Performanceดีมากดีเยี่ยมดี
Communityกำลังเติบโตใหญ่มากใหญ่มาก
ใช้ Memoryน้อย-ปานกลางน้อยมากปานกลาง-มาก
สรุปง่ายๆ: ถ้าต้องการความง่ายและ HTTPS อัตโนมัติ เลือก Caddy ถ้าต้องการ performance สูงสุดและมีประสบการณ์ เลือก Nginx ถ้าต้องการ .htaccess และ module มากมาย เลือก Apache

ติดตั้ง Caddy

Linux (Ubuntu/Debian)

# ติดตั้งจาก official repository
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

# ตรวจสอบเวอร์ชัน
caddy version

# Caddy จะรันเป็น systemd service อัตโนมัติ
sudo systemctl status caddy

macOS

brew install caddy

Windows

# ใช้ Chocolatey
choco install caddy

# หรือดาวน์โหลด binary จาก caddyserver.com

Docker

docker pull caddy:latest
docker run -d -p 80:80 -p 443:443 \
  -v caddy_data:/data \
  -v caddy_config:/config \
  -v $PWD/Caddyfile:/etc/caddy/Caddyfile \
  caddy

Caddyfile — Config ที่ง่ายที่สุดในโลก

Caddyfile คือไฟล์ config หลักของ Caddy ที่มี syntax เรียบง่ายอ่านเข้าใจได้ทันที แม้ไม่เคยใช้ Web Server มาก่อน ตัวอย่างเปรียบเทียบการ serve static website:

Caddy (Caddyfile)

example.com {
    root * /var/www/html
    file_server
}

Nginx (เทียบเท่า)

server {
    listen 80;
    listen 443 ssl;
    server_name example.com;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    root /var/www/html;
    location / {
        try_files $uri $uri/ =404;
    }
}

เห็นความแตกต่างชัดเจน Caddy ใช้แค่ 3 บรรทัดก็ได้ผลลัพธ์เดียวกัน รวมถึง HTTPS อัตโนมัติด้วย ในขณะที่ Nginx ต้องเขียน 10 บรรทัด และยังต้องจัดการ certificate แยกอีก

HTTPS อัตโนมัติ — จุดเด่นที่สุดของ Caddy

เมื่อคุณใส่ domain name ใน Caddyfile เช่น example.com สิ่งที่ Caddy ทำให้อัตโนมัติคือ:

  1. ขอ TLS Certificate จาก Let's Encrypt หรือ ZeroSSL
  2. ตั้งค่า HTTPS ให้ถูกต้องตาม best practice
  3. Redirect HTTP ไป HTTPS อัตโนมัติ
  4. เปิด HTTP/2 และ HTTP/3 (QUIC)
  5. Renew Certificate ให้อัตโนมัติก่อนหมดอายุ
  6. OCSP Stapling เปิดให้อัตโนมัติ

ทั้งหมดนี้เกิดขึ้นโดยคุณไม่ต้องเขียน config อะไรเพิ่มเลย แค่ใส่ domain name ก็พอ นี่คือเหตุผลที่ Caddy ได้รับฉายาว่าเป็น Web Server ที่ปลอดภัยที่สุดโดย default

สำหรับ Development: ถ้าใช้ localhost แทน domain name จริง Caddy จะสร้าง self-signed certificate ให้อัตโนมัติ ทำให้คุณทดสอบ HTTPS บน local ได้ทันที

Reverse Proxy — ใช้งานจริงที่พบบ่อยที่สุด

การใช้ Caddy เป็น Reverse Proxy หน้า Application Server เป็น use case ที่นิยมมากที่สุด เพราะ config ง่ายมาก:

Reverse Proxy พื้นฐาน

# Proxy ไปยัง Backend ที่รันอยู่ port 3000
app.example.com {
    reverse_proxy localhost:3000
}

# Proxy หลาย Backend (Load Balancing)
app.example.com {
    reverse_proxy localhost:3001 localhost:3002 localhost:3003
}

# Proxy ด้วย Health Check
app.example.com {
    reverse_proxy localhost:3001 localhost:3002 {
        health_uri /health
        health_interval 10s
        health_timeout 3s
    }
}

Reverse Proxy ขั้นสูง

app.example.com {
    reverse_proxy localhost:3000 {
        # เพิ่ม Header
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-Proto {scheme}

        # Timeout settings
        transport http {
            dial_timeout 5s
            response_header_timeout 30s
        }

        # Load balancing algorithm
        lb_policy round_robin
    }
}

Static File Serving

Caddy สามารถ serve ไฟล์ static ได้อย่างมีประสิทธิภาพ พร้อม features ต่างๆ ที่ใช้งานบ่อย:

# Basic static file serving
example.com {
    root * /var/www/mysite
    file_server
}

# พร้อม directory listing
example.com {
    root * /var/www/files
    file_server browse
}

# กำหนด encoding และ compression
example.com {
    root * /var/www/mysite
    encode gzip zstd
    file_server
}

# SPA (Single Page Application) fallback
example.com {
    root * /var/www/react-app
    encode gzip
    try_files {path} /index.html
    file_server
}

PHP-FPM กับ Caddy

สำหรับคนที่ใช้ PHP เช่น WordPress, Laravel หรือ PHP framework อื่นๆ Caddy รองรับ PHP-FPM ได้ดีเยี่ยม:

# WordPress กับ Caddy
wordpress.example.com {
    root * /var/www/wordpress
    encode gzip

    php_fastcgi unix//run/php/php8.3-fpm.sock

    file_server

    # Security headers
    header {
        X-Content-Type-Options nosniff
        X-Frame-Options DENY
        Referrer-Policy strict-origin-when-cross-origin
    }
}

# Laravel กับ Caddy
laravel.example.com {
    root * /var/www/laravel/public
    encode gzip

    php_fastcgi unix//run/php/php8.3-fpm.sock
    file_server

    # Laravel URL rewriting
    @notStatic not path /build/* /vendor/*
    try_files {path} {path}/ /index.php?{query}
}
เทียบกับ Nginx: สังเกตว่า Caddy ไม่ต้องเขียน location block ซับซ้อนแบบ Nginx เพื่อจัดการ PHP แค่ใช้ directive php_fastcgi ก็พอ ลดโอกาสเกิดข้อผิดพลาดจาก config ได้มาก

Load Balancing

Caddy รองรับ load balancing หลาย algorithm สำหรับกระจาย traffic ไปยัง backend หลายตัว:

app.example.com {
    reverse_proxy {
        to localhost:8001
        to localhost:8002
        to localhost:8003
        to localhost:8004

        # เลือก algorithm
        lb_policy round_robin      # วนรอบ (default)
        # lb_policy least_conn    # เลือกตัวที่มี connection น้อยสุด
        # lb_policy random        # สุ่ม
        # lb_policy first          # ตัวแรกที่พร้อม
        # lb_policy ip_hash       # ตาม IP ของ client
        # lb_policy cookie        # ตาม cookie (sticky session)

        # Health check
        health_uri /healthz
        health_interval 15s
        health_timeout 5s
        health_status 200

        # Retry failed requests
        lb_try_duration 5s
        lb_try_interval 250ms
    }
}

Caddy เป็น API Gateway

Caddy สามารถทำหน้าที่เป็น API Gateway ได้ดี โดยเฉพาะเมื่อใช้ร่วมกับ Microservices:

api.example.com {
    # Route ไปยัง service ต่างๆ ตาม path
    handle /api/users/* {
        reverse_proxy user-service:8001
    }

    handle /api/orders/* {
        reverse_proxy order-service:8002
    }

    handle /api/products/* {
        reverse_proxy product-service:8003
    }

    handle /api/payments/* {
        reverse_proxy payment-service:8004
    }

    # CORS headers สำหรับ frontend
    header {
        Access-Control-Allow-Origin *
        Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
        Access-Control-Allow-Headers "Content-Type, Authorization"
    }

    # Rate limiting (ต้องใช้ module เพิ่ม)
    # rate_limit {remote.ip} 100r/m
}

Caddy Modules และ Plugins

Caddy มีระบบ module ที่ขยายความสามารถได้ การติดตั้ง module ทำได้ผ่าน xcaddy ซึ่งเป็นเครื่องมือ build Caddy พร้อม module ที่ต้องการ:

# ติดตั้ง xcaddy
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest

# Build Caddy พร้อม module
xcaddy build \
    --with github.com/caddy-dns/cloudflare \
    --with github.com/mholt/caddy-ratelimit \
    --with github.com/greenpau/caddy-security

# ตรวจสอบ module ที่ติดตั้ง
caddy list-modules

Module ยอดนิยมที่ควรรู้จัก:

Caddy กับ Docker

Caddy ทำงานร่วมกับ Docker ได้ดีมาก เพราะเป็น single binary ขนาดเล็ก image มีน้ำหนักเบา:

Dockerfile สำหรับ Static Site

FROM caddy:latest

COPY Caddyfile /etc/caddy/Caddyfile
COPY dist/ /var/www/html/

Docker Compose สำหรับ Multi-Service

# docker-compose.yml
version: "3.9"
services:
  caddy:
    image: caddy:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"  # HTTP/3
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config
    depends_on:
      - app
      - api

  app:
    build: ./frontend
    expose:
      - "3000"

  api:
    build: ./backend
    expose:
      - "8000"
    environment:
      - DATABASE_URL=postgres://db:5432/myapp

  db:
    image: postgres:16
    volumes:
      - pg_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_PASSWORD=secret

volumes:
  caddy_data:
  caddy_config:
  pg_data:

Caddyfile สำหรับ Docker Compose

app.example.com {
    reverse_proxy app:3000
}

api.example.com {
    reverse_proxy api:8000
}

สังเกตว่าใน Docker Compose เราสามารถใช้ชื่อ service (เช่น app, api) แทน localhost ได้เลย เพราะ Docker จะจัดการ DNS ภายใน network ให้อัตโนมัติ

Rate Limiting และ IP Filtering

การป้องกัน server จาก abuse เป็นสิ่งสำคัญ Caddy มีวิธีจัดการหลายแบบ:

IP Filtering

# อนุญาตเฉพาะ IP ที่กำหนด
admin.example.com {
    @blocked not remote_ip 10.0.0.0/8 192.168.0.0/16
    respond @blocked "Forbidden" 403

    reverse_proxy localhost:9000
}

# Block IP ที่ไม่ต้องการ
example.com {
    @badips remote_ip 1.2.3.4 5.6.7.8
    respond @badips "Blocked" 403

    reverse_proxy localhost:3000
}

Rate Limiting (ด้วย module)

# ติดตั้ง module ก่อน
# xcaddy build --with github.com/mholt/caddy-ratelimit

api.example.com {
    rate_limit {
        zone dynamic_zone {
            key {remote_host}
            events 100
            window 1m
        }
    }
    reverse_proxy localhost:8000
}

Basic Authentication

# สร้าง password hash
caddy hash-password --plaintext "your-password"

# ใช้ใน Caddyfile
admin.example.com {
    basicauth * {
        admin $2a$14$hash_of_password_here
    }
    reverse_proxy localhost:9000
}

Caddy สำหรับ Development (Local HTTPS)

Caddy เหมาะมากสำหรับการพัฒนาในเครื่อง local เพราะสามารถจำลองสภาพแวดล้อม HTTPS ได้ง่าย:

# Caddyfile สำหรับ development
localhost {
    reverse_proxy localhost:3000
}

# หรือใช้ domain จำลอง
myapp.local {
    tls internal
    reverse_proxy localhost:3000
}

# Serve ไฟล์ static ง่ายๆ
localhost {
    root * ./public
    file_server
}
# รัน Caddy ในโหมด development
caddy run                    # รันพร้อมดู log
caddy start                  # รัน background
caddy stop                   # หยุด
caddy reload                 # โหลด config ใหม่
caddy adapt                  # แปลง Caddyfile เป็น JSON (debug)
เทคนิค: ใช้ caddy file-server --browse เพื่อ serve directory ปัจจุบันเป็น file browser ได้ทันทีโดยไม่ต้องเขียน Caddyfile ใช้แทน python -m http.server ได้ดี เพราะมี UI สวยกว่าและรองรับ HTTPS ด้วย

Caddy Performance

แม้ Caddy จะเขียนด้วย Go ไม่ใช่ C แบบ Nginx แต่ performance ก็อยู่ในระดับที่ดีมากสำหรับ use case ส่วนใหญ่ ต่อไปนี้คือข้อมูลเปรียบเทียบโดยประมาณ:

MetricCaddyNginx
Static file (req/sec)~50,000~70,000
Reverse proxy (req/sec)~40,000~55,000
Memory usage (idle)~20 MB~5 MB
TLS handshake speedดีมากดีมาก
HTTP/3 supportNativeExperimental

ตัวเลขเหล่านี้จะแตกต่างไปตามฮาร์ดแวร์และ configuration แต่สิ่งที่สำคัญคือสำหรับ application ส่วนใหญ่ที่ bottleneck อยู่ที่ backend ไม่ใช่ web server ดังนั้นความแตกต่างของ performance ระหว่าง Caddy กับ Nginx แทบไม่มีผลในทางปฏิบัติเลย

สิ่งที่ควรทำเพื่อ optimize Caddy:

Caddy JSON Config สำหรับการใช้งานขั้นสูง

นอกจาก Caddyfile แล้ว Caddy ยังรองรับ config แบบ JSON ซึ่งให้ความยืดหยุ่นสูงกว่า เหมาะสำหรับการ generate config ด้วยโปรแกรม หรือจัดการผ่าน API:

// caddy.json
{
  "apps": {
    "http": {
      "servers": {
        "main": {
          "listen": [":443"],
          "routes": [
            {
              "match": [{
                "host": ["app.example.com"]
              }],
              "handle": [{
                "handler": "reverse_proxy",
                "upstreams": [
                  {"dial": "localhost:3000"},
                  {"dial": "localhost:3001"}
                ],
                "load_balancing": {
                  "selection_policy": {
                    "policy": "least_conn"
                  }
                }
              }]
            }
          ]
        }
      }
    }
  }
}
# จัดการ config ผ่าน API
# โหลด config ใหม่
curl localhost:2019/load -X POST -H "Content-Type: application/json" -d @caddy.json

# ดู config ปัจจุบัน
curl localhost:2019/config/

# แก้ไขเฉพาะส่วน
curl localhost:2019/config/apps/http/servers/main/routes -X PATCH \
  -H "Content-Type: application/json" \
  -d '[{"match":[{"host":["new.example.com"]}],"handle":[{"handler":"static_response","body":"Hello"}]}]'

API endpoint ของ Caddy เปิดอยู่ที่ port 2019 โดย default ซึ่งผูกกับ localhost เท่านั้น ทำให้ปลอดภัยจากการเข้าถึงจากภายนอก ความสามารถนี้ทำให้ Caddy เหมาะมากสำหรับระบบที่ต้องการเปลี่ยน config แบบ dynamic โดยไม่ต้อง restart server

Caddy ใน Production

สำหรับการใช้ Caddy ใน Production จริง มีสิ่งที่ควรตั้งค่าเพิ่มเติม:

Security Headers

example.com {
    header {
        # Security headers
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "DENY"
        X-XSS-Protection "0"
        Referrer-Policy "strict-origin-when-cross-origin"
        Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'"
        Permissions-Policy "camera=(), microphone=(), geolocation=()"

        # ซ่อน Server header
        -Server
    }

    reverse_proxy localhost:3000
}

Logging

{
    log {
        output file /var/log/caddy/access.log {
            roll_size 100mb
            roll_keep 10
            roll_keep_for 720h
        }
        format json
        level INFO
    }
}

example.com {
    log {
        output file /var/log/caddy/example.log
    }
    reverse_proxy localhost:3000
}

Wildcard Certificate ด้วย DNS Challenge

# ต้อง build Caddy พร้อม DNS module
# xcaddy build --with github.com/caddy-dns/cloudflare

*.example.com {
    tls {
        dns cloudflare {env.CF_API_TOKEN}
    }

    @app host app.example.com
    handle @app {
        reverse_proxy localhost:3000
    }

    @api host api.example.com
    handle @api {
        reverse_proxy localhost:8000
    }
}

เมื่อไหร่ควรเลือก Caddy vs Nginx

จากประสบการณ์การใช้งานจริง สรุปได้ดังนี้:

เลือก Caddy เมื่อ:

เลือก Nginx เมื่อ:

ในความเป็นจริง Web Server ไม่ใช่ bottleneck ของระบบส่วนใหญ่ ดังนั้นการเลือก Caddy ที่ง่ายกว่าในการตั้งค่าและดูแลรักษา อาจเป็นทางเลือกที่ดีกว่าสำหรับทีมส่วนใหญ่ โดยเฉพาะทีมเล็กที่ไม่มีเวลา debug config ของ Nginx ที่ซับซ้อน

การที่ Caddy จัดการ HTTPS ให้อัตโนมัติยังช่วยลดความเสี่ยงด้าน security ได้มาก เพราะไม่ต้องกังวลว่า certificate จะหมดอายุแล้วลืม renew ซึ่งเป็นปัญหาที่พบบ่อยมากในระบบจริง หลายบริษัทเคยเจอ downtime จากเรื่องนี้ และ Caddy แก้ปัญหานี้ได้อย่างสมบูรณ์

ตัวอย่าง Caddyfile แบบครบ สำหรับ Production

# Global options
{
    email admin@example.com
    acme_ca https://acme-v02.api.letsencrypt.org/directory

    log {
        output file /var/log/caddy/caddy.log
        format json
        level WARN
    }

    servers {
        protocols h1 h2 h3
    }
}

# Main website
example.com {
    root * /var/www/example
    encode gzip zstd
    file_server

    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "SAMEORIGIN"
        -Server
    }

    log {
        output file /var/log/caddy/example-access.log {
            roll_size 50mb
            roll_keep 5
        }
    }
}

# API Backend
api.example.com {
    reverse_proxy localhost:8000 {
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-Proto {scheme}
        lb_policy least_conn
        health_uri /health
        health_interval 30s
    }

    header {
        Access-Control-Allow-Origin "https://example.com"
        Access-Control-Allow-Methods "GET, POST, PUT, DELETE"
        Access-Control-Allow-Headers "Content-Type, Authorization"
    }
}

# Admin panel (restricted)
admin.example.com {
    @allowed remote_ip 10.0.0.0/8
    handle @allowed {
        reverse_proxy localhost:9000
    }

    handle {
        respond "Forbidden" 403
    }
}

สรุป

Caddy เป็น Web Server รุ่นใหม่ที่ออกแบบมาเพื่อความง่ายและความปลอดภัยเป็นหลัก จุดเด่นที่ชัดเจนที่สุดคือ HTTPS อัตโนมัติที่ทำงานได้โดยไม่ต้องตั้งค่าอะไรเลย Caddyfile มี syntax ที่เข้าใจง่ายมากเมื่อเทียบกับ Nginx หรือ Apache ทำให้ลดโอกาสเกิดข้อผิดพลาดจากการตั้งค่า

สำหรับผู้ที่เริ่มต้นใหม่กับ Web Server หรือต้องการทดแทน Nginx ในโปรเจกต์ขนาดเล็กถึงกลาง Caddy เป็นตัวเลือกที่ดีมาก ลองเริ่มจากการติดตั้งแล้วสร้าง Caddyfile ง่ายๆ สำหรับ serve static files หรือ reverse proxy แล้วคุณจะเข้าใจว่าทำไม Caddy ถึงได้รับความนิยมเพิ่มขึ้นเรื่อยๆ ในปี 2026 การที่ Web Server จัดการ HTTPS ให้อัตโนมัติไม่ใช่แค่ความสะดวก แต่เป็นมาตรฐานใหม่ที่ทุกคนควรมี


Back to Blog | iCafe Forex | SiamLanCard | Siam2R