Skip to content

settings.proxy

The Caddy reverse proxy.

As with DNS, there is no route list: every web_services entry anywhere in the tree that carries a proxy_name becomes a route. A service is published by declaring it on the node that runs it, next to that node's IP.

labops owns the Caddyfile and nothing else. The Caddy image, the caddy-dns plugin it must be built with, and the environment holding your ACME token are managed outside labops — see the Caddy proxy guide.

Proxy

The Caddy reverse proxy, rendered from the config.

There is no route list here: every web_services entry in the tree that carries a proxy_name becomes a route, so a service is published next to the node that runs it. labops owns the Caddyfile only — the image, the caddy-dns plugin and the environment holding the ACME token are yours.

Key Type Default Description
proxy_suffix string required The domain every route hangs off: a service named nas becomes nas<proxy_suffix>. Caddy serves it as one wildcard site.
tls ProxyTls unset Wildcard TLS for the suffix. Omit to serve plain HTTP — appropriate for an internal suffix with no certificate.
deploy ProxyDeploy unset Where Caddy runs. Omit for render-only use; proxy sync, deploy and reload need it.
template path to a file unset Render the Caddyfile from your own Jinja template instead of the built-in one. Relative to the config file, or absolute; the file must exist, so a typo fails at labops validate rather than part-way through a deploy. A template can replace the built-in one outright, or extend it and override only the blocks it cares about.
trusted_proxies list of CIDR unset CIDRs of reverse proxies (e.g. a CDN) directly in front of Caddy. When set, access-list matchers use Caddy's client_ip (which reads X-Forwarded-For) instead of remote_ip (the connecting socket). List only the proxy in front of Caddy — never 0.0.0.0/0. Trusting an address that is not a proxy under your control lets anyone at that address forge their apparent IP and bypass every access list.
default_access string required The access list used by services with no explicit access. Must name a key of access_lists: a service that names no list still has to resolve to one, so there is no unrestricted fallback.
access_lists map of name → AccessList required Named CIDR sets that web services reference by name. default_access picks the one used by a service with no explicit access.

ProxyTls

Wildcard TLS for the proxy suffix, via the provider's ACME DNS-01 challenge.

Omit the whole tls: block to serve the wildcard over plain HTTP — sensible for an internal suffix with no certificate.

Key Type Default Description
provider none | cloudflare "cloudflare" One provider at a time; none is the off switch. The name fixes both the credential env var and the caddy-dns plugin the Caddy image must be built with — labops renders the Caddyfile, not the image, so it cannot check that the plugin is present.
token string unset The API token, inline and rendered literally into the Caddyfile — discouraged. By default labops renders a reference like {env.CF_API_TOKEN} that Caddy resolves from its own environment at runtime, so the secret never lands in the config or the rendered file. labops reads the same key from the secret store only to warn when it is missing.

ProxyDeploy

Where Caddy runs, so the rendered Caddyfile can be delivered and reloaded.

Omit the whole block for render-only use: proxy render still works, and sync / deploy / reload say what is missing instead of guessing a target.

Key Type Default Description
target string required The node running Caddy — a host, VM or LXC in this config, by name or IP. Hosts and VMs are reached over SSH; an LXC is reached through its Proxmox parent with pct, so it needs no sshd.
caddyfile_dest string required Absolute path the Caddyfile is written to on the target. In docker mode this is the host path that is bind-mounted into the container. Must be absolute: it is resolved on the target, where a relative path would land in the remote login directory.
docker DockerDeploy unset Present for docker mode, absent for host mode (a bare caddy on the target). The presence of this block is the mode switch.
reload_command string unset Replaces the whole reload command, run verbatim over SSH. Overrides the mode default; when set, docker.container is not required.

DockerDeploy

Docker-mode settings. Its mere presence on a ProxyDeploy selects docker mode; omit the whole block for a host-mode (bare caddy) target.

Key Type Default Description
container string unset The container to docker exec into for the reload. Required in docker mode unless reload_command replaces the reload outright.
container_caddyfile_path string "/etc/caddy/Caddyfile" Where the Caddyfile is mounted inside the container — the mount target that caddyfile_dest on the host maps to.

AccessList

A named set of CIDRs, referenced by a web service's access.

Lists are named rather than written inline so that "who may reach this" is declared once and reused — change the VPN range in one place and every service that names it follows.

Key Type Default Description
accept list of CIDR required CIDRs allowed to reach services using this list. At least one is required. An IPv4-only list denies IPv6 clients, so a list meant to be public needs ::/0 alongside 0.0.0.0/0.
deny list of CIDR unset CIDRs blocked even when accept would allow them — deny wins. Use it to carve a single host out of an allowed subnet.