Mastering Caddy 2: Installation, Configuration, and Advanced Features
This guide introduces Caddy 2, an enterprise‑grade Go‑based web server, outlines its key features and advantages over Nginx, provides step‑by‑step installation commands for various Linux distributions and macOS, and demonstrates comprehensive Caddyfile configurations including site blocks, global options, logging, TLS, reverse proxy, and modular snippets.
Overview
Caddy 2 is an open‑source, enterprise‑grade web server written in Go. It provides built‑in HTTP/2, automatic HTTPS via ACME, optional HTTP/3 (QUIC), IPv6, WebSocket handling, and a modular plugin system that can be extended with Go code.
Key capabilities
Automatic HTTP/2 without configuration.
Zero‑configuration HTTPS with automatic certificate issuance and renewal (ACME HTTP/DNS challenges, OCSP stapling).
Multi‑core utilization and IPv6 support.
Native WebSocket proxying.
Built‑in Markdown‑to‑HTML conversion.
Simple log format definition and log rotation.
Dependency‑free binary deployment (single static executable).
Reverse‑proxy with active/passive health checks, load balancing, circuit breaking, and caching.
Cross‑platform binaries for Windows, Linux, and macOS.
Installation
Official download page: https://caddyserver.com/download
Fedora / RHEL / CentOS 8
$ dnf install 'dnf-command(copr)'
$ dnf copr enable @caddy/caddy
$ dnf install caddymacOS (Homebrew)
$ brew install caddyRHEL / CentOS 7
$ yum install yum-plugin-copr
$ yum copr enable @caddy/caddy
$ yum install caddyDebian / Ubuntu / Raspbian
$ sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
$ curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo tee /etc/apt/trusted.gpg.d/caddy-stable.asc
$ 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 caddyCommon systemd commands
$ systemctl start caddy # start the service
$ systemctl reload caddy # reload configuration without downtime
$ systemctl status caddy # view service statusConfiguration basics
Caddy’s core configuration format is JSON, but most users write a Caddyfile – a concise, line‑oriented syntax that the server compiles to JSON. The Caddyfile supports:
Site blocks that define a domain or address.
Global options wrapped in { ... }.
Reusable snippets (named blocks in parentheses) that can be imported elsewhere.
Wildcard imports and glob patterns for modular configuration files.
Site block example
(site_option) {
encode zstd gzip
file_server
handle_errors {
rewrite * /{http.error.status_code}.html
file_server
}
import acme_https
import log_file
root * /www/{host}
}Global options
{
debug # enable debug output
default_sni domain.com
admin off # disable the admin endpoint
}Error page handling
www.example.com {
root * /web/example.com/
file_server
handle_errors {
rewrite * /{http.error.status_code}.html
file_server
}
}Logging snippet
(log_file) {
log {
format logfmt
output file /var/log/caddy/{host}.access.log {
roll_keep 7
}
}
}Headers and cache control
www.example.com {
header Access-Control-Allow-Origin *
header Cache-Control max-age=3600
header /css/* Cache-Control max-age=604800
} (cachecontrol) {
header /css/* Cache-Control max-age=3600
header /img/* Cache-Control max-age=3600
header /js/* Cache-Control max-age=3600
}Reverse proxy
https://www.example.com {
gzip
tls [email protected]
reverse_proxy / https://backend.example.com
}Quick static site command
$ caddy file-server --website ./index --listen :8088 --domain www.example.comParameters:
file-server # starts a production‑ready static file server
--website DIR # directory containing index.html and other assets
--listen :PORT # listening address (e.g., :8088)
--domain HOST # domain name to bind the site toSnippet definition and import
# TLS snippet
(TLS) {
protocols tls1.2 tls1.3
ciphers TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
}
# Use the snippet elsewhere
import TLSModular imports
# Import all Caddyfiles under /etc/caddy
import /etc/caddy/*.caddyFull modular configuration example
The example below combines logging, TLS, HSTS, and an ACME DNS challenge (Gandi) into reusable snippets, enables experimental HTTP/3, and applies the common configuration to two sites.
(LOG) {
log {
format "[{ts}] {request>remote_addr} {request>proto} {request>method} <- {status} -> {request>host} {request>uri} {request>headers>User-Agent>[0]" {
time_format "iso8601"
}
output file "{args.0}" {
roll_size 100mb
roll_keep 3
roll_keep_for 7d
}
}
}
(TLS) {
protocols tls1.2 tls1.3
ciphers TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
}
(HSTS) {
header / Strict-Transport-Security "max-age=63072000"
}
(ACME_GANDI) {
dns gandi {$GANDI_API_TOKEN}
}
(COMMON_CONFIG) {
encode zstd gzip
tls {
import TLS
import ACME_GANDI
}
import HSTS
}
# Enable experimental HTTP/3 on port 443
{
servers :443 {
protocol {
experimental_http3
}
}
}
import /etc/caddy/*.caddy
www.example.com {
redir https://example.com{uri}
import LOG "/data/logs/example.com.log"
import COMMON_CONFIG
}
example.com {
route /* {
reverse_proxy backend:80
}
import LOG "/data/logs/example.com.log"
import COMMON_CONFIG
}Running and reloading
$ systemctl start caddy # start the server
$ systemctl reload caddy # apply configuration changes without stopping
$ systemctl status caddy # check service healthThese commands behave similarly to the traditional nginx service management commands.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
