I’ve been using the Caddy webserver for all my projects lately. Here’s my current default config for a Laravel project.
First, I want to separate all my configs in different config files, to keep things tidy. My Caddyfile is simply an import of all my vhosts.
$ cat /etc/caddy/Caddyfile
import /etc/caddy/conf.d/*.conf
As a result, all configs live in /etc/caddy/conf.d/.
Here’s an example for my own company, robotstudios.be . (which is a Laravel app just to receive Stripe payments via credit card. Damn international wire transfers suck.)
$ cat /etc/caddy/conf.d/robotstudios.be.conf
www.robotstudios.be {
redir https://robotstudios.be{uri} permanent
}
# The actual vhost, on a single domain
robotstudios.be {
root * /var/www/html/robotstudios.be/public
encode gzip
# This blocks access to dot files and folders such as .htaccess,
# .git, etc., while still allowing the .well-known directory through.
@hidden {
path */.*
not path /.well-known/*
}
respond @hidden 404
# Point all PHP requests to the upstream PHP-FPM socket. php_fastcgi
# also handles the front-controller rewrite to index.php for you, so
# the explicit "rewrite to /index.php" rules from Caddy v1 are gone.
php_fastcgi unix//run/php/robotstudios.be-fpm.sock
# Serve static files (CSS, JS, images) that aren't handled by PHP
file_server
header {
Strict-Transport-Security "max-age=30758400"
X-Content-Type-Options "nosniff"
X-Frame-Options "deny"
Referrer-Policy "same-origin"
}
# Access logging in the combined format, rolled and kept for 14 days
log {
output file /var/www/html/robotstudios.be/logs/access.log {
roll_size 50mb
roll_keep 14
roll_keep_for 336h
}
format transform `{request>remote_ip} - {user_id} [{ts}] "{request>method} {request>uri} {request>proto}" {status} {size} "{request>headers>Referer>[0]}" "{request>headers>User-Agent>[0]}"` {
time_format "02/Jan/2006:15:04:05 -0700"
}
}
}
This config serves a couple of purposes:
- Redirect all versions of the domain to
robotstudios.be, without the www-prefix - Enable gzip compression
- Store logs in the home dir of the site, rotate them and keep 14 versions
- Point all PHP requests to an upstream socket, served by php-fpm
- Redirect all URLs to the index.php (for pretty-printed URLs)
- Prevent access to files like
.htaccess,.git, … (like robotstudios.be/.htaccess ) - Set a sane set of default security headers, like HSTS (force HTTPS)
The logs use the transform encoder to produce the familiar Apache-style combined log line, so I get the referer header & user agents too. That encoder ships as the caddy-transform-encoder
plugin, so it needs to be built into your Caddy binary (caddy add-package github.com/caddyserver/transform-encoder or via xcaddy).
It’s readable and pretty short, I like that.