Caddy Web server, auto HTTPS

Version 2.11 · source

Start here

caddy run
Run in the foreground
caddy start
Run in the background
caddy reload
Apply a changed config
caddy stop
Stop gracefully
caddy validate
Check config without running
caddy fmt --overwrite
Tidy the Caddyfile
caddy file-server --browse
Serve this folder
caddy reverse-proxy --from :80 --to :8080
Quick proxy

Concepts

  1. Caddyfile human-friendly config
  2. JSON config native format
  3. Admin API localhost:2019
  4. Running server auto HTTPS

Run and control

caddy run
Run in the foreground
Loads ./Caddyfile if present; logs go to stderr.
caddy start
Run in the background
caddy stop
Stop the running instance gracefully
caddy reload
Apply the config to the running instance
Zero downtime; a failing config leaves the old one running.
caddy run --config <file>
Run with a specific config file
caddy run --watch
Reload automatically when the config changes
Meant for local development only.
caddy version
Print the version

Config tools

caddy validate --config <file>
Load and provision without running
caddy fmt --overwrite <file>
Format the file in place
caddy adapt --config <file>
Convert a Caddyfile to JSON
caddy run --config <file> --adapter caddyfile
Pick the config adapter by name
The caddyfile adapter is the default for a file named Caddyfile.

Quick servers

caddy file-server
Serve the current directory
caddy file-server --browse
Serve with a directory listing
caddy file-server --root <dir> --listen :<port>
Serve a folder on a port
caddy file-server --access-log
Log every request
caddy reverse-proxy --from <addr> --to <backend>
Proxy requests to a backend
caddy reverse-proxy --change-host-header --to <url>
Send the backend's own Host header
caddy respond --status <code> "<body>"
Run a fixed-response test server

Caddyfile basics

example.com { ... }
Site block with automatic HTTPS
:8080 { ... }
Site block on plain HTTP, port 8080
http://example.com { ... }
Explicit HTTP, no auto-HTTPS
{ email <addr> }
Global options block, must come first
reverse_proxy <backend>
Send requests to a backend
file_server
Serve static files from the site root
root * <dir>
Set the document root for all paths
encode zstd gzip
Compress responses
respond "<text>" <status>
Send a fixed response
redir <to> permanent
Redirect to another URL
try_files {path} /index.html
Single-page app fallback
handle /api/* { ... }
Exclusive block for a path prefix
handle_path /api/* { ... }
Same, but strips the prefix first
header <Name> <value>
Set a response header
basic_auth { <user> <hash> }
Require a username and password
log
Enable access logs for the site
@<name> { ... }
Define a named request matcher
(<name>) { ... } / import <name>
Reusable snippet and its use
{$VAR} / {env.VAR}
Environment variable at load or run time
{$VAR} is substituted when the file is parsed; {env.VAR} per request.

Certificates and passwords

caddy trust
Install the local CA in system trust stores
caddy hash-password
Prompt for a password and print its hash
Paste the result into basic_auth. Default algorithm is bcrypt.

Recipes

Static site with SPA fallback
# Caddyfileexample.com {  root * /var/www/site  encode zstd gzip  try_files {path} /index.html  file_server}
Proxy an API, serve the rest
# Caddyfileexample.com {  handle /api/* {    reverse_proxy localhost:3000  }  handle {    root * /var/www/site    file_server  }}
Password-protect a site
caddy hash-password# Caddyfile: paste the hashexample.com {  basic_auth {    alice <hash>  }  reverse_proxy localhost:8080}
Edit, check, apply
caddy fmt --overwrite Caddyfilecaddy validate --config Caddyfilecaddy reload --config Caddyfile