# Caddy server recipes These recipes are for the [Caddy](https://caddyserver.com/) web server version 2. ## Contents ## Multiple sites in separate files (Caddyfile.d) {#caddyfile.d} Create a Caddyfile consisting of the following single line: ```caddy import Caddyfile.d/*.conf ``` Create the directory `Caddyfile.d/` next to the Caddyfile. Put your site configurations in Caddyfiles with the extension `.conf` in `Caddyfile.d/`. Note that with this setup, one broken Caddyfile will prevent your server from starting. ## Overriding an error status code {#error-status-override} Use the [`respond`](https://caddyserver.com/docs/caddyfile/directives/respond) or [`file_server`](https://caddyserver.com/docs/caddyfile/directives/file_server) directive in the error handler. ```caddy handle_errors { file_server { status 200 } rewrite * /templates/index.html } ``` ## Redirecting a query parameter to a path {#redir-query-parameter} This will only work with a single query parameter. The example is something useful for the [Fossil SCM](https://fossil-scm.org/) wiki. It prevents search engines and users from accessing your pages as both `/wiki?name=foo` and `/wiki/foo`. (The latter seems more search engine-friendly.) ```caddy @wiki_query { path_regexp ^/wiki(?:/*|)$ query name=* } route @wiki_query { uri replace name= / redir * /wiki{query} } ``` ## Reverse proxy for... {#reverse-proxy} ### Everything except some static files {#everything-not-static} ```caddy root * /opt/foo/static @not_static { not { path /BingSiteAuth.xml /robots.txt path /favicon.ico } } reverse_proxy @not_static localhost:8100 file_server ``` ### FastCGI (generic, non-PHP) {#fastcgi} ```caddy @foo path /foo /foo/* reverse_proxy @foo { to localhost:9000 transport fastcgi } ``` ### SCGI {#scgi} You can use the unofficial third-party [scgi-transport](https://github.com/Elegant996/scgi-transport) module. ```caddy @foo path /foo /foo/* reverse_proxy @foo { to localhost:9999 transport scgi } ``` ### WeeChat {#weechat} See the Glowing Bear wiki page ["Proxying WeeChat relay with a web server"](https://github.com/glowing-bear/glowing-bear/wiki/Proxying-WeeChat-relay-with-a-web-server). ```caddy weechat.example.com { reverse_proxy /weechat localhost:9001 } ``` ## Running CGI scripts {#cgi} Caddy can run CGI scripts either with a plugin or with a FastCGI-to-CGI proxy. See my [caddy-cgi](https://github.com/dbohdan/caddy-cgi) repository. ## Serving Markdown files as pages {#markdown} You can serve Markdown files as adequately good-looking minimal web pages. See my [caddy-markdown-site](https://github.com/dbohdan/caddy-markdown-site) repository. ## Showing an error page on errors {#error-page} This will give your server a human-readable, if not the most user-friendly, error page. It will tell the user an error has occurred and give them something to report to you. The page will contain a custom error message for the most common errors: 403, 404, and 500. Otherwise, the error message will be the description text of the HTTP status code. ### Caddyfile {#error-page-caddyfile} ```caddy handle_errors { rewrite * /error.html file_server templates } ``` ### error.html {#error-page-error.html} ```html {{- $code := placeholder "http.error.status_code" -}} {{- $text := placeholder "http.error.status_text" }}
You don't have permission to access this resource.
{{- else if eq $code "404" -}}The requested URL was not found on this server.
{{- else if eq $code "500" -}}An internal server error has occurred.
{{- else -}}{{ $text }}.
{{- end}}Copyright (c) {{ $years }} J. Random Hacker
Permission is hereby granted, free of charge, to any person obtaining a copy
[...]
~~~
### license.txt {#licenses-license.txt}
This is the downloadable plain-text license file.
The fallback year is based on server time, as above.
```plaintext
Copyright (c) {{ or (placeholder "http.regexp.license.years" | replace "," ", ") (now | date "2006") }} J. Random Hacker
Permission is hereby granted, free of charge, to any person obtaining a copy
[...]
```
## Content-Type on FreeBSD {#content-type-freebsd}
When working on [dynamic license pages](#licenses), I found that Caddy on FreeBSD evaluated HTML but not plain-text files as templates.
This contradicted Caddy documentation that said it evaluated both.
I traced the problem to the files not having a `Content-Type: text/plain` header or any [`Content-Type` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Type) like they had on Linux.
This solution is an alternative to setting the `Content-Type` header manually.
You need to create `/usr/local/etc/mime.types` on your system.
You can download the latest version of the file from Apache's GitHub mirror:
```shell
# As root:
fetch -o /usr/local/etc/mime.types https://raw.githubusercontent.com/apache/httpd/master/docs/conf/mime.types
```
Alternatively, ports like Apache 2.4 and Python provide the file.
Copy or symlink one of the following files to `/usr/local/etc/mime.types` if you have them installed:
- `/usr/local/etc/apache24/mime.types`
- `/usr/local/lib/python3.11/test/mime.types` (older version than in Apache; lacks `image/avif` in Python 3.11)
## Page metadata
URL: