diff --git a/src/docs/markdown/automatic-https.md b/src/docs/markdown/automatic-https.md
index 3b8cc20..6f180e6 100644
--- a/src/docs/markdown/automatic-https.md
+++ b/src/docs/markdown/automatic-https.md
@@ -75,8 +75,8 @@ Because HTTPS utilizes a shared, public infrastructure, you as the server admin
Caddy implicitly activates automatic HTTPS when it knows a domain name (i.e. hostname) or IP address it is serving. There are various ways to tell Caddy your domain/IP, depending on how you run or configure Caddy:
- A [site address](/docs/caddyfile/concepts#addresses) in the [Caddyfile](/docs/caddyfile)
-- A [host matcher](/docs/json/apps/http/servers/routes/match/host/) in a [JSON route](/docs/modules/http#servers/routes)
-- Command line flags like [--domain](/docs/command-line#caddy-file-server) or [--from](/docs/command-line#caddy-reverse-proxy)
+- A [host matcher](/docs/json/apps/http/servers/routes/match/host/) at the top-level in the [JSON routes](/docs/modules/http#servers/routes)
+- Command line flags like [`--domain`](/docs/command-line#caddy-file-server) or [`--from`](/docs/command-line#caddy-reverse-proxy)
- The [automate](/docs/json/apps/tls/certificates/automate/) certificate loader
Any of the following will prevent automatic HTTPS from being activated, either in whole or in part:
@@ -96,11 +96,12 @@ Any of the following will prevent automatic HTTPS from being activated, either i
When automatic HTTPS is activated, the following occurs:
-- Certificates are obtained and renewed for [all domain names](#hostname-requirements)
-- The default port (if any) is changed to the [HTTPS port](/docs/modules/http#https_port) `443`
+- Certificates are obtained and renewed for [all qualifying domain names](#hostname-requirements)
- HTTP is redirected to HTTPS (this uses [HTTP port](/docs/modules/http#http_port) `80`)
-Automatic HTTPS never overrides explicit configuration.
+Automatic HTTPS never overrides explicit configuration, it only augments it.
+
+If you already have a [server](/docs/json/apps/http/servers/) listening on the HTTP port, the HTTP->HTTPS redirect routes will be inserted after your routes with a host matcher, but before a user-defined catch-all route.
You can [customize or disable automatic HTTPS](/docs/json/apps/http/servers/automatic_https/) if necessary; for example, you can skip certain domain names or disable redirects (for Caddyfile, do this with [global options](/docs/caddyfile/options)).
diff --git a/src/docs/markdown/caddyfile/concepts.md b/src/docs/markdown/caddyfile/concepts.md
index b3599f5..e282700 100644
--- a/src/docs/markdown/caddyfile/concepts.md
+++ b/src/docs/markdown/caddyfile/concepts.md
@@ -30,13 +30,18 @@ The Caddyfile's structure can be described visually:
Key points:
- An optional [**global options block**](#global-options) can be the very first thing in the file.
+
- [Snippets](#snippets) or [named routes](#named-routes) may optionally appear next.
+
- Otherwise, the first line of the Caddyfile is **always** the [address(es)](#addresses) of the site to serve.
+
- All [directives](#directives) and [matchers](#matchers) **must** go in a site block. There is no global scope or inheritance across site blocks.
+
- If there is only one site block, its curly braces `{ }` are optional.
A Caddyfile consists of at least one or more site blocks, which always starts with one or more [addresses](#addresses) for the site. Any directives appearing before the address will be confusing to the parser.
+
### Blocks
Opening and closing a **block** is done with curly braces:
@@ -48,6 +53,7 @@ Opening and closing a **block** is done with curly braces:
```
- The open curly brace `{` must be at the end of its line and preceded by a space.
+
- The close curly brace `}` must be on its own line.
When there is only one site block, the curly braces (and indentation) are optional. This is for convenience to quickly define a single site, for example, this:
@@ -120,7 +126,7 @@ localhost {
Here, `lb_policy` is a subdirective to [`reverse_proxy`](/docs/caddyfile/directives/reverse_proxy) (it sets the load balancing policy to use between backends).
-**Unless otherwise documented, directives cannot be used within other directive blocks.** For example, `basicauth` cannot be used within `file_server` because the file server does not know how to do authentication; but you can use directives within [`route`](/docs/caddyfile/directives/route), [`handle`](/docs/caddyfile/directives/handle), and [`handle_path`](/docs/caddyfile/directives/handle_path) blocks because they are specifically designed to group directives together.
+**Unless otherwise documented, directives cannot be used within other directive blocks.** For example, [`basicauth`](/docs/caddyfile/directives/basicauth) cannot be used within [`file_server`](/docs/caddyfile/directives/file_server) because the file server does not know how to do authentication; but you can use directives within [`route`](/docs/caddyfile/directives/route), [`handle`](/docs/caddyfile/directives/handle), and [`handle_path`](/docs/caddyfile/directives/handle_path) blocks because they are specifically designed to group directives together.
Note that when the HTTP Caddyfile is adapted, HTTP handler directives are sorted according to a specific default [directive order](/docs/caddyfile/directives#directive-order) unless in a [`route`](/docs/caddyfile/directives/route) block, so the order of appearance of the directives does not matter except in `route` blocks.
@@ -202,7 +208,15 @@ If present, it must be the very first block in the config.
It is used to set options that apply globally, or not to any one site in particular. Inside, only global options can be set; you cannot use regular site directives in them.
-[Learn more](/docs/caddyfile/options) about the global options block.
+For example, to enable the `debug` global option, which is commonly used to produce verbose logs for troubleshooting:
+
+```caddy
+{
+ debug
+}
+```
+
+**[Read the Global Options page](/docs/caddyfile/options) to learn more.**
@@ -212,20 +226,28 @@ An address always appears at the top of the site block, and is usually the first
These are examples of valid addresses:
-- `localhost`
-- `example.com`
-- `:443`
-- `http://example.com`
-- `localhost:8080`
-- `127.0.0.1`
-- `[::1]:2015`
-- `*.example.com`
-- `http://`
+| Address | Effect |
+|----------------------|-----------------------------------|
+| `example.com` | HTTPS with managed [publicly-trusted certificate](/docs/automatic-https#hostname-requirements) |
+| `*.example.com` | HTTPS with managed [wildcard publicly-trusted certificate](/docs/caddyfile/patterns#wildcard-certificates) |
+| `localhost` | HTTPS with managed [locally-trusted certificate](/docs/automatic-https#local-https) |
+| `http://` | HTTP catch-all, affected by [`http_port`](/docs/caddyfile/options#http-port) |
+| `https://` | HTTPS catch-all, affected by [`https_port`](/docs/caddyfile/options#http-port) |
+| `http://example.com` | HTTP explicitly, with a `Host` matcher |
+| `example.com:443` | HTTPS due to matching the [`https_port`](/docs/caddyfile/options#http-port) default |
+| `:443` | HTTPS catch-all due to matching the [`https_port`](/docs/caddyfile/options#http-port) default |
+| `:8080` | HTTP on non-standard port, no `Host` matcher |
+| `localhost:8080` | HTTPS on non-standard port, due to having a valid domain |
+| `https://example.com:443` | HTTPS, but both `https://` and `:443` are redundant |
+| `127.0.0.1` | HTTPS, with a locally-trusted IP certificate |
+| `http://127.0.0.1` | HTTP, with an IP address `Host` matcher (rejects `localhost`) |
@@ -238,21 +260,44 @@ Wildcards (`*`) may be used, but only to represent precisely one label of the ho
To catch all hosts, omit the host portion of the address, for example, simply `https://`. This is useful when using [On-Demand TLS](/docs/automatic-https#on-demand-tls), when you don't know the domains ahead of time.
-If multiple sites share the same definition, you can list all of them together; notice how the commas indicate the continuation of addresses:
+If multiple sites share the same definition, you can list all of them together, either with spaces or commas. The following three examples are equivalent:
```caddy
-localhost:8080, example.com, www.example.com
+# Comma separated site addresses
+localhost:8080, example.com, www.example.com {
+ ...
+}
```
or
```caddy
-localhost:8080,
-example.com,
-www.example.com
+# Space separated site addresses
+localhost:8080 example.com www.example.com {
+ ...
+}
```
-An address must be unique; you cannot specify the same address more than once. [Placeholders](#placeholders) **cannot** be used in addresses, but you may use Caddyfile-style [environment variables](#environment-variables) in them.
+or
+
+```caddy
+# Comma and new-line separated site addresses
+localhost:8080,
+example.com,
+www.example.com {
+ ...
+}
+```
+
+An address must be unique; you cannot specify the same address more than once.
+
+[Placeholders](#placeholders) **cannot** be used in addresses, but you may use Caddyfile-style [environment variables](#environment-variables) in them:
+
+```caddy
+{$DOMAIN:localhost} {
+ ...
+}
+```
By default, sites bind on all network interfaces. If you wish to override this, use the [`bind` directive](/docs/caddyfile/directives/bind) or the [`default_bind` global option](/docs/caddyfile/options#default-bind) to do so.
@@ -260,7 +305,7 @@ By default, sites bind on all network interfaces. If you wish to override this,
## Matchers
-HTTP handler directives apply to all requests by default (unless otherwise documented).
+HTTP handler [directives](#directives) apply to all requests by default (unless otherwise documented).
[Request matchers](/docs/caddyfile/matchers) can be used to classify requests by a given criteria. With matchers, you can specify exactly which requests a certain directive applies to.
@@ -274,7 +319,7 @@ root @post /var/www # matcher token: @post
Matcher tokens can be omitted entirely to match all requests; for example, `*` does not need to be given if the next argument does not look like a path matcher.
-**[Read the page about request matchers](/docs/caddyfile/matchers) to learn more.**
+**[Read the Request Matchers page](/docs/caddyfile/matchers) to learn more.**
@@ -328,27 +373,41 @@ You can use any [Caddy placeholders](/docs/conventions#placeholders) in the Cadd
You can define special blocks called snippets by giving them a name surrounded in parentheses:
```caddy
-(redirect) {
- @http {
- protocol http
+(logging) {
+ log {
+ output file /var/log/caddy.log
+ format json
}
- redir @http https://{host}{uri}
}
```
-And then you can reuse this anywhere you need:
+And then you can reuse this anywhere you need, using the special [`import`](/docs/caddyfile/directives/import) directive:
-```caddy-d
-import redirect
+```caddy
+example.com {
+ import logging
+}
+
+www.example.com {
+ import logging
+}
```
-The [`import`](/docs/caddyfile/directives/import) directive can also be used to include other files in its place. As a special case, it can appear almost anywhere within the Caddyfile.
+The [`import`](/docs/caddyfile/directives/import) directive can also be used to include other files in its place. If the argument does not match a defined snippet, it will be tried as a file. It also supports globs to import multiple files. As a special case, it can appear anywhere within the Caddyfile (except as an argument to another directive), including outside of site blocks:
-You can pass arguments to imported configuration and use them like so:
+```caddy
+{
+ email admin@example.com
+}
+
+import sites/*
+```
+
+You can pass arguments to an imported configuration (snippets or files) and use them like so:
```caddy
(snippet) {
- respond "Yahaha! You found {args[0]}!"
+ respond "Yahaha! You found {args[0]}!"
}
a.example.com {
@@ -360,10 +419,12 @@ b.example.com {
}
```
+**[Read the `import` directive page](/docs/caddyfile/directives/import) to learn more.**
+
## Named Routes
-⚠️ Experimental
+⚠️ Experimental
Named routes use syntax similar to [snippets](#snippets); they're a special block defined outside of site blocks, prefixed with `&(` and ending in `)` with the name in between.
@@ -375,13 +436,20 @@ Named routes use syntax similar to [snippets](#snippets); they're a special bloc
And then you can reuse this named route within any site:
-```caddy-d
-invoke app-proxy
+```caddy
+example.com {
+ invoke app-proxy
+}
+
+www.example.com {
+ invoke app-proxy
+}
```
This is particularly useful to reduce memory usage if the same route is needed in many different sites, or if multiple different matcher conditions are needed to invoke the same route.
-See the [`invoke` directive](/docs/caddyfile/directives/invoke) documentation for more details.
+**[Read the `invoke` directive page](/docs/caddyfile/directives/invoke) to learn more.**
+
## Comments
@@ -402,16 +470,35 @@ The hash character `#` for a comment cannot appear in the middle of a token (i.e
If your configuration relies on environment variables, you can use them in the Caddyfile:
```caddy
-{$SITE_ADDRESS}
+{$ENV}
```
-Environment variables in this form are substituted before Caddyfile parsing begins, so they can expand to empty values, partial tokens, complete tokens, or even multiple tokens and lines.
+Environment variables in this form are substituted **before Caddyfile parsing begins**, so they can expand to empty values (i.e. `""`), partial tokens, complete tokens, or even multiple tokens and lines.
+
+For example, a environement variable `UPSTREAMS="app1:8080 app2:8080 app3:8080"` would expand to multiple [tokens](#tokens-and-quotes):
+
+```caddy
+example.com {
+ reverse_proxy {$UPSTREAMS}
+}
+```
A default value can be specified for when the environment variable is not found, by using `:` as the delimiter between the variable name and the default value:
```caddy
-{$DOMAIN:localhost}
+{$DOMAIN:localhost} {
+
+}
```
-If you want to defer the substitution of an environment variable until runtime, you can use the [standard `{env.*}` placeholders](/docs/conventions#placeholders). Note that not all config parameters support these placeholders though, since module developers need to add a line of code to perform the replacement. If it doesn't seem to work, please file an issue to request support for it.
+If you want to **defer the substitution** of an environment variable until runtime, you can use the [standard `{env.*}` placeholders](/docs/conventions#placeholders). Note that not all config parameters support these placeholders though, since module developers need to add a line of code to perform the replacement. If it doesn't seem to work, please file an issue to request support for it.
+For example, if you have the [`caddy-dns/cloudflare` plugin ](https://github.com/caddy-dns/cloudflare) installed and wish to configure the [DNS challenge](/docs/automatic-https#dns-challenge), you can pass your `CLOUDFLARE_API_TOKEN` environment variable to the plugin like this:
+
+```caddy
+{
+ acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
+}
+```
+
+If you're running Caddy as a systemd service, see [these instructions](/docs/running#overrides) for setting service overrides to define your environment variables.
diff --git a/src/docs/markdown/caddyfile/directives/acme_server.md b/src/docs/markdown/caddyfile/directives/acme_server.md
index 84ff39a..d30bbc8 100644
--- a/src/docs/markdown/caddyfile/directives/acme_server.md
+++ b/src/docs/markdown/caddyfile/directives/acme_server.md
@@ -29,3 +29,42 @@ acme_server [] {
- **lifetime** (Default: `12h`) is a [duration](/docs/conventions#durations) which specifies the validity period for issued certificates. This value must be less than the lifetime of the [intermediate certificate](/docs/caddyfile/options#intermediate-lifetime) used for signing. It is not recommended to change this unless absolutely necessary.
- **resolvers** are the addresses of DNS resolvers to use when looking up the TXT records for solving ACME DNS challenges. Accepts [network addresses](/docs/conventions#network-addresses) defaulting to UDP and port 53 unless specified. If the host is an IP address, it will be dialed directly to resolve the upstream server. If the hot is not an IP address, the addresses are resolved using the [name resolution convention](https://golang.org/pkg/net/#hdr-Name_Resolution) of the Go standard library. If multiple resolvers are specified, then one is chosen at random.
+
+
+## Examples
+
+To serve an ACME server with ID `home` on the domain `acme.example.com`, with the CA customized via the [`pki` global option](/docs/caddyfile/options#pki-options), and issuing its own certificate using the `internal` issuer:
+
+```caddy
+{
+ pki {
+ ca home {
+ name "My Home CA"
+ }
+ }
+}
+
+acme.example.com {
+ tls {
+ issuer internal {
+ ca home
+ }
+ }
+ acme_server {
+ ca home
+ }
+}
+```
+
+If you have another Caddy server, it can use the above ACME server to issue its own certificates:
+
+```caddy
+{
+ acme_ca https://acme.example.com/acme/home/directory
+ acme_ca_root /path/to/home_ca_root.crt
+}
+
+example.com {
+ respond "Hello, world!"
+}
+```
diff --git a/src/docs/markdown/caddyfile/directives/basicauth.md b/src/docs/markdown/caddyfile/directives/basicauth.md
index 9631563..43c3f7d 100644
--- a/src/docs/markdown/caddyfile/directives/basicauth.md
+++ b/src/docs/markdown/caddyfile/directives/basicauth.md
@@ -37,11 +37,30 @@ basicauth [] [ []] {
## Examples
-Protect all resources in /secret so only Bob can access them with the password "hiccup":
+Require authentication for all requests to `example.com`:
-```caddy-d
-basicauth /secret/* {
- Bob $2a$14$Zkx19XLiW6VYouLHR5NmfOFU0z2GTNmpkT/5qqR7hx4IjWJPDhjvG
+```caddy
+example.com {
+ basicauth {
+ # Username "Bob", password "hiccup"
+ Bob $2a$14$Zkx19XLiW6VYouLHR5NmfOFU0z2GTNmpkT/5qqR7hx4IjWJPDhjvG
+ }
+ respond "Welcome, {http.auth.user.id}" 200
+}
+```
+
+Protect files in `/secret/` so only `Bob` can access them (and anyone can see other paths):
+
+```caddy
+example.com {
+ root * /srv
+
+ basicauth /secret/* {
+ # Username "Bob", password "hiccup"
+ Bob $2a$14$Zkx19XLiW6VYouLHR5NmfOFU0z2GTNmpkT/5qqR7hx4IjWJPDhjvG
+ }
+
+ file_server
}
```
diff --git a/src/docs/markdown/caddyfile/directives/bind.md b/src/docs/markdown/caddyfile/directives/bind.md
index 744e6ac..151ed05 100644
--- a/src/docs/markdown/caddyfile/directives/bind.md
+++ b/src/docs/markdown/caddyfile/directives/bind.md
@@ -4,7 +4,9 @@ title: bind (Caddyfile directive)
# bind
-Overrides the interface to which the server's socket should bind. Normally, the listener binds to the empty (wildcard) interface. However, you may force the listener to bind to another hostname or IP instead. (This directive accepts only a host, not a port.)
+Overrides the interface to which the server's socket should bind.
+
+Normally, the listener binds to the empty (wildcard) interface. However, you may force the listener to bind to another hostname or IP instead. This directive accepts only a host, not a port. The port is determined by the [site address](/docs/caddyfile/concepts#addresses) (defaulting to `443`).
Note that binding sites inconsistently may result in unintended consequences. For example, if two sites on the same port resolve to `127.0.0.1` and only one of those sites is configured with `bind 127.0.0.1`, then only one site will be accessible since the other will bind to the port without a specific host; the OS will choose the more specific matching socket. (Virtual hosts are not shared across different listeners.)
@@ -24,18 +26,54 @@ bind
To make a socket accessible only on the current machine, bind to the loopback interface (localhost):
-```caddy-d
-bind 127.0.0.1
+```caddy
+example.com {
+ bind 127.0.0.1
+}
```
To include IPv6:
-```caddy-d
-bind 127.0.0.1 [::1]
+```caddy
+example.com {
+ bind 127.0.0.1 [::1]
+}
+```
+
+To bind to `10.0.0.1:8080`:
+
+```caddy
+example.com:8080 {
+ bind 10.0.0.1
+}
```
To bind to a Unix domain socket at `/run/caddy`:
-```caddy-d
-bind unix//run/caddy
+```caddy
+example.com {
+ bind unix//run/caddy
+}
+```
+
+To change the file permission to be writable by all users ([defaults](/docs/conventions#network-addresses) to `0200`, which is only writable by the owner):
+
+```caddy
+example.com {
+ bind unix//run/caddy|0222
+}
+```
+
+To bind one domain to two different interfaces, with different responses:
+
+```caddy
+example.com {
+ bind 10.0.0.1
+ respond "One"
+}
+
+example.com {
+ bind 10.0.0.2
+ respond "Two"
+}
```
diff --git a/src/docs/markdown/caddyfile/directives/encode.md b/src/docs/markdown/caddyfile/directives/encode.md
index dd5a84d..3f417f6 100644
--- a/src/docs/markdown/caddyfile/directives/encode.md
+++ b/src/docs/markdown/caddyfile/directives/encode.md
@@ -55,10 +55,12 @@ encode [] {
}
```
+
## Response matcher
**Response matchers** can be used to filter (or classify) responses by specific criteria.
+
### status
```caddy-d
@@ -69,10 +71,12 @@ By HTTP status code.
- **<code...>** is a list of HTTP status codes. Special cases are `2xx`, `3xx`, ... which match against all status codes in the range of 200-299, 300-399, ... respectively
+
### header
See the [header](/docs/caddyfile/matchers#header) request matcher for the supported syntax.
+
## Examples
Enable Gzip compression:
@@ -86,3 +90,13 @@ Enable Zstandard and Gzip compression (with Zstandard implicitly preferred, sinc
```caddy-d
encode zstd gzip
```
+
+And in a full site, compressing static files served by [`file_server`](file_server):
+
+```caddy
+example.com {
+ root * /srv
+ encode zstd gzip
+ file_server
+}
+```
diff --git a/src/docs/markdown/caddyfile/directives/error.md b/src/docs/markdown/caddyfile/directives/error.md
index e50f250..dad79bb 100644
--- a/src/docs/markdown/caddyfile/directives/error.md
+++ b/src/docs/markdown/caddyfile/directives/error.md
@@ -23,6 +23,7 @@ error [] | [] {
To clarify, the first non-matcher argument can be either a 3-digit status code, or an error message string. If it is an error message, the next argument can be the status code.
+
## Examples
Trigger an error on certain request paths, and use [`handle_errors`](handle_errors) to write a response:
diff --git a/src/docs/markdown/caddyfile/directives/file_server.md b/src/docs/markdown/caddyfile/directives/file_server.md
index 6fb285d..31dc4b7 100644
--- a/src/docs/markdown/caddyfile/directives/file_server.md
+++ b/src/docs/markdown/caddyfile/directives/file_server.md
@@ -85,9 +85,11 @@ file_server /static/*
The `file_server` directive is usually paired with the [`root` directive](root) to set the root path from which to serve files:
-```caddy-d
-root * /home/user/public_html
-file_server
+```caddy
+example.com {
+ root * /srv
+ file_server
+}
```
+```caddy
+{
+ default_bind 10.0.0.1
+}
+```
+
##### `order`
@@ -188,8 +203,10 @@ Assigns an order to HTTP handler directive(s). As HTTP handlers execute in a seq
For example, to use the [`replace-response` plugin](https://github.com/caddyserver/replace-response), you'd want to make sure its directive is ordered after `encode` so that it can perform replacements before the response is encoded (because responses flow up the handler chain, not down):
-```caddy-d
-order replace after encode
+```caddy
+{
+ order replace after encode
+}
```
@@ -198,76 +215,186 @@ Configures Caddy's storage mechanism. The default is [`file_system`](/docs/json/
For example, to change the file system's storage location:
-```caddy-d
-storage file_system /path/to/custom/location
+```caddy
+{
+ storage file_system /path/to/custom/location
+}
```
Customizing the storage module is typically needed when syncing Caddy's storage across multiple instances of Caddy to make sure they all use the same certificates and keys. See the [Automatic HTTPS section on storage](/docs/automatic-https#storage) for more details.
##### `storage_clean_interval`
-How often to scan storage units for old or expired assets and remove them. These scans exert lots of reads (and list operations) on the storage module, so choose a longer interval for large deployments. Accepts [duration values](/docs/conventions#durations). Default: `24h`.
+How often to scan storage units for old or expired assets and remove them. These scans exert lots of reads (and list operations) on the storage module, so choose a longer interval for large deployments. Accepts [duration values](/docs/conventions#durations).
Storage will always be cleaned when the process first starts. Then, a new cleaning will be started this duration after the previous cleaning started if the previous cleaning finished in less than half the time of this interval (otherwise next start will be skipped).
+Default: `24h`
-##### `renew_interval`
-How often to scan all loaded, managed certificates for expiration, and trigger renewal if expired. Default: `10m`.
+```caddy
+{
+ storage_clean_interval 7d
+}
+```
-##### `ocsp_interval`
-How often to check if OCSP staples need updating. Default: `1h`.
##### `admin`
-Customizes the [admin API endpoint](/docs/api). Accepts placeholders. If `off`, then the admin endpoint will be disabled. If disabled, config changes will be impossible without stopping and starting the server. Remember to use the `--address` CLI flag to specify the current admin endpoint when changing this value if the currently-running admin endpoint is not at the default address.
+Customizes the [admin API endpoint](/docs/api). Accepts placeholders. Takes [network addresses](/docs/conventions#network-addresses).
-- **origins** configures the list of remotes/origins that are allowed to connect to the endpoint.
+Default: `localhost:2019`, unless the `CADDY_ADMIN` environment variable is set.
+
+If set to `off`, then the admin endpoint will be disabled. When disabled, **config changes will be impossible** without stopping and starting the server, since the [`caddy reload` command](/docs/command-line#caddy-reload) uses the admin API to push the new config to the running server.
+
+Remember to use the `--address` CLI flag with compatible [commands](/docs/command-line) to specify the current admin endpoint, if the address of the running server was changed from the default.
+
+Also supports these sub-options:
+
+- **origins** configures the list of origins that are allowed to connect to the endpoint.
+
+ A default is intelligently chosen:
+ - if the listen address is loopback (e.g. `localhost` or a loopback IP, or a unix socket) then the allowed origins are `localhost`, `::1` and `127.0.0.1`, joined with the listen address port (so `localhost:2019` is a valid origin).
+ - if the listen address is not loopback, then the allowed origin is the same as the listen address.
+
+ If the listen address host is not a wildcard interface (wildcards include: empty string, or `0.0.0.0`, or `[::]`), then `Host` header enforcement is performed. Effectively, this means that by default, the `Host` header is validated to be in `origins`, since the interface is `localhost`. But for an address like `:2020` which has a wildcard interface, `Host` header validation is not performed.
+
+- **enforce_origin** enables enforcement of the `Origin` request header.
+
+ This is most useful when the listen address is a wildcard interface (since `Host` is not validated), and the admin API is exposed to the public internet. It enables CORS preflight checks and ensures that the `Origin` header is validated against the `origins` list. Only use this if you're running Caddy on your development machine and need to access the admin API from a web browser.
+
+For example, to expose the admin API on a different port, on all interfaces — ⚠️ this port **should not be exposed publicly**, otherwise anyone can control your server; consider enabling origin enforcement if you need it to be public:
+
+```caddy
+{
+ admin :2020
+}
+```
+
+To turn off the admin API — ⚠️ this makes **config reloads impossible** without stopping and starting the server:
+
+```caddy
+{
+ admin off
+}
+```
+
+To use a [unix socket](/docs/conventions#network-addresses) for the admin API, allowing access control via file permissions:
+
+```caddy
+{
+ admin unix//run/caddy-admin.sock
+}
+```
+
+To only allow requests having a matching `Origin` header:
+
+```caddy
+{
+ admin :2019 {
+ origins localhost
+ enforce_origin
+ }
+}
+```
-- **enforce_origin** enables enforcement of the Origin header. (This is different from enforcing origins generally, which is always done.)
##### `persist_config`
Controls whether the current JSON config should be persisted to the [configuration directory](/docs/conventions#configuration-directory), to avoid losing config changes performed via the admin API. Currently, only the `off` option is supported. By default, the config is persisted.
+```caddy
+{
+ persist_config off
+}
+```
+
##### `log`
-Configures named loggers. The name can be passed to indicate a specific logger for which to customize the behavior. If no name is specified, the behavior of the `default` logger is modified. Multiple loggers with different names can be configured by using the `log` multiple times. You can read more about the `default` logger and an explanation of [how logging works in Caddy](/docs/logging).
+Configures named loggers.
+
+The name can be passed to indicate a specific logger for which to customize the behavior. If no name is specified, the behavior of the `default` logger is modified. You can read more about the `default` logger and an explanation of [how logging works in Caddy](/docs/logging).
+
+Multiple loggers with different names can be configured by using the `log` multiple times.
The differs from the [`log` directive](/docs/caddyfile/directives/log), which only configures HTTP request logging (also known as access logs). The `log` global option shares its configuration structure with the directive (except for `include` and `exclude`), and complete documentation can be found on the directive's page.
-- **output** configures where to write the logs. See the [`log` directive](/docs/caddyfile/directives/log#output-modules) for complete documentation.
-- **format** describes how to encode, or format, the logs. See the [`log` directive](/docs/caddyfile/directives/log#format-modules) for complete documentation.
-- **level** is the minimum entry level to log. Possible values: `DEBUG`, `INFO`, `WARN`, `ERROR`, `PANIC`, `FATAL`. Default: `INFO`.
-- **include** specifies the log names to be included in this logger. For example, to include only logs emitted by the admin API, you would include `admin.api`. By default, this list is empty (i.e. all logs are included).
-- **exclude** specifies the log names to be excluded from this logger. For example, to exclude only HTTP access logs, you would exclude `http.log.access`. By default, this list is empty (i.e. no logs are excluded).
+- **output** configures where to write the logs.
+
+ See the [`log` directive](/docs/caddyfile/directives/log#output-modules) for complete documentation.
+
+- **format** describes how to encode, or format, the logs.
+
+ See the [`log` directive](/docs/caddyfile/directives/log#format-modules) for complete documentation.
+
+- **level** is the minimum entry level to log.
+
+ Default: `INFO`.
+
+ Possible values: `DEBUG`, `INFO`, `WARN`, `ERROR`, and very rarely, `PANIC`, `FATAL`.
+
+- **include** specifies the log names to be included in this logger.
+
+ By default, this list is empty (i.e. all logs are included).
+
+ For example, to include only logs emitted by the admin API, you would include `admin.api`.
+
+- **exclude** specifies the log names to be excluded from this logger.
+
+ By default, this list is empty (i.e. no logs are excluded).
+
+ For example, to exclude only HTTP access logs, you would exclude `http.log.access`.
The logger names that `include` and `exclude` accept depend on the modules used, and easiest way to discover them is from prior logs.
Here is an example logging as json all http access logs and admin logs to stdout:
```caddy
-log default {
- output stdout
- format json
- include http.log.access admin.api
+{
+ log default {
+ output stdout
+ format json
+ include http.log.access admin.api
+ }
}
```
##### `grace_period`
-Defines the grace period for shutting down HTTP servers (i.e. during config changes or when Caddy is stopping). During the grace period, no new connections are accepted, idle connections are closed, and active connections are impatiently waited upon to finish their requests. If clients do not finish their requests within the grace period, the server will be forcefully terminated to allow the reload to complete and free up resources. Accepts [duration values](/docs/conventions#durations). By default, the grace period is eternal, which means connections are never forcefully closed.
+Defines the grace period for shutting down HTTP servers (i.e. during config changes or when Caddy is stopping).
+
+During the grace period, no new connections are accepted, idle connections are closed, and active connections are impatiently waited upon to finish their requests. If clients do not finish their requests within the grace period, the server will be forcefully terminated to allow the reload to complete and free up resources. Accepts [duration values](/docs/conventions#durations).
+
+By default, the grace period is eternal, which means connections are never forcefully closed.
+
+```caddy
+{
+ grace_period 10s
+}
+```
##### `shutdown_delay`
-Defines a duration before the grace period during which a server that is going to be stopped continues to operate normally, except the `{http.shutting_down}` placeholder evaluates to `true` and `{http.time_until_shutdown}` gives the time until the grace period begins. This causes a delay if any server is being shut down as part of a config change and effectively schedules the change for a later time. It is useful for announcing to health checkers of this server's impending doom and to give time for a load balancer to move it out of the rotation; for example:
+Defines a [duration](/docs/conventions#durations)
+_before_ the [grace period](#grace_period) during which a server that is going to be stopped continues to operate normally, except the `{http.shutting_down}` placeholder evaluates to `true` and `{http.time_until_shutdown}` gives the time until the grace period begins.
-```caddy-d
-handle /health-check {
- @goingDown vars {http.shutting_down} true
- respond @goingDown "Bye-bye in {http.time_until_shutdown}" 503
- respond 200
+This causes a delay if any server is being shut down as part of a config change, and effectively schedules the change for a later time. It is useful for announcing to health checkers of this server's impending doom and to give time for a load balancer to move it out of the rotation; for example:
+
+```caddy
+{
+ shutdown_delay 30s
+}
+
+example.com {
+ handle /health-check {
+ @goingDown vars {http.shutting_down} true
+ respond @goingDown "Bye-bye in {http.time_until_shutdown}" 503
+ respond 200
+ }
+ handle {
+ respond "Hello, world!"
+ }
}
```
@@ -291,10 +418,16 @@ There are a few modes to choose from:
This option does not affect Caddy's default protocol, which is always HTTPS, when a site address has a valid domain name. This means that `auto_https off` will not cause your site to be served over HTTP, it will only disable automatic certificate management and redirects.
-This means that if you wish to serve your site over HTTP, you should change your [site address](/docs/caddyfile/concepts#addresses) to be prefixed with `http://` or suffixed with `:80`.
+This means that if you wish to serve your site over HTTP, you should change your [site address](/docs/caddyfile/concepts#addresses) to be prefixed with `http://` or suffixed with `:80` (or the [`http_port` option](#http_port)).
+```caddy
+{
+ auto_https disable_redirects
+}
+```
+
##### `email`
Your email address. Mainly used when creating an ACME account with your CA, and is highly recommended in case there are problems with your certificates.
@@ -305,44 +438,112 @@ Keep in mind that Let's Encrypt may send you emails about your certificate neari
+```caddy
+{
+ email admin@example.com
+}
+```
+
##### `default_sni`
Sets a default TLS ServerName for when clients do not use SNI in their ClientHello.
+```caddy
+{
+ default_sni example.com
+}
+```
+
##### `fallback_sni`
-If configured, the fallback becomes the TLS ServerName in the ClientHello if the original ServerName doesn't match any certificates in the cache. The uses for this are very niche; typically if a client is a CDN and passes through the ServerName of the downstream handshake but can accept a certificate with the origin's hostname instead, then you would set this as your origin's hostname. Note that Caddy must be managing a certificate for this name. ⚠️ Experimental
+⚠️ Experimental
+
+If configured, the fallback becomes the TLS ServerName in the ClientHello if the original ServerName doesn't match any certificates in the cache.
+
+The uses for this are very niche; typically if a client is a CDN and passes through the ServerName of the downstream handshake but can accept a certificate with the origin's hostname instead, then you would set this as your origin's hostname. Note that Caddy must be managing a certificate for this name.
+
+```caddy
+{
+ fallback_sni example.com
+}
+```
##### `local_certs`
-Causes all certificates to be issued internally by default, rather than through a (public) ACME CA such as Let's Encrypt. This is useful in development environments.
+Causes **all** certificates to be issued internally by default, rather than through a (public) ACME CA such as Let's Encrypt. This is useful as a quick toggle in development environments.
+
+```caddy
+{
+ local_certs
+}
+```
##### `skip_install_trust`
Skips the attempts to install the local CA's root into the system trust store, as well as into Java and Mozilla Firefox trust stores.
+```caddy
+{
+ skip_install_trust
+}
+```
+
##### `acme_ca`
Specifies the URL to the ACME CA's directory. It is strongly recommended to set this to Let's Encrypt's [staging endpoint ](https://letsencrypt.org/docs/staging-environment/) for testing or development. Default: ZeroSSL and Let's Encrypt's production endpoints.
Note that a globally-configured ACME CA may not apply to all sites; see the [hostname requirements](/docs/automatic-https#hostname-requirements) for using the default ACME issuer(s).
+```caddy
+{
+ acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
+}
+```
+
##### `acme_ca_root`
Specifies a PEM file that contains a trusted root certificate for ACME CA endpoints, if not in the system trust store.
+```caddy
+{
+ acme_ca_root /path/to/ca/root.pem
+}
+```
+
##### `acme_eab`
Specifies an External Account Binding to use for all ACME transactions.
+For example, with mock ZeroSSL credentials:
+
+```caddy
+{
+ acme_eab GD-VvWydSVFuss_GhBwYQQ MjXU3MH-Z0WQ7piMAnVsCpD1shgMiWx6ggPWiTmydgUaj7dWWWfQfA
+}
+```
+
##### `acme_dns`
-Configures the ACME DNS challenge provider to use for all ACME transactions. The tokens following the name of the provider set up the provider the same as if specified in the [`tls` directive's `acme` issuer](/docs/caddyfile/directives/tls#acme).
+Configures the [ACME DNS challenge](/docs/automatic-https#dns-challenge) provider to use for all ACME transactions.
+
+Requires a custom build of Caddy with a plugin for your DNS provider.
+
+The tokens following the name of the provider set up the provider the same as if specified in the [`tls` directive's `acme` issuer](/docs/caddyfile/directives/tls#acme).
+
+```caddy
+{
+ acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
+}
+```
##### `on_demand_tls`
Configures [On-Demand TLS](/docs/automatic-https#on-demand-tls) where it is enabled, but does not enable it (to enable it, use the [`on_demand` subdirective of the `tls` directive](/docs/caddyfile/directives/tls#syntax)). Required for use in production environments, to prevent abuse.
-- **ask** will cause Caddy to make an HTTP request to the given URL with a query string of `?domain=` containing the value of the domain name. If the endpoint returns a `2xx` status code, Caddy will be authorized to obtain a certificate for that name. Any other status code will result in cancelling issuance of the certificate.
+- **ask** will cause Caddy to make an HTTP request to the given URL, asking whether a domain is allowed to have a certificate issued.
+
+ The request has a query string of `?domain=` containing the value of the domain name.
+
+ If the endpoint returns a `2xx` status code, Caddy will be authorized to obtain a certificate for that name. Any other status code will result in cancelling issuance of the certificate and erroring the TLS handshake.