mirror of
https://github.com/caddyserver/caddy.git
synced 2025-08-11 09:16:26 -04:00
Updated v2: Documentation (markdown)
parent
7efba6c6a0
commit
b6db30c1a4
@ -1,6 +1,6 @@
|
||||
(This documentation is very much a work in progress!)
|
||||
|
||||
## Contents
|
||||
# Contents
|
||||
|
||||
- [Command-line interface]()
|
||||
- [start]()
|
||||
@ -22,11 +22,13 @@
|
||||
- [storage]()
|
||||
- [caddy.storage.file_system]()
|
||||
- [apps]()
|
||||
- [http]()
|
||||
- [tls]()
|
||||
|
||||
|
||||
## Command-line interface
|
||||
# Command-line interface
|
||||
|
||||
### start
|
||||
## start
|
||||
|
||||
```
|
||||
$ caddy start
|
||||
@ -37,7 +39,7 @@ Starts the Caddy process, optionally bootstrapped with an
|
||||
initial config file. Blocks until server is successfully
|
||||
running (or fails to run), then returns.
|
||||
|
||||
### run
|
||||
## run
|
||||
|
||||
```
|
||||
$ caddy run
|
||||
@ -46,7 +48,7 @@ $ caddy run
|
||||
|
||||
Same as `start`, but blocks indefinitely.
|
||||
|
||||
### stop
|
||||
## stop
|
||||
|
||||
```
|
||||
$ caddy stop
|
||||
@ -55,7 +57,7 @@ $ caddy stop
|
||||
Stops the running Caddy process. (Note: this will stop any process named the same as the executable file.)
|
||||
|
||||
|
||||
### version
|
||||
## version
|
||||
|
||||
```
|
||||
$ caddy version
|
||||
@ -63,7 +65,7 @@ $ caddy version
|
||||
|
||||
Prints the version.
|
||||
|
||||
### list-modules
|
||||
## list-modules
|
||||
|
||||
```
|
||||
$ caddy list-modules
|
||||
@ -71,7 +73,7 @@ $ caddy list-modules
|
||||
|
||||
Prints the modules that are installed.
|
||||
|
||||
### environ
|
||||
## environ
|
||||
|
||||
```
|
||||
$ caddy environ
|
||||
@ -81,19 +83,19 @@ Prints the environment as seen by caddy. Can be useful when debugging init syste
|
||||
|
||||
|
||||
|
||||
## Admin endpoint
|
||||
# Admin endpoint
|
||||
|
||||
Caddy is configured through an administration endpoint which is an HTTP listener with a REST API.
|
||||
|
||||
Default address: `localhost:2019`
|
||||
|
||||
### POST /load
|
||||
## POST /load
|
||||
|
||||
Sets Caddy's configuration to the JSON body. The `Content-Type` header must indicate a JSON payload, e.g. `application/json`.
|
||||
|
||||
_Enterprise_: If you are using the `/config` endpoint to modify configuration instead, you MUST NOT use `/load` because it lacks the capabilities for partial configuration updates.
|
||||
|
||||
#### Example
|
||||
### Example
|
||||
|
||||
```bash
|
||||
$ curl -X POST "http://localhost:2019/load" \
|
||||
@ -101,13 +103,13 @@ $ curl -X POST "http://localhost:2019/load" \
|
||||
-d @caddy.json
|
||||
```
|
||||
|
||||
### GET /config/[scope]
|
||||
## GET /config/[scope]
|
||||
|
||||
🏢 _Enterprise_
|
||||
|
||||
Exports Caddy's current configuration. Returns a JSON body. Any path appended to this endpoint will traverse the configuration and return only the scope scope.
|
||||
|
||||
#### Examples
|
||||
### Examples
|
||||
|
||||
```bash
|
||||
$ curl "http://localhost:2019/config/"
|
||||
@ -120,13 +122,13 @@ $ curl "http://localhost:2019/config/apps/http/servers/myserver/listen"
|
||||
```
|
||||
|
||||
|
||||
### POST /config/[scope]
|
||||
## POST /config/[scope]
|
||||
|
||||
🏢 _Enterprise_
|
||||
|
||||
Changes Caddy's configuration at the named scope to the JSON body of the request. If the named scope is an array, POST appends; if an object, it creates or replaces.
|
||||
|
||||
#### Example
|
||||
### Example
|
||||
|
||||
```bash
|
||||
$ curl -X POST \
|
||||
@ -136,13 +138,13 @@ $ curl -X POST \
|
||||
```
|
||||
|
||||
|
||||
### PUT /config/[scope]
|
||||
## PUT /config/[scope]
|
||||
|
||||
🏢 _Enterprise_
|
||||
|
||||
Changes Caddy's configuration at the named scope to the JSON body of the request. If the named scope is an array, PUT inserts; if an object, it strictly creates a new value.
|
||||
|
||||
#### Example
|
||||
### Example
|
||||
|
||||
```bash
|
||||
$ curl -X PUT \
|
||||
@ -152,13 +154,13 @@ $ curl -X PUT \
|
||||
```
|
||||
|
||||
|
||||
### PATCH /config/[scope]
|
||||
## PATCH /config/[scope]
|
||||
|
||||
🏢 _Enterprise_
|
||||
|
||||
Changes Caddy's configuration at the named scope to the JSON body of the request. PATCH strictly replaces an existing value or array element.
|
||||
|
||||
#### Example
|
||||
### Example
|
||||
|
||||
```bash
|
||||
$ curl -X PUT \
|
||||
@ -168,13 +170,13 @@ $ curl -X PUT \
|
||||
```
|
||||
|
||||
|
||||
### DELETE /config/[scope]
|
||||
## DELETE /config/[scope]
|
||||
|
||||
🏢 _Enterprise_
|
||||
|
||||
Changes Caddy's configuration at the named scope to the JSON body of the request. DELETE deletes the value at the named scope.
|
||||
|
||||
#### Example
|
||||
### Example
|
||||
|
||||
```bash
|
||||
$ curl -X DELETE "http://localhost:2019/config/apps/http/servers/myserver"
|
||||
@ -182,7 +184,7 @@ $ curl -X DELETE "http://localhost:2019/config/apps/http/servers/myserver"
|
||||
|
||||
|
||||
|
||||
## Caddy modules
|
||||
# Caddy modules
|
||||
|
||||
Caddy modules are distinct from [Go modules](https://github.com/golang/go/wiki/Modules), although technically speaking, Caddy modules can be implemented by Go modules. When we talk about modules here, we mean Caddy modules.
|
||||
|
||||
@ -202,7 +204,7 @@ _Guest modules_ (or _child modules_) are modules which get loaded or initialized
|
||||
|
||||
|
||||
|
||||
## Config structure
|
||||
# Config structure
|
||||
|
||||
Caddy configuration is a JSON document.
|
||||
|
||||
@ -218,7 +220,7 @@ At the top level, you'll find properties needed for Caddy's basic functionality:
|
||||
}
|
||||
```
|
||||
|
||||
### admin
|
||||
## admin
|
||||
|
||||
Configures the administration endpoint.
|
||||
|
||||
@ -230,13 +232,13 @@ Configures the administration endpoint.
|
||||
|
||||
- `listen`: the address to which the admin endpoint's listener should bind itself
|
||||
|
||||
### storage
|
||||
## storage
|
||||
|
||||
Configures Caddy's default storage module.
|
||||
|
||||
Default: The local file system (`caddy.storage.file_system`). If `XDG_DATA_HOME` is set, then `$XDG_DATA_HOME/caddy` is the folder. Otherwise, `$HOME/.local/share/caddy` is the folder.
|
||||
|
||||
#### caddy.storage.file_system
|
||||
### caddy.storage.file_system
|
||||
|
||||
```json
|
||||
{
|
||||
@ -249,7 +251,130 @@ Default: The local file system (`caddy.storage.file_system`). If `XDG_DATA_HOME`
|
||||
- `root`: The base path in which things should be stored
|
||||
|
||||
|
||||
### apps
|
||||
## apps
|
||||
|
||||
Each app to initialize should be keyed by its name (i.e. module ID).
|
||||
|
||||
### http
|
||||
|
||||
The `http` app implements an HTTP server with automatic HTTPS. It consists of servers which you name and describe. Each server has listeners and routes.
|
||||
|
||||
Routes are not your traditional notion of routes (i.e. "GET /foo/bar" -> someFunc). Routes in Caddy 2 are much more powerful. They are given in an ordered list, and each route has three parts: match, apply, respond. All parts are optional. Match is the "if" statement of each route. Each route takes a list of matcher sets. A matcher set comprises matchers of various types. A matcher may comprise multiple values.
|
||||
|
||||
The boolean logic of request matching goes like this:
|
||||
|
||||
- Matcher sets are OR'ed (first matching matcher set is sufficient)
|
||||
- Matchers within a site are AND'ed (all matchers in the set must match)
|
||||
- Values within a specific matcher are OR'ed (but this could vary depending on the matcher; some don't allow multiple values)
|
||||
|
||||
This design enables moderately complex logic such as:
|
||||
|
||||
```
|
||||
IF (Host = "example.com")
|
||||
OR (Host = "sub.example.com" AND Path = "/foo/bar")
|
||||
```
|
||||
|
||||
The expressions in parentheses are matcher sets. Even more advanced logic can be expressed through the Starlark expression matcher.
|
||||
|
||||
If a request matches a route, the route's middleware are applied to the request. Unlike Caddy 1, middleware in Caddy 2 are chained in the order you specify, rather than a hard-coded order. (So be careful!) Then a responder, if defined, is what actually writes the response.
|
||||
|
||||
All matching routes cascade on top of each other to create a "composite route" that is customized for each request. Crucially, if multiple responders match a request, only the first responder is used; the rest are ignored. This way it is impossible to corrupt the response with multiple writes solely by configuration (a common bug in Caddy 1).
|
||||
|
||||
A good rule of thumb for building routes: keep middleware that deal with the request near the beginning, and middleware that deal with the response near the end. Generally, this will help ensure you put things in the right order (e.g. the encode middleware must wrap the response writer, but you wouldn't want to execute templates on a compressed bitstream, so you'd put the templates middleware later in the chain).
|
||||
|
||||
If a route returns an error, the error along with its recommended status code are bubbled back to the HTTP server which executes a separate error route, if specified. The error routes work exactly like the normal routes, making error handling very powerful and expressive.
|
||||
|
||||
There is more to routing such as grouping routes for exclusivity (i.e. radio buttons instead of checkboxes); making routes terminal so they don't match any more later in the list; and rehandling, which is like an internal redirect that restarts handling the (likely modified) request. You can also omit matchers in a route to have it match all requests. Phew! Lots to know.
|
||||
|
||||
```json
|
||||
{
|
||||
"http_port": 80,
|
||||
"https_port": 443,
|
||||
"grace_period": "10s",
|
||||
"servers": {
|
||||
"my_server": {
|
||||
"listen": [":8080"],
|
||||
"routes": [
|
||||
{
|
||||
"match": [{
|
||||
"host": ["example.com"],
|
||||
"path": ["/foo/bar", "*.ext"],
|
||||
"path_regexp": {
|
||||
"name": "myre",
|
||||
"pattern": "/foo/(.*)/bar"
|
||||
},
|
||||
"method": ["GET"],
|
||||
"query": {"param": ["value"]},
|
||||
"header": {"Field": ["foo"]},
|
||||
"header_regexp": {
|
||||
"Field": {
|
||||
"pattern": "foo(.*)-bar",
|
||||
"name": "other"
|
||||
},
|
||||
},
|
||||
"protocol": "grpc",
|
||||
"not": {
|
||||
"path": ["/foo/bar"],
|
||||
"...": "(any matchers in here will be negated)"
|
||||
},
|
||||
"remote_ip": {
|
||||
"ranges": ["127.0.0.1", "192.168.0.1/24"]
|
||||
},
|
||||
"starlark_expr": "req.host == 'foo.com' || (req.host != 'example.com' && req.host != 'sub.example.com')"
|
||||
}],
|
||||
"apply": [
|
||||
{
|
||||
"middleware": "rewrite",
|
||||
"method": "FOO",
|
||||
"uri": "/test/abc"
|
||||
},
|
||||
{
|
||||
"middleware": "headers",
|
||||
"response": {
|
||||
"set": {
|
||||
"Foo": ["bar"],
|
||||
"Regexp": ["{http.matchers.path_regexp.myre.0}"]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"respond": {
|
||||
"responder": "static",
|
||||
"body": "Booyah: {http.request.method} {http.request.uri} Foo: {http.response.header.foo}"
|
||||
},
|
||||
"group": "exclusive",
|
||||
"terminal": true
|
||||
}
|
||||
],
|
||||
"errors": {
|
||||
"routes": [ ... ]
|
||||
},
|
||||
"tls_connection_policies": [
|
||||
{
|
||||
"match": {
|
||||
"host": ["example.com"]
|
||||
},
|
||||
"alpn": ["..."],
|
||||
"cipher_suites": ["..."],
|
||||
"certificate_selection": {
|
||||
"policy": "enterprise",
|
||||
"subject.organization": "O1",
|
||||
"tag": "company1"
|
||||
}
|
||||
}
|
||||
],
|
||||
"automatic_https": {
|
||||
"disabled": false,
|
||||
"disable_redirects": false,
|
||||
"skip": ["exclude", "these", "domains"],
|
||||
"skip_certificates": ["doesn't provision certs for these domains but still does redirects"]
|
||||
},
|
||||
"max_rehandles": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
# FIN
|
||||
@ -261,51 +386,7 @@ What follows is the original ad-hoc documentation that we sent some early tester
|
||||
HTTP App
|
||||
=========
|
||||
|
||||
Routes are not your traditional notion of routes (i.e. "GET /foo/bar" -> someFunc).
|
||||
Routes in Caddy 2 are much more powerful. They are given in an ordered list, and each
|
||||
route has three parts: match, apply, respond. All parts are optional. Match is the "if"
|
||||
statement of each route. Each route takes a list of matcher sets. A matcher set
|
||||
comprises matchers of various types. A matcher may comprise multiple values.
|
||||
The boolean logic of request matching goes like this:
|
||||
|
||||
- Matcher sets are OR'ed (first matching matcher set is sufficient)
|
||||
- Matchers within a site are AND'ed (all matchers in the set must match)
|
||||
- Values within a specific matcher are OR'ed (but this could vary depending on
|
||||
the matcher; some don't allow multiple values)
|
||||
|
||||
This design enables moderately complex logic such as:
|
||||
|
||||
IF (Host = "example.com") OR (Host = "sub.example.com" AND Path = "/foo/bar")
|
||||
|
||||
The expressions in parentheses are matcher sets. Even more advanced logic can be
|
||||
expressed through the Starlark expression matcher.
|
||||
|
||||
If a request matches a route, the route's middleware are applied to the request.
|
||||
Unlike Caddy 1, middleware in Caddy 2 are chained in the order you specify, rather than
|
||||
a hard-coded order. (So be careful!) Then a responder, if defined, is what actually
|
||||
writes the response.
|
||||
|
||||
All matching routes cascade on top of each other to create a "composite route" that is
|
||||
customized for each request. Crucially, if multiple responders match a request, only the
|
||||
first responder is used; the rest are ignored. This way it is impossible to corrupt the
|
||||
response with multiple writes solely by configuration (a common bug in Caddy 1).
|
||||
|
||||
A good rule of thumb for building routes: keep middleware that deal with the request
|
||||
near the beginning, and middleware that deal with the response near the end. Generally,
|
||||
this will help ensure you put things in the right order (e.g. the encode middleware
|
||||
must wrap the response writer, but you wouldn't want to execute templates on a
|
||||
compressed bitstream, so you'd put the templates middleware later in the chain).
|
||||
|
||||
If a route returns an error, the error along with its recommended status code are
|
||||
bubbled back to the HTTP server which executes a separate error route, if specified.
|
||||
The error routes work exactly like the normal routes, making error handling very
|
||||
powerful and expressive.
|
||||
|
||||
There is more to routing such as grouping routes for exclusivity (i.e. radio buttons
|
||||
instead of checkboxes); making routes terminal so they don't match any more later in
|
||||
the list; and rehandling, which is like an internal redirect that restarts handling
|
||||
the (likely modified) request. You can also omit matchers in a route to have it match
|
||||
all requests. Phew! Lots to know.
|
||||
...
|
||||
|
||||
Now then. The contents of caddy.json are up to you. Here's a contrived example to
|
||||
demonstrate the fields you can use:
|
||||
|
Loading…
x
Reference in New Issue
Block a user