| author | |
| committer | |
| log | 839f6e614995faa9c948343f23bb23831af3117c |
| tree | 93623916fecc52b8c26002b646dc499f54e72532 |
| parent | 6818a04ce885276880fac95a779f3a5a6c849727 |
| signature |
5 files changed, 162 insertions(+), 143 deletions(-)
compose.yaml+57-51| ... | ... | @@ -17,6 +17,12 @@ services: |
| 17 | 17 | watch: |
| 18 | 18 | - path: ./config/Caddyfile |
| 19 | 19 | action: restart |
| 20 | healthcheck: | |
| 21 | test: ["CMD", "caddy", "healthcheck", "--address", ":2019"] | |
| 22 | interval: 10s | |
| 23 | timeout: 5s | |
| 24 | retries: 3 | |
| 25 | start_period: 5s | |
| 20 | 26 | # SSO |
| 21 | 27 | keycloak: # port 80, 443 |
| 22 | 28 | container_name: keycloak |
| ... | ... | @@ -255,6 +261,7 @@ services: |
| 255 | 261 | ND_SCANNER_GROUPALBUMRELEASES: "1" |
| 256 | 262 | ND_BASEURL: "https://music.${HOME_DOMAIN}/" |
| 257 | 263 | ND_PID_ALBUM: "folder" |
| 264 | ND_EXTAUTH_USERHEADER: "Remote-User" | |
| 258 | 265 | ND_EXTAUTH_TRUSTEDSOURCES: "0.0.0.0/0" # troll |
| 259 | 266 | ND_PORT: "80" |
| 260 | 267 | labels: |
| ... | ... | @@ -306,55 +313,55 @@ services: |
| 306 | 313 | net.paperclover.list.domain: qbt |
| 307 | 314 | net.paperclover.list.priority: 52 |
| 308 | 315 | net.paperclover.list.access: media-manage |
| 309 | # jackett: # port 9117 | |
| 310 | # container_name: jackett | |
| 311 | # environment: | |
| 312 | # - "PUID=$USER_ID" | |
| 313 | # - "PGID=$GROUP_ID" | |
| 314 | # - "TZ=America/Los_Angelas" | |
| 315 | # image: lscr.io/linuxserver/jackett:latest | |
| 316 | # restart: unless-stopped | |
| 317 | # volumes: | |
| 318 | # - "${APP_ROOT}/jackett:/config/Jackett" | |
| 319 | # labels: | |
| 320 | # net.paperclover.list.name: Jackett API Adapter | |
| 321 | # net.paperclover.list.domain: jkt | |
| 322 | # net.paperclover.list.priority: 40 | |
| 323 | # net.paperclover.list.access: media-manage | |
| 324 | # sonarr: # port 8989 | |
| 325 | # container_name: sonarr | |
| 326 | # environment: | |
| 327 | # - "PUID=$USER_ID" | |
| 328 | # - "PGID=$GROUP_ID" | |
| 329 | # - "TZ=America/Los_Angelas" | |
| 330 | # image: lscr.io/linuxserver/sonarr:latest | |
| 331 | # volumes: | |
| 332 | # - "${APP_ROOT}/sonarr:/config" | |
| 333 | # - "${TORRENT_TEMP:-${APP_ROOT}/qbittorrent/tmp}:/data/tmp" | |
| 334 | # - "${MEDIA_ROOT}:/data/media" | |
| 335 | # restart: unless-stopped | |
| 336 | # labels: | |
| 337 | # net.paperclover.list.name: Sonarr TV PVR | |
| 338 | # net.paperclover.list.domain: jkt | |
| 339 | # net.paperclover.list.priority: 51 | |
| 340 | # net.paperclover.list.access: media-manage | |
| 341 | # radarr: # port 7878 | |
| 342 | # container_name: radarr | |
| 343 | # environment: | |
| 344 | # - "PUID=$USER_ID" | |
| 345 | # - "PGID=$GROUP_ID" | |
| 346 | # - "TZ=America/Los_Angelas" | |
| 347 | # image: lscr.io/linuxserver/radarr:latest | |
| 348 | # volumes: | |
| 349 | # - "${APP_ROOT}/radarr:/config" | |
| 350 | # - "${TORRENT_TEMP:-${APP_ROOT}/qbittorrent/tmp}:/data/tmp" | |
| 351 | # - "${MEDIA_ROOT}:/data/media" | |
| 352 | # restart: unless-stopped | |
| 353 | # labels: | |
| 354 | # net.paperclover.list.name: Radarr Movie Organizer | |
| 355 | # net.paperclover.list.domain: jkt | |
| 356 | # net.paperclover.list.priority: 50 | |
| 357 | # net.paperclover.list.access: media-manage | |
| 316 | jackett: # port 9117 | |
| 317 | container_name: jackett | |
| 318 | environment: | |
| 319 | - "PUID=$USER_ID" | |
| 320 | - "PGID=$GROUP_ID" | |
| 321 | - "TZ=America/Los_Angelas" | |
| 322 | image: lscr.io/linuxserver/jackett:latest | |
| 323 | restart: unless-stopped | |
| 324 | volumes: | |
| 325 | - "${APP_ROOT}/jackett:/config/Jackett" | |
| 326 | labels: | |
| 327 | net.paperclover.list.name: Jackett API Adapter | |
| 328 | net.paperclover.list.domain: jkt | |
| 329 | net.paperclover.list.priority: 40 | |
| 330 | net.paperclover.list.access: media-manage | |
| 331 | sonarr: # port 8989 | |
| 332 | container_name: sonarr | |
| 333 | environment: | |
| 334 | - "PUID=$USER_ID" | |
| 335 | - "PGID=$GROUP_ID" | |
| 336 | - "TZ=America/Los_Angelas" | |
| 337 | image: lscr.io/linuxserver/sonarr:latest | |
| 338 | volumes: | |
| 339 | - "${APP_ROOT}/sonarr:/config" | |
| 340 | - "${TORRENT_TEMP:-${APP_ROOT}/qbittorrent/tmp}:/data/tmp" | |
| 341 | - "${MEDIA_ROOT}:/data/media" | |
| 342 | restart: unless-stopped | |
| 343 | labels: | |
| 344 | net.paperclover.list.name: Sonarr TV PVR | |
| 345 | net.paperclover.list.domain: jkt | |
| 346 | net.paperclover.list.priority: 51 | |
| 347 | net.paperclover.list.access: media-manage | |
| 348 | radarr: # port 7878 | |
| 349 | container_name: radarr | |
| 350 | environment: | |
| 351 | - "PUID=$USER_ID" | |
| 352 | - "PGID=$GROUP_ID" | |
| 353 | - "TZ=America/Los_Angelas" | |
| 354 | image: lscr.io/linuxserver/radarr:latest | |
| 355 | volumes: | |
| 356 | - "${APP_ROOT}/radarr:/config" | |
| 357 | - "${TORRENT_TEMP:-${APP_ROOT}/qbittorrent/tmp}:/data/tmp" | |
| 358 | - "${MEDIA_ROOT}:/data/media" | |
| 359 | restart: unless-stopped | |
| 360 | labels: | |
| 361 | net.paperclover.list.name: Radarr Movie Organizer | |
| 362 | net.paperclover.list.domain: rdr | |
| 363 | net.paperclover.list.priority: 50 | |
| 364 | net.paperclover.list.access: media-manage | |
| 358 | 365 | # language models |
| 359 | 366 | opencode: # port 4096 |
| 360 | 367 | container_name: opencode |
| ... | ... | @@ -554,7 +561,7 @@ services: |
| 554 | 561 | net.paperclover.list.name: Open Speed Test |
| 555 | 562 | net.paperclover.list.domain: speedtest |
| 556 | 563 | net.paperclover.list.priority: 10 |
| 557 | technitium-dns: | |
| 564 | technitium-dns: # port 5380 | |
| 558 | 565 | image: technitium/dns-server |
| 559 | 566 | container_name: technitium-dns |
| 560 | 567 | user: "$USER_ID:$GROUP_ID" |
| ... | ... | @@ -563,7 +570,6 @@ services: |
| 563 | 570 | - 53:53/tcp |
| 564 | 571 | - 67:67/udp |
| 565 | 572 | - 68:68/udp |
| 566 | - 5380:5380/tcp # Web console | |
| 567 | 573 | - 8053:8053/tcp # dns over http |
| 568 | 574 | volumes: |
| 569 | 575 | - "${APP_ROOT}/technitium/config:/app/config" |
config/403.html created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | no permission &lt;/3 ... <br> | |
| 2 | <a href="/snow.oauth2/sign_out">retry</a> | |
| 3 | <br> | |
| 4 | <br> | |
| 5 | contact clover for assistance... |
config/Caddyfile+96-89| ... | ... | @@ -1,62 +1,45 @@ |
| 1 | # (auth_require) { | |
| 2 | # 	@not_websocket not header Connection Upgrade | |
| 3 | # 	handle /snow.oauth2/* { | |
| 4 | # 		reverse_proxy "http://forward-auth" { | |
| 5 | # 			header_up X-Real-IP {remote_host} | |
| 6 | # 			header_up X-Forwarded-Uri {uri} | |
| 7 | # 		} | |
| 8 | # 	} | |
| 9 | # | |
| 10 | # 	handle { | |
| 11 | # 		forward_auth @not_websocket "http://forward-auth" { | |
| 12 | # 			uri /snow.oauth2/auth | |
| 13 | # 			header_up X-Real-IP {remote_host} | |
| 14 | # 			copy_headers X-Forwarded-User X-Forwarded-Groups X-Forwarded-Email | |
| 15 | # 			@error status 401 | |
| 16 | # 			handle_response @error { | |
| 17 | # 				redir * /snow.oauth2/sign_in?rd={scheme}://{host}{uri} | |
| 18 | # 			} | |
| 19 | # 		} | |
| 20 | # | |
| 21 | # 		reverse_proxy {args[:]} | |
| 22 | # } | |
| 23 | # } | |
| 24 | (auth-optional) { | |
| 25 | 	handle /snow.oauth2/* { | |
| 1 | { | |
| 2 | admin | |
| 3 | } | |
| 4 | ||
| 5 | (reverse_proxy_auth) { | |
| 6 | handle /snow.oauth2/* { | |
| 26 | 7 | 		reverse_proxy "http://forward-auth" { |
| 27 | 8 | 			header_up X-Real-IP {remote_host} |
| 28 | 9 | 			header_up X-Forwarded-Uri {uri} |
| 29 | 10 | 		} |
| 30 | 11 | 	} |
| 31 | ||
| 32 | @not_websocket not header Connection Upgrade | |
| 33 | reverse_proxy @not_websocket "http://forward-auth" { | |
| 34 | method GET | |
| 35 | rewrite /snow.oauth2/auth | |
| 36 | ||
| 37 | header_up X-Forwarded-Method {method} | |
| 38 | header_up X-Forwarded-Uri {uri} | |
| 39 | ||
| 40 | @good status 2xx | |
| 41 | handle_response @good { | |
| 42 | request_header User-Id {rp.header.X-Auth-Request-User} | |
| 43 | request_header User-Groups {rp.header.X-Auth-Request-Groups} | |
| 44 | request_header User-Email {rp.header.X-Auth-Request-Email} | |
| 45 | request_header User-Name {rp.header.X-Auth-Request-Preferred-Username} | |
| 46 | } | |
| 47 | @bad status 4xx | |
| 48 | handle_response @bad { | |
| 49 | request_header User-Id "" | |
| 50 | request_header User-Groups "" | |
| 51 | request_header User-Email "" | |
| 52 | request_header User-Name "" | |
| 12 | handle { | |
| 13 | reverse_proxy "http://forward-auth" { | |
| 14 | method GET | |
| 15 | header_up X-Forwarded-Method {method} | |
| 16 | header_up X-Forwarded-Uri {uri} | |
| 17 | rewrite /snow.oauth2/auth | |
| 18 | header_up X-Real-IP {remote_host} | |
| 19 | @error status 401 | |
| 20 | handle_response @error { | |
| 21 | redir * /snow.oauth2/sign_in?rd={scheme}://{host}{uri} | |
| 22 | } | |
| 23 | @valid_group header X-Auth-Request-Groups *role:{args[1]}* | |
| 24 | handle_response @valid_group { | |
| 25 | method {method} | |
| 26 | rewrite {uri} | |
| 27 | reverse_proxy {args[0]} { | |
| 28 | header_up Cookie ([^;]*?)\s*_oauth2_proxy_\d=[^;]*(;?.*) "$1$2" | |
| 29 | {block} | |
| 30 | } | |
| 31 | } | |
| 32 | handle_response { | |
| 33 | rewrite /403.html | |
| 34 | file_server { | |
| 35 | status 403 | |
| 36 | root /etc/caddy | |
| 37 | } | |
| 38 | } | |
| 53 | 39 | } |
| 54 | 40 | } |
| 55 | ||
| 56 | reverse_proxy {args[:]} | |
| 57 | 41 | } |
| 58 | 42 | |
| 59 | ||
| 60 | 43 | # services are sorted alphabetically |
| 61 | 44 | auth.{$HOME_DOMAIN} { |
| 62 | 45 | handle / { |
| ... | ... | @@ -70,6 +53,9 @@ dawarich.{$HOME_DOMAIN} { |
| 70 | 53 | db.{$HOME_DOMAIN} { |
| 71 | 54 | 	reverse_proxy "http://clover-source-of-truth" |
| 72 | 55 | } |
| 56 | dns.{$HOME_DOMAIN} { | |
| 57 | 	import reverse_proxy_auth "http://technitium-dns:5380" admin | |
| 58 | } | |
| 73 | 59 | file.{$HOME_DOMAIN} { |
| 74 | 60 | handle "/.static/*" { |
| 75 | 61 | uri strip_prefix /.static |
| ... | ... | @@ -82,7 +68,36 @@ file.{$HOME_DOMAIN} { |
| 82 | 68 | root /etc/caddy/static |
| 83 | 69 | file_server |
| 84 | 70 | } |
| 85 | import auth-optional "http://copyparty" | |
| 71 | 	handle /snow.oauth2/* { | |
| 72 | 		reverse_proxy "http://forward-auth" { | |
| 73 | 			header_up X-Real-IP {remote_host} | |
| 74 | 			header_up X-Forwarded-Uri {uri} | |
| 75 | 		} | |
| 76 | 	} | |
| 77 | @should_auth not path /shr/* | |
| 78 | reverse_proxy @should_auth "http://forward-auth" { | |
| 79 | method GET | |
| 80 | rewrite /snow.oauth2/auth | |
| 81 | ||
| 82 | header_up X-Forwarded-Method {method} | |
| 83 | header_up X-Forwarded-Uri {uri} | |
| 84 | ||
| 85 | @good status 2xx | |
| 86 | handle_response @good { | |
| 87 | request_header User-Id {rp.header.X-Auth-Request-User} | |
| 88 | request_header User-Groups {rp.header.X-Auth-Request-Groups} | |
| 89 | request_header User-Email {rp.header.X-Auth-Request-Email} | |
| 90 | request_header User-Name {rp.header.X-Auth-Request-Preferred-Username} | |
| 91 | } | |
| 92 | @bad status 4xx | |
| 93 | handle_response @bad { | |
| 94 | request_header User-Id "" | |
| 95 | request_header User-Groups "" | |
| 96 | request_header User-Email "" | |
| 97 | request_header User-Name "" | |
| 98 | } | |
| 99 | } | |
| 100 | reverse_proxy "http://copyparty" | |
| 86 | 101 | } |
| 87 | 102 | git.{$HOME_DOMAIN} { |
| 88 | 103 | handle /user/login { |
| ... | ... | @@ -94,12 +109,11 @@ git.{$HOME_DOMAIN} { |
| 94 | 109 | 	} |
| 95 | 110 | } |
| 96 | 111 | import ./jellyfin/Caddyfile |
| 97 | # jkt.{$HOME_DOMAIN} { | |
| 98 | # 	import auth | |
| 99 | # 	reverse_proxy "http://jackett:9117" { | |
| 100 | # 		header_up Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" | |
| 101 | # 	} | |
| 102 | # } | |
| 112 | jkt.{$HOME_DOMAIN} { | |
| 113 | 	import reverse_proxy_auth "http://jackett:9117" media-manage { | |
| 114 | 		header_up Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" | |
| 115 | 	} | |
| 116 | } | |
| 103 | 117 | music.{$HOME_DOMAIN} { |
| 104 | 118 | 	handle_path /app/sw.js { |
| 105 | 119 | header Content-Type "application/javascript" |
| ... | ... | @@ -147,41 +161,34 @@ music.{$HOME_DOMAIN} { |
| 147 | 161 | reverse_proxy "http://navidrome" |
| 148 | 162 | } |
| 149 | 163 | } |
| 150 | # opencode.{$HOME_DOMAIN} { | |
| 151 | # 	import auth | |
| 152 | # 	reverse_proxy "http://opencode" | |
| 153 | # } | |
| 154 | # pg.{$HOME_DOMAIN} { | |
| 155 | # 	import auth | |
| 156 | # 	reverse_proxy "http://pgadmin" | |
| 157 | # } | |
| 158 | # qbt.{$HOME_DOMAIN} { | |
| 159 | # 	import auth | |
| 160 | # 	reverse_proxy "qbittorrent:23938" | |
| 161 | # } | |
| 162 | # redis.{$HOME_DOMAIN} { | |
| 163 | # 	import auth | |
| 164 | # 	reverse_proxy "redis-insight:5540" | |
| 165 | # } | |
| 166 | # rdr.{$HOME_DOMAIN} { | |
| 167 | # 	import auth | |
| 168 | # 	reverse_proxy "radarr:7878" { | |
| 169 | # 		header_up Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" | |
| 170 | # 	} | |
| 171 | # } | |
| 172 | # snr.{$HOME_DOMAIN} { | |
| 173 | # 	import auth | |
| 174 | # 	reverse_proxy "sonarr:8989" { | |
| 175 | # 		header_up Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" | |
| 176 | # 	} | |
| 177 | # } | |
| 164 | opencode.{$HOME_DOMAIN} { | |
| 165 | 	import reverse_proxy_auth "http://opencode" admin | |
| 166 | } | |
| 167 | pg.{$HOME_DOMAIN} { | |
| 168 | 	import reverse_proxy_auth "http://pgadmin" admin | |
| 169 | } | |
| 170 | qbt.{$HOME_DOMAIN} { | |
| 171 | 	import reverse_proxy_auth "http://qbittorrent:23938" media-manage | |
| 172 | } | |
| 173 | redis.{$HOME_DOMAIN} { | |
| 174 | 	import reverse_proxy_auth "http://redis-insight:5540" admin | |
| 175 | } | |
| 176 | rdr.{$HOME_DOMAIN} { | |
| 177 | 	import reverse_proxy_auth "http://radarr:7878" media-manage { | |
| 178 | 		header_up Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" | |
| 179 | 	} | |
| 180 | } | |
| 181 | snr.{$HOME_DOMAIN} { | |
| 182 | 	import reverse_proxy_auth "http://sonarr:8989" media-manage { | |
| 183 | 		header_up Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" | |
| 184 | 	} | |
| 185 | } | |
| 178 | 186 | speedtest.{$HOME_DOMAIN} { |
| 179 | 187 | 	reverse_proxy "openspeedtest:3000" |
| 180 | 188 | } |
| 181 | # sync.{$HOME_DOMAIN} { | |
| 182 | # 	import auth | |
| 183 | # 	reverse_proxy "syncthing:8384" | |
| 184 | # } | |
| 189 | sync.{$HOME_DOMAIN} { | |
| 190 | 	import reverse_proxy_auth "http://syncthing:8384" admin | |
| 191 | } | |
| 185 | 192 | |
| 186 | 193 | # redirections |
| 187 | 194 | paperclover.dev { |
config/jellyfin/Caddyfile+3-2| ... | ... | @@ -49,8 +49,9 @@ jelly.{$HOME_DOMAIN} { |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | 51 | /* theme fixes */ |
| 52 | .playlistSectionButton, .noBackdropTransparency .detailPagePrimaryContainer { | |
| 53 | background: rgb(from var(--main-background) r g b / 50%; | |
| 52 | .material-icons.play_arrow { display: flex } | |
| 53 | .detailPagePrimaryContainer { | |
| 54 | background: rgb(from var(--main-background) r g b / 75%)!; | |
| 54 | 55 | } |
| 55 | 56 | .selectLabel { |
| 56 | 57 | display: flex; |
config/keycloak/init.py+1-1| ... | ... | @@ -19,7 +19,7 @@ def env(key: str): |
| 19 | 19 | return val |
| 20 | 20 | |
| 21 | 21 | |
| 22 | groups_to_create = ["snow", "media", "media-manage", "git", "file"] | |
| 22 | groups_to_create = ["snow", "media-manage"] | |
| 23 | 23 | realm_config = { |
| 24 | 24 | "realm": "master", |
| 25 | 25 | "displayName": "snow sign on", |