-
-
Save Fastidious/72568416f368f2ec2ed6c74c19a96d9f to your computer and use it in GitHub Desktop.
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
# GLOBAL SETTINGS | |
{ | |
#debug logs | |
#debug | |
dynamic_dns { | |
provider cloudflare {env.CLOUDFLARE_API_TOKEN} | |
domains { | |
example.com | |
example2.com | |
} | |
check_interval 10m | |
versions ipv4 | |
} | |
#### caddy-security #### | |
order authenticate before respond | |
order authorize before basicauth | |
security { | |
oauth identity provider pocket-id { | |
realm pocket-id | |
driver generic | |
client_id <removed | |
client_secret <removed> | |
scopes openid email profile groups | |
enable id_token_cookie pocket-id_token | |
base_auth_url http://pocket-id:80 | |
metadata_url http://pocket-id:80/.well-known/openid-configuration | |
delay_start 3 | |
} | |
authentication portal pocket-id { | |
crypto default token lifetime 86400 | |
enable identity provider pocket-id | |
transform user { | |
match realm pocket-id | |
action add caddy_username all-users as string | |
} | |
transform user { | |
match email [email protected] | |
action add caddy_username testing as string | |
} | |
} | |
authorization policy private_access { | |
bypass uri prefix /api | |
set auth url /caddy-security/oauth2/pocket-id | |
allow roles private | |
inject headers with claims | |
inject header "X-Token-Username" from caddy_username | |
} | |
authorization policy public_access { | |
set auth url /caddy-security/oauth2/pocket-id | |
allow roles user | |
inject headers with claims | |
inject header "X-Token-Username" from caddy_username | |
} | |
} | |
} | |
# SNIPPETS | |
## Use this private_access to skip auth on local network ## | |
# (private_access) { | |
# @notLocal not remote_ip private_ranges | |
# @auth path /caddy-security/* | |
# handle @notLocal { | |
# route @auth { | |
# authenticate with pocket-id | |
# } | |
# route { | |
# authorize with private_access | |
# } | |
# } | |
# } | |
(authentik) { | |
reverse_proxy /outpost.goauthentik.io/* authentik-server:9000 { | |
header_up Host {http.reverse_proxy.upstream.hostport} | |
} | |
forward_auth authentik-server:9000 { | |
uri /outpost.goauthentik.io/auth/caddy | |
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt X-Authentik-Meta-Jwks X-Authentik-Meta-Outpost X-Authentik-Meta-Provider X-Authentik-Meta-App X-Authentik-Meta-Version | |
} | |
} | |
(oauth2) { | |
handle /oauth2/* { | |
reverse_proxy oauth2-proxy:4180 { | |
header_up X-Real-IP {remote_host} | |
header_up X-Forwarded-Uri {uri} | |
} | |
} | |
handle { | |
forward_auth oauth2-proxy:4180 { | |
uri /oauth2/auth | |
header_up X-Real-IP {remote_host} | |
copy_headers Authorization X-Auth-Request-User X-Auth-Request-Email X-Auth-Request-Preferred-Username X-Auth-Request-Groups | |
@error status 401 | |
handle_response @error { | |
redir * /oauth2/sign_in?rd={scheme}://{host}{uri} | |
} | |
} | |
} | |
} | |
(private_access) { | |
@auth { | |
path /caddy-security/* | |
} | |
route @auth { | |
authenticate with pocket-id | |
} | |
route /* { | |
authorize with private_access | |
} | |
} | |
(public_access) { | |
@auth { | |
path /caddy-security/* | |
} | |
route @auth { | |
authenticate with pocket-id | |
} | |
route /* { | |
authorize with public_access | |
} | |
} | |
(localNetwork) { | |
@localNetwork remote_ip private_ranges | |
@notLocal not remote_ip private_ranges | |
handle @notLocal { | |
respond "This service is not accessible remotely" 403 | |
} | |
} | |
### Blog ## | |
example.com, www.example.com { | |
encode gzip | |
tls { | |
dns cloudflare {env.CLOUDFLARE_API_TOKEN} | |
resolvers 1.1.1.1 8.8.8.8 | |
} | |
reverse_proxy http://192.168.20.2:2368 | |
} | |
# WILDCARD Cert for all sites | |
*.{env.DOMAIN} { | |
encode gzip | |
tls { | |
dns cloudflare {env.CLOUDFLARE_API_TOKEN} | |
resolvers 1.1.1.1 8.8.8.8 | |
} | |
# actual | |
@actual host actual.{env.DOMAIN} | |
handle @actual { | |
import localNetwork | |
reverse_proxy @localNetwork actual_server:5006 | |
} | |
# audiobookshelf | |
@audiobooks host audiobooks.{env.DOMAIN} | |
handle @audiobooks { | |
reverse_proxy http://192.168.1.21:8585 | |
} | |
# authentik | |
@authentik host auth.{env.DOMAIN} | |
handle @authentik { | |
reverse_proxy http://authentik-server:9000 | |
} | |
# bitwarden | |
@bitwarden host bitwarden.{env.DOMAIN} | |
handle @bitwarden { | |
#import private_access | |
#extra security header modifications | |
header { | |
X-XSS-Protection "1; mode=block" | |
X-Frame-Options "DENY" | |
X-Robots-Tag "none" | |
-Server | |
} | |
reverse_proxy bitwarden:80 | |
} | |
# blinko | |
@blinko host blinko.{env.DOMAIN} | |
handle @blinko { | |
import private_access | |
reverse_proxy blinko-website:1111 | |
} | |
# calibre | |
@calibre host calibre.{env.DOMAIN} | |
handle @calibre { | |
import public_access | |
reverse_proxy http://192.168.1.21:8083 | |
} | |
# calibre downloader | |
@books host books.{env.DOMAIN} | |
handle @books { | |
import public_access | |
reverse_proxy http://192.168.1.21:8084 | |
} | |
# # cards | |
@cards host cards.{env.DOMAIN} | |
handle @cards { | |
basic_auth { | |
admin $2a$12$removed | |
} | |
reverse_proxy http://192.168.20.2:8080 | |
} | |
# dockge | |
@dockge host dockge.{env.DOMAIN} | |
handle @dockge { | |
import private_access | |
reverse_proxy dockge:5001 | |
} | |
# dozzle | |
@dozzle host dozzle.{env.DOMAIN} | |
handle @dozzle { | |
import localNetwork | |
reverse_proxy @localNetwork dozzle:8080 | |
} | |
# frigate | |
@frigate host frigate.{env.DOMAIN} | |
handle @frigate { | |
import private_access | |
#reverse_proxy http://192.168.1.60:8971 | |
reverse_proxy http://192.168.10.10:8971 | |
} | |
# homeassistant | |
@hass host hass.{env.DOMAIN} | |
handle @hass { | |
# import private_access | |
reverse_proxy http://192.168.10.10:8123 | |
} | |
# homepage | |
@home host home.{env.DOMAIN} | |
handle @home { | |
import localNetwork | |
reverse_proxy @localNetwork homepage:3000 | |
} | |
# immich | |
@immich host immich.{env.DOMAIN} | |
handle @immich { | |
import private_access | |
reverse_proxy immich-server:2283 | |
} | |
# jellyfin | |
@jellyfin host jellyfin.{env.DOMAIN} | |
handle @jellyfin { | |
import private_access | |
reverse_proxy 192.168.1.21:8096 | |
} | |
# mealie | |
@mealie host mealie.{env.DOMAIN} | |
handle @mealie { | |
reverse_proxy mealie:9000 | |
} | |
# NAS | |
@nas host nas.{env.DOMAIN} | |
handle @nas { | |
import private_access | |
reverse_proxy http://192.168.1.9:5000 | |
} | |
# obsidian | |
@obsidian host obsidian.{env.DOMAIN} | |
handle @obsidian { | |
import private_access | |
reverse_proxy http://obsidian:3000 | |
} | |
# obsidian sync | |
@sync host sync.{env.DOMAIN} | |
handle @sync { | |
reverse_proxy http://obsidian-livesync:5984 | |
} | |
# outline | |
@notes host notes.{env.DOMAIN} | |
handle @notes { | |
reverse_proxy http://outline:3000 | |
} | |
# ollama | |
@chat host chat.{env.DOMAIN} | |
handle @chat { | |
import private_access | |
reverse_proxy http://open-webui:8080 | |
} | |
# overseerr | |
@overseerr host overseerr.{env.DOMAIN} | |
handle @overseerr { | |
reverse_proxy http://192.168.1.21:5055 | |
} | |
#paperless | |
@paperless host paperless.{env.DOMAIN} | |
handle @paperless { | |
#import private_access | |
reverse_proxy http://paperless:8000 | |
} | |
# #paperlessai | |
# @paperlessai host paperlessai.{env.DOMAIN} | |
# handle @paperlessai { | |
# import private_access | |
# reverse_proxy http://paperless-ai:3000 | |
#paperlessgpt | |
@paperlessgpt host paperlessgpt.{env.DOMAIN} | |
handle @paperlessgpt { | |
import private_access | |
reverse_proxy http://paperless-gpt:8080 | |
} | |
# pingvin | |
@pingvin host pingvin.{env.DOMAIN} | |
handle @pingvin { | |
import private_access | |
reverse_proxy http://pingvin:3000 | |
} | |
# plex | |
@plex host plex.{env.DOMAIN} | |
handle @plex { | |
reverse_proxy http://192.168.1.21:32400 | |
} | |
# pocket-id | |
@pocket-id host pocket-id.{env.DOMAIN} | |
handle @pocket-id { | |
reverse_proxy pocket-id:80 | |
} | |
# prowlarr | |
@prowlarr host prowlarr.{env.DOMAIN} | |
handle @prowlarr { | |
import private_access | |
reverse_proxy http://192.168.1.21:9696 | |
} | |
# proxmox | |
@proxmox host proxmox.{env.DOMAIN} | |
handle @proxmox { | |
import localNetwork | |
reverse_proxy @localNetwork https://192.168.0.50:8006 { | |
transport http { | |
tls_insecure_skip_verify | |
} | |
} | |
} | |
# proxmox backup server | |
@pbs host pbs.{env.DOMAIN} | |
handle @pbs { | |
import localNetwork | |
reverse_proxy @localNetwork https://192.168.0.52:8007 { | |
transport http { | |
tls_insecure_skip_verify | |
} | |
} | |
} | |
# radarr | |
@radarr host radarr.{env.DOMAIN} | |
handle @radarr { | |
import private_access | |
reverse_proxy http://192.168.1.21:7878 | |
} | |
# readarr | |
@readarr host readarr.{env.DOMAIN} | |
handle @readarr { | |
import private_access | |
reverse_proxy http://192.168.1.21:8787 | |
} | |
# remote access | |
@remote host remote.{env.DOMAIN} | |
handle @remote { | |
#rewrite * /guacamole{uri} | |
import private_access | |
reverse_proxy http://guacamole:8080 { | |
header_up X-Token-Username username | |
} | |
} | |
# sabnzbd | |
@sabnzbd host sabnzbd.{env.DOMAIN} | |
handle @sabnzbd { | |
import localNetwork | |
reverse_proxy @localNetwork http://192.168.1.21:8085 | |
} | |
# scrypted | |
@scrypted host scrypted.{env.DOMAIN} | |
handle @scrypted { | |
import localNetwork | |
reverse_proxy @localNetwork https://192.168.0.51:10443 { | |
transport http { | |
tls_insecure_skip_verify | |
} | |
} | |
} | |
# sonarr | |
@sonarr host sonarr.{env.DOMAIN} | |
handle @sonarr { | |
import private_access | |
reverse_proxy http://192.168.1.21:8989 { | |
} | |
} | |
# # speaches | |
# @speaches host speaches.{env.DOMAIN} | |
# handle @speaches { | |
# import private_access | |
# reverse_proxy http://192.168.1.60:8000 { | |
# } | |
# } | |
# stirling-pdf | |
@pdf host pdf.{env.DOMAIN} | |
handle @pdf { | |
import private_access | |
reverse_proxy stirling-pdf:8080 | |
} | |
# switchwire | |
@switchwire host switchwire.{env.DOMAIN} | |
handle @switchwire { | |
import private_access | |
reverse_proxy http://192.168.10.111:80 | |
} | |
# tautulli (has plex login) | |
@tautulli host tautulli.{env.DOMAIN} | |
handle @tautulli { | |
reverse_proxy http://192.168.1.21:8181 | |
} | |
# transmission | |
@transmission host transmission.{env.DOMAIN} | |
handle @transmission { | |
import private_access | |
reverse_proxy http://192.168.1.21:9091 | |
} | |
# unifi | |
@unifi host unifi.{env.DOMAIN} | |
handle @unifi { | |
import private_access | |
reverse_proxy https://192.168.1.1 { | |
transport http { | |
tls_insecure_skip_verify | |
} | |
header_up X-Real-IP {remote_host} | |
} | |
} | |
# vacuum | |
@vacuum host vacuum.{env.DOMAIN} | |
handle @vacuum { | |
import private_access | |
reverse_proxy http://192.168.10.15:80 | |
} | |
# voron | |
@voron host voron.{env.DOMAIN} | |
handle @voron { | |
import private_access | |
reverse_proxy http://192.168.10.110:80 | |
} | |
# vscode | |
@vscode host vscode.{env.DOMAIN} | |
handle @vscode { | |
import private_access | |
reverse_proxy http://192.168.0.100:8443 | |
} | |
# For whoami protected with oauth2-proxy | |
@whoami host whoami.{env.DOMAIN} | |
handle @whoami { | |
import oauth2 | |
reverse_proxy whoami:80 | |
} | |
# whats up docker | |
@wud host wud.{env.DOMAIN} | |
handle @wud { | |
import localNetwork | |
reverse_proxy @localNetwork whatsupdocker:3000 | |
} | |
# Handle unlisted subdomains | |
handle { | |
respond "This service is not available" 404 | |
#abort | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment