Add cheatsheet.md
Some checks failed
Build and publish / Git Tag (push) Successful in 12s
Build and publish / Build Container (push) Failing after 35s

This commit is contained in:
2025-10-17 18:13:39 -04:00
parent 574c2e4b32
commit dbb6a33afc

238
cheatsheet.md Normal file
View File

@@ -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!