- Seed postfix-accounts.cf before mailserver start to satisfy Dovecot's requirement for at least one account on first boot - Add failed_when: false to mail user/alias list tasks (files don't exist on first run) - Add forgejo_runner_version (was undefined); default to 12 - Create /srv/forgejo/data/gitea/conf before deploying app.ini - Decouple goaccess sync from restic: new enable_goaccess_sync flag with its own goaccess_sync_* variables - Move Docker installation to bootstrap exclusively; rename docker.yml to networks.yml (runs docker_network role only) - Add radicale_password to vault template and setup.sh - Fix goaccess sync tasks gated on enable_goaccess_sync - Add upstream bug comment to authorized_key deprecation warning - Update CLAUDE.md and README.md throughout Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
129 lines
2.6 KiB
Django/Jinja
129 lines
2.6 KiB
Django/Jinja
{
|
|
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) %}
|
|
http://{{ mail_hostname }} {
|
|
root * /var/www/acme
|
|
file_server
|
|
}
|
|
|
|
{{ 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 %}
|