version: "3.7"
services:
caddy:
build:
context: .
dockerfile: Dockerfile
restart: unless-stopped
cap_add:
- NET_ADMIN
ports:
- "6443:443"
- "6443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:Z
- ./site:/srv:Z
- ./data:/data:Z
- ./config:/config:Z
This will add the Cloudflare DNS module into the Caddy build. This module will allow Caddy to create the DNS records which lets Let's Encrypt issue the certificate.
FROM caddy:2-builder-alpine AS builder
RUN caddy-builder github.com/caddy-dns/cloudflare
FROM caddy:2
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
In your ./Caddyfile
https://site.mydomain.com {
tls {
dns cloudflare <DNS cloudflare token>
}
reverse_proxy internal_server.lan:3000
}
Make sure the internal server port is the same as the service you're wanting to expose to the internet.
If you want to use Basic Auth and have Bitwarden transparently log in, in the Caddyfile put the same username and password as will be used for the user login on the site:
https://securesite.mydomain.com {
basic_auth {
username password_hash
}
reverse_proxy internal_server.lan:3020
}
Then in Bitwarden, as long as one single password matches that site, it will transparently fill in the HTTP Basic Auth before taking you straight to the destination service's login screen.
This is a basic way to generate a certificate for a user. If it's only you using your own homelab, then you'll just need to make one certificate.
This certificate will last for ~10 years (although of course you can revoke it at any time by deleting it from Caddy's key store).
#!/bin/bash
mkdir -p certs
# Generate CA certificates
openssl genrsa -out certs/client-ca.key 4096
openssl req -new -x509 -nodes -days 3600 -key certs/client-ca.key -out certs/client-ca.crt
# Generate a certificate signing request
openssl req -newkey rsa:4096 -nodes -keyout certs/client.key -out certs/client.req
# Have the CA sign the certificate requests and output the certificates.
openssl x509 -req -in certs/client.req -days 3600 -CA certs/client-ca.crt -CAkey certs/client-ca.key -set_serial 01 -out certs/client.crt
echo
echo "Please enter a STRONG password. Many clients *require* a password for you to be able to import the certificate, and you want to protect it."
echo
# Convert the cerificate to PKCS12 format (for import into browser)
openssl pkcs12 -export -out certs/client.pfx -inkey certs/client.key -in certs/client.crt
# Clean up
rm certs/client.req
https://securesite.mydomain.com {
tls {
client_auth {
mode require_and_verify
trusted_ca_cert_file /data/client_certs/client.crt
}
}
reverse_proxy internal_server.lan:3020
}