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