2026-02-27 15:09:25 -07:00
|
|
|
{
|
|
|
|
|
email {{ admin_user }}@{{ domain }}
|
|
|
|
|
log {
|
|
|
|
|
output stdout
|
|
|
|
|
}
|
|
|
|
|
metrics {
|
|
|
|
|
per_host
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(access_log) {
|
|
|
|
|
log
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
:{{ caddy_metrics_port }} {
|
|
|
|
|
metrics
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{% for site in caddy_sites %}
|
|
|
|
|
# Redirect www → apex
|
|
|
|
|
www.{{ site }} {
|
|
|
|
|
import access_log
|
|
|
|
|
redir https://{{ site }}{uri} permanent
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{{ site }} {
|
|
|
|
|
import access_log
|
|
|
|
|
root * /srv/sites/{{ site }}
|
|
|
|
|
encode zstd gzip
|
|
|
|
|
file_server
|
|
|
|
|
|
|
|
|
|
header {
|
|
|
|
|
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
|
|
|
|
X-Content-Type-Options "nosniff"
|
|
|
|
|
X-Frame-Options "DENY"
|
|
|
|
|
Referrer-Policy "strict-origin-when-cross-origin"
|
|
|
|
|
}
|
|
|
|
|
{% if site == domain and enable_tuwunel | default(false) %}
|
|
|
|
|
|
|
|
|
|
handle /.well-known/matrix/server {
|
|
|
|
|
header Content-Type application/json
|
|
|
|
|
respond `{"m.server": "{{ tuwunel_domain }}:443"}`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handle /.well-known/matrix/client {
|
|
|
|
|
header Content-Type application/json
|
|
|
|
|
header Access-Control-Allow-Origin *
|
|
|
|
|
respond `{"m.homeserver": {"base_url": "https://{{ tuwunel_domain }}"}}`
|
|
|
|
|
}
|
|
|
|
|
{% endif %}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{% endfor %}
|
|
|
|
|
{% if enable_mail | default(false) %}
|
2026-02-28 00:51:16 -07:00
|
|
|
http://{{ mail_hostname }} {
|
|
|
|
|
root * /var/www/acme
|
|
|
|
|
file_server
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-27 15:09:25 -07:00
|
|
|
{{ webmail_domain }} {
|
|
|
|
|
import access_log
|
|
|
|
|
reverse_proxy rainloop:{{ rainloop_port }}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{{ rspamd_domain }} {
|
|
|
|
|
import access_log
|
|
|
|
|
reverse_proxy mailserver:{{ rspamd_port }}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% if enable_forgejo | default(false) %}
|
|
|
|
|
{{ forgejo_domain }} {
|
|
|
|
|
import access_log
|
|
|
|
|
reverse_proxy forgejo:{{ forgejo_port }}
|
|
|
|
|
|
|
|
|
|
header {
|
|
|
|
|
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
|
|
|
|
X-Content-Type-Options "nosniff"
|
|
|
|
|
X-Frame-Options "SAMEORIGIN"
|
|
|
|
|
Referrer-Policy "strict-origin-when-cross-origin"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% if enable_monitoring | default(false) %}
|
|
|
|
|
{{ grafana_domain }} {
|
|
|
|
|
import access_log
|
|
|
|
|
reverse_proxy grafana:{{ grafana_port }} {
|
|
|
|
|
header_up Host {host}
|
|
|
|
|
header_up X-Real-IP {remote_host}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% if enable_tuwunel | default(false) %}
|
|
|
|
|
{{ tuwunel_domain }} {
|
|
|
|
|
import access_log
|
|
|
|
|
reverse_proxy tuwunel:{{ tuwunel_port }}
|
|
|
|
|
|
|
|
|
|
header {
|
|
|
|
|
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
|
|
|
|
X-Content-Type-Options "nosniff"
|
|
|
|
|
X-Frame-Options "DENY"
|
|
|
|
|
Referrer-Policy "strict-origin-when-cross-origin"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% if enable_radicale | default(false) %}
|
|
|
|
|
{{ radicale_domain }} {
|
|
|
|
|
import access_log
|
|
|
|
|
|
|
|
|
|
redir /.well-known/caldav / permanent
|
|
|
|
|
redir /.well-known/carddav / permanent
|
|
|
|
|
|
|
|
|
|
reverse_proxy radicale:{{ radicale_port }}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% if enable_goaccess | default(false) %}
|
|
|
|
|
{{ goaccess_domain }} {
|
|
|
|
|
import access_log
|
|
|
|
|
root * /srv/goaccess/reports
|
|
|
|
|
file_server browse
|
|
|
|
|
basic_auth {
|
|
|
|
|
{$GOACCESS_USER} {$GOACCESS_HASH}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
{% endif %}
|