Files
vaultwarden-deployment/quadlets/caddy.container.j2
T
2026-05-26 08:28:42 -05:00

49 lines
1.8 KiB
Django/Jinja

[Unit]
Description=Caddy reverse proxy (custom build with googleclouddns + Coraza)
Wants=network-online.target vaultwarden.service
After=network-online.target vaultwarden.service
# Wants= (not Requires=) on vaultwarden.service: a Vaultwarden restart
# returns a brief 502 from reverse_proxy rather than tearing down Caddy
# (which would drop TLS termination at 443). Client cache covers the gap.
OnFailure=status-email-root@%n.service
[Container]
# Custom build pushed by cloudbuild.yaml. :latest is what `podman
# auto-update` watches; bump deliberately by re-tagging a known-good <sha>
# tag as :latest in Artifact Registry. The repo grants
# roles/artifactregistry.reader to allUsers (declared in Pulumi) so the
# host pulls without auth.
#
# The image path is templated from `caddy_image` which Ansible receives via
# --extra-vars at deploy time, sourced from the Pulumi output `imageRepo`.
Image={{ caddy_image }}
ContainerName=caddy
AutoUpdate=registry
Network=vaultwarden.network
# 443 on the host. The sysctl ip_unprivileged_port_start=443 (set by the
# podman role) lets rootless caddy bind without CAP_NET_BIND_SERVICE.
PublishPort=443:443
# Caddyfile bind-mount, plus Caddy's data dir (certs, OCSP staples) and
# log dir (access log + Coraza audit). All :Z under SELinux.
Volume=%h/caddy/Caddyfile:/etc/caddy/Caddyfile:Z,ro
Volume=%h/caddy/data:/data:Z
Volume=%h/caddy/logs:/var/log/caddy:Z
# VAULT_FQDN + WG_SUBNET come from the Ansible-rendered env file.
EnvironmentFile=%h/caddy/caddy.env
# GCP SA JSON for DNS-01. Podman mounts the secret at /run/secrets/gcp-sa-dns
# by default for type=mount.
Environment=GOOGLE_APPLICATION_CREDENTIALS=/run/secrets/gcp-sa-dns
Secret=gcp-sa-dns,type=mount
[Service]
Restart=always
RestartSec=10s
TimeoutStartSec=300
[Install]
WantedBy=default.target