## Cheatsheet When you add a new container, you just need to do this: ```yaml networks: caddy_net: external: true services: snapdrop: image: linuxserver/snapdrop:latest container_name: snapdrop networks: - caddy_net restart: always #👇 Magic happening below labels: caddy: drop.example.com #👈 Subdomain using wildcard cert caddy.reverse_proxy: "{{upstreams 80}}" #👈 Container port caddy.import: auth #👈 One-line enable Authelia ``` Now with [`auto_https prefer_wildcard option`](https://github.com/caddyserver/caddy/pull/6146) merged, we get a even better config structure if wanting to use wildcard SSL certs for HTTPS. ## Caddy Dockerfile To use wildcard certs, need to build a custom Docker image of Caddy with Cloudflare module (if that is you DNS nameserver) to handle DNS challenge. Put this Dockerfile in the same directory as the Docker Compose file below. ```Dockerfile ARG CADDY_VERSION=2 FROM caddy:${CADDY_VERSION}-builder AS builder # no need the "v2.9.0-beta.2" part after new version release RUN xcaddy build v2.9.0-beta.2 \ --with github.com/lucaslorentz/caddy-docker-proxy/v2 \ --with github.com/caddy-dns/cloudflare FROM caddy:${CADDY_VERSION}-alpine COPY --from=builder /usr/bin/caddy /usr/bin/caddy CMD ["caddy", "docker-proxy"] ``` ## Caddy Docker Compose Besure to modify to your info where indicated. Some examples are provided at the end. ### .env file ```ini EMAIL=your_email@example.com #👈 Your email for SSL cert CF_API_TOKEN=your_cloudflare_api_token #👈 Get your token from Cloudflare AUTH_HOST_INTERNAL=authelia:9091 #👈 Authelia container name and port AUTH_HOST_EXTERNAL=auth.example.com #👈 Public facing domain of Authelia ``` ### Caddy Main Container ```yaml # docker-compose.yaml networks: caddy_net: #â„šī¸ Caddy ingress network name: caddy_net ipam: driver: default services: caddy: container_name: caddy build: . restart: always environment: CADDY_INGRESS_NETWORKS: caddy_net volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./caddy/data:/data/caddy #👈 where to save SSL certs - ./caddy/config:/config/caddy #👈 where to save configs networks: - caddy_net ports: - 80:80 - 443:443 extra_hosts: - host.docker.internal:host-gateway # to be continued below... ``` ### Caddy Labels Before using, we need to configure Caddy itself first. This can be done purely with compose labels. We group labels with `_numbers` as yaml keys must be unique. You can read more about [Labels to Caddyfile conversion here](https://github.com/lucaslorentz/caddy-docker-proxy?tab=readme-ov-file#labels-to-caddyfile-conversion). While we CAN put these labels directly under the main container above, it is better to use a **separate**, lightweight container. As commented by @coandco, if we change any labels under the main container, Caddy has to be restarted and thus interrupt existing connections. Personally, I use the `traefik/whoami` image, which can double as a troubleshooting tool. ```yaml # docker-compose.yaml continued caddy-config: container_name: caddy-config image: traefik/whoami:latest networks: - caddy_net restart: always labels: ############################################# # Settings and snippets to get things working # You shouldn't need to modify this normally # Custom settings and definitions are below ############################################# #### Global Settings #### caddy_0.email: "{env.EMAIL}" caddy_0.auto_https: prefer_wildcard #### Snippets #### # Get wildcard certificate caddy_1: (wildcard) caddy_1.tls.dns: "cloudflare {env.CF_API_TOKEN}" caddy_1.tls.resolvers: 1.1.1.1 1.0.0.1 caddy_1.handle.abort: "" # Secure a site with Authelia caddy_2: (auth) caddy_2.forward_auth: "{$$AUTH_HOST_INTERNAL}" caddy_2.forward_auth.uri: /api/authz/forward-auth caddy_2.forward_auth.copy_headers : Remote-User Remote-Groups Remote-Name Remote-Email # Skip TLS verify for backend with self-signed HTTPS caddy_3: (https) caddy_3.transport: http caddy_3.transport.tls: "" caddy_3.transport.tls_insecure_skip_verify: "" ########################################### # Custom settings. Modify things below 👇: # Make sure they have unique label numbers ########################################### # Custom global settings, add/edit as needed # caddy_0.log: default # caddy_0.log.format: console # Uncomment this during testing to avoid hitting rate limit. # It will try to obtain SSL from Let's Encrypt's staging endpoint. # acme_ca: "https://acme-staging-v02.api.letsencrypt.org/directory" # 👈 Staging ## Setup wildcard sites caddy_10: "*.example.com" #👈 Change to your domain caddy_10.import: wildcard # Add our first site, which this container itself caddy_99: whoami.example.com #👈 Subdomain using wildcard cert caddy_99.reverse_proxy: "{{upstreams 80}}" #👈 Container port caddy_99.import: auth #👈 Enable protection by Authelia # to be continued below... ``` If we have some non-docker sites that need to be reverse proxied, we can also add their configs here: ```yaml # docker-compose.yaml continued # e.g.: Pi-Hole on another machine in the same LAN caddy_100: pihole.example.com #👈 Subdomain using wildcard cert caddy_100.reverse_proxy: 192.168.1.4:88 #👈 LAN IP and port caddy_100.import: auth #👈 Enable protection by Authelia # e.g. OpenMediaVault on the host machine, with self-signed https at port 4430 caddy_101: omv.example.com #👈 Subdomain using wildcard cert caddy_101.reverse_proxy: host.docker.internal:4430 #👈 Port on host machine caddy_101.reverse_proxy.import: https #👈 Allow self-signed cert between OMV and Caddy caddy_101.import: auth #👈 Enable protection by Authelia ``` ## Authelia Docker Compose Make sure Authelia is in the same network with Caddy. Add two labels under your existing Authelia compose: ```yaml networks: caddy_net: external: true # ... other networks used by authelia ... services: authelia: container_name: authelia hostname: authelia image: authelia/authelia:latest networks: - caddy_net - #... other networks ... expose: - 9091 # ... the rest of your regular ... # ... authelia compose here ... # ... # Add this: labels: caddy: auth.example.com #👈 Public facing subdomain of Authelia caddy.reverse_proxy: "{{upstreams 9091}}" #👈 Authelia container port ``` ## Add new sites from other containers Three labels! Just the subdomain, port and if you want Authelia. ```yaml networks: caddy_net: external: true snapdrop: image: linuxserver/snapdrop:latest container_name: snapdrop networks: - caddy_net restart: always labels: caddy: drop.example.com #👈 Subdomain caddy.reverse_proxy: "{{upstreams 80}}" #👈 Container port caddy.import: auth #👈 Authelia ``` ## Some extra tricks ### Caddy Admin Endpoint and Metrics (Homepage) The docker version of Caddy needs its admin endpoint internally for reload, and does not allow you to modify or expose it outside the container. If you need it, such as for the [Caddy widget](https://gethomepage.dev/widgets/services/caddy/) of [Homepage](https://gethomepage.dev/) dashboard, you can expose this portion with the following labels for Caddy: ```yaml # docker-compose.yaml # under caddy-config container caddy_20: :2020 caddy_20.handle: /reverse_proxy/upstreams caddy_20.handle.reverse_proxy: localhost:2019 caddy_20.handle.reverse_proxy.header_up: Host localhost:2019 ``` And for your Homepage widget: (make sure they are on the same network) ```yaml # services.yaml ... widget: type: caddy url: http://caddy:2020 ``` More to come... Please leave a ⭐ if this helps you!