Docs / Web Servers / How to Set Up Caddy as an Automatic HTTPS Web Server

How to Set Up Caddy as an Automatic HTTPS Web Server

By Admin · Mar 15, 2026 · Updated Apr 23, 2026 · 363 views · 2 min read

Caddy is a modern web server that automatically handles HTTPS certificate provisioning and renewal via Let's Encrypt. It requires minimal configuration and is an excellent choice for simple to medium-complexity deployments.

Why Caddy?

  • Automatic HTTPS — Obtains and renews Let's Encrypt certificates with zero configuration
  • HTTP/2 and HTTP/3 by default
  • Simple Caddyfile syntax (much simpler than Nginx)
  • Automatic OCSP stapling
  • Single binary, no dependencies

Installation

# Ubuntu/Debian
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
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

# Or download binary
curl -fsSL https://caddyserver.com/api/download | sudo tee /usr/bin/caddy > /dev/null
sudo chmod +x /usr/bin/caddy

Basic Caddyfile

# /etc/caddy/Caddyfile

# Static site — automatic HTTPS!
example.com {
    root * /var/www/example.com
    file_server
}

# Reverse proxy
api.example.com {
    reverse_proxy localhost:3000
}

# PHP application
myapp.com {
    root * /var/www/myapp/public
    php_fastcgi unix//run/php/php8.3-fpm.sock
    file_server
    encode gzip
}

# Multiple domains on one site
example.com, www.example.com {
    root * /var/www/example.com
    file_server
}

Advanced Configuration

# Caddyfile with all features
example.com {
    root * /var/www/example.com/public

    # Compression
    encode gzip zstd

    # Logging
    log {
        output file /var/log/caddy/access.log
        format json
    }

    # Security headers
    header {
        X-Content-Type-Options "nosniff"
        X-Frame-Options "DENY"
        Strict-Transport-Security "max-age=63072000"
        Referrer-Policy "strict-origin-when-cross-origin"
        -Server
    }

    # Static file caching
    @static {
        path *.css *.js *.png *.jpg *.gif *.svg *.woff2
    }
    header @static Cache-Control "public, max-age=2592000"

    # PHP processing
    php_fastcgi unix//run/php/php8.3-fpm.sock

    # File server (for static files)
    file_server
}

Caddy as a Reverse Proxy with Load Balancing

api.example.com {
    reverse_proxy {
        to localhost:3001
        to localhost:3002
        to localhost:3003

        lb_policy least_conn
        health_uri /health
        health_interval 10s
    }
}

# WebSocket support (automatic)
ws.example.com {
    reverse_proxy localhost:8080
}

Managing Caddy

# Validate configuration
caddy validate --config /etc/caddy/Caddyfile

# Reload without downtime
sudo systemctl reload caddy

# Format Caddyfile
caddy fmt --overwrite /etc/caddy/Caddyfile

# View certificates
caddy list-modules
sudo ls /var/lib/caddy/.local/share/caddy/certificates/

Caddy vs Nginx

FeatureCaddyNginx
Auto HTTPSBuilt-inRequires Certbot
ConfigurationVery simpleMore complex
PerformanceVery goodExcellent
HTTP/3Built-inRequires build flag
EcosystemGrowingMature, extensive
Best forSimple-medium sitesComplex deployments

Was this article helpful?