Last active
April 25, 2025 14:45
-
-
Save DanielVolz/fb2da03618748679132aa70cee6f1a5c to your computer and use it in GitHub Desktop.
Dockerfile, Caddyfile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ARG CADDY_VERSION=2.9.1 | |
FROM caddy:${CADDY_VERSION}-builder-alpine AS builder | |
RUN xcaddy build \ | |
--with github.com/lucaslorentz/caddy-docker-proxy/[email protected] \ | |
--with github.com/caddy-dns/porkbun \ | |
--with github.com/greenpau/[email protected] | |
FROM caddy:${CADDY_VERSION}-alpine | |
COPY --from=builder /usr/bin/caddy /usr/bin/caddy | |
CMD ["caddy", "docker-proxy"] | |
---------------------------------------------------------------------- | |
{ | |
email [email protected] | |
acme_dns porkbun { | |
api_key {$PORKBUN_API_KEY} | |
api_secret_key {$PORKBUN_API_PASSWORD} | |
} | |
# admin 2019 | |
# OAuth security configuration | |
security { | |
oauth identity provider generic_oauth { | |
realm generic | |
driver generic | |
delay_start 10 | |
client_id | |
client_secret | |
scopes openid email profile | |
base_auth_url http://auth.{$MY_DOMAIN} | |
metadata_url http://auth.{$MY_DOMAIN}/.well-known/openid-configuration | |
} | |
authentication portal myportal { | |
enable identity provider generic_oauth | |
crypto default token lifetime 7200 | |
cookie domain {$MY_DOMAIN} | |
ui { | |
links { | |
"Home" "/" | |
} | |
} | |
transform user { | |
match realm generic | |
action add role authp/user | |
} | |
} | |
authorization policy mypolicy { | |
set auth url /auth | |
allow roles authp/user | |
validate source address | |
inject headers with claims | |
} | |
} | |
} | |
(tls_internal) { | |
tls /certs/_wildcard.rbpi.lan+4.pem /certs/_wildcard.rbpi.lan+4-key.pem | |
} | |
# Base settings for all sites | |
(base_settings) { | |
encode gzip { | |
minimum_length 512 | |
} | |
log { | |
output file /var/log/caddy/access.log { | |
roll_size 10MB | |
roll_keep 10 | |
} | |
format console | |
level INFO | |
} | |
handle_errors { | |
respond "{http.error.status_code} {http.error.status_text}" | |
} | |
} | |
# Common security headers | |
(common_headers) { | |
import base_settings | |
header { | |
-Server | |
X-Content-Type-Options "nosniff" | |
Referrer-Policy "no-referrer-when-downgrade" | |
Strict-Transport-Security "max-age=31536000; includeSubDomains" | |
X-Xss-Protection "1; mode=block" | |
} | |
} | |
(strict_headers) { | |
import common_headers | |
header { | |
# Additional strict security headers | |
X-Frame-Options "SAMEORIGIN" | |
X-Robots-Tag "noindex, nofollow" | |
Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()" | |
Content-Security-Policy "upgrade-insecure-requests; default-src 'self'; script-src 'self' 'unsafe-inline'" | |
X-Permitted-Cross-Domain-Policies "none" | |
Cache-Control "no-store, no-cache, must-revalidate" | |
} | |
} | |
(nextcloud_headers) { | |
import base_settings | |
header { | |
# Remove Server header | |
-Server | |
# Basic security headers | |
X-Content-Type-Options "nosniff" | |
Referrer-Policy "no-referrer" | |
X-XSS-Protection "1; mode=block" | |
X-Robots-Tag "noindex, nofollow" | |
X-Download-Options "noopen" | |
X-Permitted-Cross-Domain-Policies "none" | |
# HSTS | |
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" | |
# Nextcloud requires a more permissive Content-Security-Policy | |
Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-ancestors 'self'; img-src * data: blob:; media-src *; connect-src *" | |
# More appropriate cache control for Nextcloud | |
Cache-Control "public, max-age=15778463" | |
# Permissions that Nextcloud might need | |
Permissions-Policy "interest-cohort=()" | |
} | |
} | |
# Define a reusable snippet with common auth logic | |
(auth_common) { | |
@oauth { | |
path /auth/oauth2/generic | |
path /auth/oauth2/generic/authorization-code-callback | |
} | |
route @oauth { | |
authenticate with myportal | |
} | |
route /* { | |
authorize with mypolicy | |
} | |
} | |
(site_tls) { | |
tls { | |
issuer acme { | |
dns porkbun { | |
api_key {$PORKBUN_API_KEY} | |
api_secret_key {$PORKBUN_API_PASSWORD} | |
} | |
} | |
} | |
} | |
auth.domain.org { | |
reverse_proxy /api/* http://pocketid:8080 { | |
trusted_proxies 0.0.0.0/0 | |
trusted_proxies ::/0 | |
} | |
reverse_proxy /.well-known/* http://pocketid:8080 { | |
trusted_proxies 0.0.0.0/0 | |
trusted_proxies ::/0 | |
} | |
reverse_proxy /* http://pocketid:3000 { | |
trusted_proxies 0.0.0.0/0 | |
trusted_proxies ::/0 | |
} | |
} | |
local.{$MY_DOMAIN} *.local.{$MY_DOMAIN} { | |
import site_tls | |
} | |
wg.domain.org { | |
reverse_proxy rbpi:51821 | |
} | |
---------------------------------------- | |
compose.yml for example container: | |
labels: | |
caddy_0: ${CADDY_DOMAIN_DOZZLE_LOCAL} | |
caddy_0.import: common_headers | |
caddy_0.reverse_proxy: dozzle-rbpi:8080 | |
This generates with ucaslorentz/caddy-docker-proxy/[email protected] in Caddyfile the following: | |
rbpi-log.local.domain.org { | |
import common_headers | |
reverse_proxy dozzle-rbpi:8080 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment