1. The problem I’m having:
Hi there!
I’m using Caddy mainly as a reverse proxy for my services running in containers.
I’m splitting my logging for each subdomain to have finer grained fail2ban filtering available.
Works great so far, but Silverbullet is sending A LOT of requests (Log grows to several MB in a couple of minutes), even while idling - logrotate is fine and all, but i also want to limit ssd-wear.
My wish is to filter out Status 200 out of the logs, but so far i haven’t had any luck with any method or hint i found.
My current attempt looks like this:
# general Logging
{
log {
output file /var/log/caddy/access.log {
roll_size 10MB
roll_keep 10
}
format json
}
}
# logging for subdomain/service
silverbullet.saldorin.duckdns.org {
reverse_proxy localhost:3000 {
header_up X-Real-IP {remote_host}
}
@not200 not expression `{err.status_code} != 200`
log_skip @not200
log {
output file /var/log/caddy/silverbullet.access.log
}
}
Unfortunately, this still logs status 200 requests…
Hopefully, someone can point me in the right direction?
2. Error messages and/or full log output:
No related output in the general log. Example log of Silverbullet-request:
{"level":"info","ts":1750066419.574309,"logger":"http.log.access.log1","msg":"handled request","request":{"remote_ip":"192.168.1.1","remote_port":"54714","client_ip":"192.168.1.1","proto":"HTTP/3.0","method":"GET","host":"silverbullet.saldorin.duckdns.org","uri":"/service_worker.js","headers":{"Service-Worker":["script"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Dnt":["1"],"Sec-Fetch-Site":["same-origin"],"Cache-Control":["max-age=0"],"Sec-Fetch-Mode":["same-origin"],"Priority":["u=4"],"Accept":["*/*"],"Alt-Used":["silverbullet.saldorin.duckdns.org"],"Sec-Fetch-Dest":["serviceworker"],"Accept-Language":["en-US,en;q=0.5"],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64; rv:139.0) Gecko/20100101 Firefox/139.0"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h3","server_name":"silverbullet.saldorin.duckdns.org"}},"bytes_read":0,"user_id":"","duration":0.003773312,"size":18175,"status":200,"resp_headers":{"Via":["1.1 Caddy"],"Cache-Control":["no-cache"],"Vary":["Accept-Encoding"],"Content-Type":["application/javascript"],"Content-Encoding":["br"],"Content-Length":["18175"],"Date":["Mon, 16 Jun 2025 09:33:39 GMT"]}}
3. Caddy version:
v2.10.0 h1:fonubSaQKF1YANl8TXqGcn4IbIRUDdfAkpcsfI/vX5U=
4. How I installed and ran Caddy:
a. System environment:
Debian 12 x86 VM running atop Proxmox, managed by systemd, as described in Install — Caddy Documentation
b. Command:
systemctl start caddy.service
c. Service/unit/compose file:
# caddy.service
#
# For using Caddy with a config file.
#
# Make sure the ExecStart and ExecReload commands are correct
# for your installation.
#
# See https://caddyserver.com/docs/install for instructions.
#
# WARNING: This service does not use the --resume flag, so if you
# use the API to make changes, they will be overwritten by the
# Caddyfile next time the service is restarted. If you intend to
# use Caddy's API to configure it, add the --resume flag to the
# `caddy run` command or use the caddy-api.service file instead.
[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
d. My complete Caddy config:
# The Caddyfile is an easy way to configure your Caddy web server.
#
# Unless the file starts with a global options block, the first
# uncommented line is always the address of your site.
#
# To use your own domain name (with automatic HTTPS), first make
# sure your domain's A/AAAA DNS records are properly pointed to
# this machine's public IP, then replace ":80" below with your
# domain name.
# Create log that is parceable for fail2ban
{
log {
output file /var/log/caddy/access.log {
roll_size 10MB
roll_keep 10
}
format json
}
}
# Setup DNS API
*.saldorin.duckdns.org {
tls {
dns duckdns {
token xxx
}
}
}
# Setup base dir
:80, :443 {
respond /health "Im healthy" 200
log
}
# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile
silverbullet.saldorin.duckdns.org{
reverse_proxy localhost:3000 {
header_up X-Real-IP {remote_host}
}
@not200 not expression `{err.status_code} != 200`
log_skip @not200
log {
output file /var/log/caddy/silverbullet.access.log
}
}
[other services...]
5. Links to relevant resources:
Some posts/suggestions that i tried to implement/used for further research:
https://caddy.community/t/exclude-certain-requests-from-logs-based-on-request-path/15607
https://caddy.community/t/how-to-disable-logs-with-a-matcher/16882
(max 4 links allowed )
Relevant issue (i think?):