diff --git a/cheatsheet.md b/cheatsheet.md new file mode 100644 index 0000000..f580d66 --- /dev/null +++ b/cheatsheet.md @@ -0,0 +1,238 @@ +## 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! \ No newline at end of file