Compare commits
60 Commits
photos-cut
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 900e46c667 | |||
|
|
6e6bfe3aa0 | ||
|
|
28543e1662 | ||
|
|
3d52e9d1c1 | ||
|
|
fa1dff62c6 | ||
|
|
2faea41d3e | ||
|
|
3cebb8fd11 | ||
|
|
4635001feb | ||
|
|
1ea60a9aca | ||
|
|
e7bf4f9d93 | ||
|
|
2c418d395d | ||
|
|
86e727255b | ||
|
|
2b8bddc488 | ||
| 4238adb81c | |||
| f266f0605f | |||
| 48549d0072 | |||
|
|
d17ee47ce5 | ||
| 25b81b2dce | |||
|
|
a3d9368a54 | ||
|
|
89ff86e36e | ||
| e026ba867a | |||
| 8e48911e1f | |||
| fc50aa3bda | |||
| 5401d77bab | |||
| ed20908d34 | |||
| c195142827 | |||
| 205cbf00f3 | |||
| c937c03da3 | |||
|
|
9dcac60a08 | ||
|
|
dfe4e7bf80 | ||
|
|
468c2e7d93 | ||
|
|
9b99dbb641 | ||
|
|
0b703fa192 | ||
|
|
751feefe4c | ||
|
|
8c92428b42 | ||
|
|
ae854e563d | ||
|
|
acc5af8477 | ||
|
|
e01a39175f | ||
|
|
3824faf11c | ||
|
|
06d9452741 | ||
|
|
e0973bfeeb | ||
|
|
85e9a92059 | ||
|
|
d2d9ef8da0 | ||
|
|
6786f07c76 | ||
|
|
0f472e9088 | ||
|
|
f9783571a1 | ||
|
|
b3e7385754 | ||
|
|
8d14ef80fa | ||
|
|
d49a844941 | ||
|
|
32575ce73f | ||
| 1b977aabfa | |||
|
|
408a11c856 | ||
|
|
fec102895f | ||
|
|
2962a6e485 | ||
|
|
f520afad60 | ||
| c906a5acc7 | |||
| 6ea8e727d4 | |||
| db7f8fbf4e | |||
| a52cf68d0f | |||
| e535f93dcc |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -1,5 +1,4 @@
|
|||||||
# Environment variables
|
# Backup files
|
||||||
.env
|
Caddyfile.bak*
|
||||||
.env.local
|
caddy.env
|
||||||
.env.*.local
|
*.env
|
||||||
!.env.example
|
|
||||||
|
|||||||
158
Caddyfile
158
Caddyfile
@@ -1,9 +1,20 @@
|
|||||||
|
# Internal forward-auth upstream proxy (no TLS between Caddy handlers)
|
||||||
|
:8099 {
|
||||||
|
@outpost path /outpost.goauthentik.io/*
|
||||||
|
reverse_proxy @outpost https://auth.hubris.network:443 {
|
||||||
|
transport http {
|
||||||
|
tls_server_name auth.hubris.network
|
||||||
|
}
|
||||||
|
header_up Host auth.hubris.network
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Authentik forward-auth snippet (domain-level mode).
|
# Authentik forward-auth snippet (domain-level mode).
|
||||||
# Usage: add "import authentik" inside any site block to gate it.
|
# Usage: add "import authentik" inside any site block to gate it.
|
||||||
(authentik) {
|
(authentik) {
|
||||||
route {
|
route {
|
||||||
reverse_proxy /outpost.goauthentik.io/* http://192.168.8.180:9000
|
reverse_proxy /outpost.goauthentik.io/* https://auth.hubris.network:443
|
||||||
forward_auth http://192.168.8.180:9000 {
|
forward_auth http://127.0.0.1:8099 {
|
||||||
uri /outpost.goauthentik.io/auth/caddy
|
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
|
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
|
||||||
trusted_proxies private_ranges
|
trusted_proxies private_ranges
|
||||||
@@ -24,12 +35,6 @@
|
|||||||
# this machine's public IP, then replace ":80" below with your
|
# this machine's public IP, then replace ":80" below with your
|
||||||
# domain name.
|
# domain name.
|
||||||
|
|
||||||
media.hubris.network {
|
|
||||||
tls {
|
|
||||||
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
|
||||||
}
|
|
||||||
reverse_proxy 192.168.8.206:8096
|
|
||||||
}
|
|
||||||
|
|
||||||
git.hubris.network {
|
git.hubris.network {
|
||||||
tls {
|
tls {
|
||||||
@@ -58,11 +63,12 @@ paperless.hubris.network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
books.hubris.network {
|
|
||||||
|
pascal.hubris.network {
|
||||||
tls {
|
tls {
|
||||||
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
}
|
}
|
||||||
reverse_proxy 192.168.8.205:6060
|
reverse_proxy 192.168.8.100:3001
|
||||||
}
|
}
|
||||||
|
|
||||||
home.hubris.network {
|
home.hubris.network {
|
||||||
@@ -79,12 +85,6 @@ cloud.hubris.network {
|
|||||||
reverse_proxy 192.168.8.224:80
|
reverse_proxy 192.168.8.224:80
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix.hubris.network {
|
|
||||||
tls {
|
|
||||||
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
|
||||||
}
|
|
||||||
reverse_proxy 192.168.8.239:8008
|
|
||||||
}
|
|
||||||
|
|
||||||
proxmox.hubris.network {
|
proxmox.hubris.network {
|
||||||
tls {
|
tls {
|
||||||
@@ -108,33 +108,8 @@ docker.hubris.network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jellyseerr.hubris.network {
|
|
||||||
tls {
|
|
||||||
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
|
||||||
}
|
|
||||||
reverse_proxy 192.168.8.132:5056
|
|
||||||
}
|
|
||||||
|
|
||||||
qbit.hubris.network {
|
|
||||||
tls {
|
|
||||||
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
|
||||||
}
|
|
||||||
@api path /api/*
|
|
||||||
handle @api {
|
|
||||||
reverse_proxy 192.168.8.132:8080
|
|
||||||
}
|
|
||||||
handle {
|
|
||||||
import authentik
|
|
||||||
reverse_proxy 192.168.8.132:8080
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sab.hubris.network {
|
|
||||||
tls {
|
|
||||||
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
|
||||||
}
|
|
||||||
reverse_proxy 192.168.8.132:8081
|
|
||||||
}
|
|
||||||
|
|
||||||
blog.hubris.network {
|
blog.hubris.network {
|
||||||
tls {
|
tls {
|
||||||
@@ -144,30 +119,44 @@ blog.hubris.network {
|
|||||||
}
|
}
|
||||||
|
|
||||||
photos.hubris.network {
|
photos.hubris.network {
|
||||||
# mule-image — PhotoPrism + Go sidecar + SvelteKit (post-Mulimage 2.0)
|
# Mulimage 2.0 — PhotoPrism + Go sidecar + SvelteKit (LXC 120)
|
||||||
tls {
|
tls {
|
||||||
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
}
|
}
|
||||||
encode zstd gzip
|
encode zstd gzip
|
||||||
# PhotoPrism API + OIDC callback first (matched before static catch-all)
|
# PhotoPrism API + static assets + share links
|
||||||
@pp path /api/v1/* /api/v1 /static/* /share/*
|
@pp path /api/v1/* /api/v1 /static/* /share/*
|
||||||
reverse_proxy @pp 192.168.8.136:2342
|
reverse_proxy @pp 192.168.8.136:2342
|
||||||
# PhotoPrism redirects to /library/browse after OIDC. Bounce back to
|
# OIDC hand-off: PhotoPrism redirects to /library/login after SSO;
|
||||||
# the SvelteKit SPA; mule-image is the only user-facing frontend.
|
# bounce back to / so the SvelteKit SPA picks up the session.
|
||||||
redir /library / 302
|
redir /library / 302
|
||||||
redir /library/* / 302
|
redir /library/* / 302
|
||||||
# mule-sidecar (Go) — keeps the /api/sidecar/ prefix
|
# Go sidecar — marks, folder mutations, duplicates, heap convert
|
||||||
@sc path /api/sidecar/*
|
@sc path /api/sidecar/*
|
||||||
reverse_proxy @sc 192.168.8.136:8000
|
reverse_proxy @sc 192.168.8.136:8000
|
||||||
# Catch-all → nginx-on-120 serving the SvelteKit static bundle (no Vite in prod)
|
# SvelteKit frontend (catch-all)
|
||||||
reverse_proxy 192.168.8.136:3000
|
reverse_proxy 192.168.8.136:3000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prism.hubris.network {
|
||||||
|
# PhotoPrism — direct access for Prismatic mobile client (LXC 120)
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
encode zstd gzip
|
||||||
|
reverse_proxy 192.168.8.136:2342
|
||||||
|
}
|
||||||
|
|
||||||
auth.hubris.network {
|
auth.hubris.network {
|
||||||
tls {
|
tls {
|
||||||
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
}
|
}
|
||||||
reverse_proxy 192.168.8.180:9000
|
reverse_proxy https://auth.hubris.network:443 {
|
||||||
|
transport http {
|
||||||
|
tls_server_name auth.hubris.network
|
||||||
|
}
|
||||||
|
header_up Host auth.hubris.network
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
artifacto.hubris.network {
|
artifacto.hubris.network {
|
||||||
@@ -200,23 +189,82 @@ zimaos.hubris.network {
|
|||||||
tls {
|
tls {
|
||||||
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
}
|
}
|
||||||
reverse_proxy 192.168.8.195
|
reverse_proxy 192.168.8.195:80
|
||||||
}
|
}
|
||||||
|
|
||||||
# Homelab MCP server (read-only context + management tools).
|
# Homelab MCP server (read-only context + management tools).
|
||||||
# Mesh+LAN-gated by the service itself + nftables; no SSO so agent clients work.
|
# Mesh+LAN-gated by the service itself + nftables; no SSO so agent clients work.
|
||||||
mcp.hubris.network {
|
sso.hubris.network {
|
||||||
tls {
|
tls {
|
||||||
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
}
|
}
|
||||||
reverse_proxy 192.168.8.205:9810
|
reverse_proxy https://auth.hubris.network:443 {
|
||||||
|
transport http {
|
||||||
|
tls_server_name auth.hubris.network
|
||||||
|
}
|
||||||
|
header_up Host auth.hubris.network
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Per-client age-key issuance (mesh-only via source-IP gating in the service).
|
|
||||||
# No SSO — agents call this during bootstrap; identity is mesh peer + hostname.
|
# Matrix Synapse federation + client API.
|
||||||
secrets.hubris.network {
|
# No authentik gate — Synapse handles its own auth.
|
||||||
|
|
||||||
|
|
||||||
|
trmnl.hubris.network {
|
||||||
tls {
|
tls {
|
||||||
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
}
|
}
|
||||||
reverse_proxy 192.168.8.205:9820
|
reverse_proxy 192.168.8.211:9851
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
teddy.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy https://192.168.8.150:8443 {
|
||||||
|
transport http {
|
||||||
|
tls_insecure_skip_verify
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ─── Oikos (Go rewrite, Docker on mac-mini) ───
|
||||||
|
# Phase 6 cutover — replaces apps/105 Python MCP + console.
|
||||||
|
# /api/v1/clients/enroll bypasses Authentik (IP-gated in the API handler).
|
||||||
|
# The SPA is its own container (:8091, compose/web/Dockerfile in the oikos
|
||||||
|
# repo) — not served by api itself, which no longer embeds it.
|
||||||
|
oikos.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
@enroll path /api/v1/clients/enroll /oidc-callback
|
||||||
|
handle @enroll {
|
||||||
|
reverse_proxy 192.168.178.182:8090
|
||||||
|
}
|
||||||
|
@api path /api/v1/* /mcp /agent/*
|
||||||
|
handle @api {
|
||||||
|
reverse_proxy 192.168.178.182:8090
|
||||||
|
}
|
||||||
|
handle {
|
||||||
|
import authentik
|
||||||
|
reverse_proxy 192.168.178.182:8091
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mcp.hubris.network {
|
||||||
|
reverse_proxy 192.168.178.182:8090
|
||||||
|
}
|
||||||
|
|
||||||
|
hermes.hubris.network {
|
||||||
|
reverse_proxy 192.168.178.182:8092
|
||||||
|
}
|
||||||
|
|
||||||
|
tube.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.178.44:8082
|
||||||
}
|
}
|
||||||
|
|||||||
1
caddy.env.example
Normal file
1
caddy.env.example
Normal file
@@ -0,0 +1 @@
|
|||||||
|
IONOS_AUTH_API_TOKEN=your_token_here
|
||||||
234
hosts/hubris/Caddyfile
Normal file
234
hosts/hubris/Caddyfile
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
import /etc/caddy/shared/*
|
||||||
|
|
||||||
|
git.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
handle_path /_plantuml/* {
|
||||||
|
rewrite * /plantuml{uri}
|
||||||
|
reverse_proxy 192.168.8.205:8079
|
||||||
|
}
|
||||||
|
handle {
|
||||||
|
reverse_proxy 192.168.8.121:3000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
paperless.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
@api path /api/*
|
||||||
|
handle @api {
|
||||||
|
reverse_proxy 192.168.8.130:8000
|
||||||
|
}
|
||||||
|
handle {
|
||||||
|
import authentik
|
||||||
|
reverse_proxy 192.168.8.130:8000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pascal.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.8.100:3001
|
||||||
|
}
|
||||||
|
|
||||||
|
home.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.8.101:8123
|
||||||
|
}
|
||||||
|
|
||||||
|
cloud.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.8.224:80
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proxmox.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy https://192.168.8.77:8006 {
|
||||||
|
transport http {
|
||||||
|
tls_insecure_skip_verify
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
docker.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy https://192.168.8.205:9443 {
|
||||||
|
transport http {
|
||||||
|
tls_insecure_skip_verify
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
blog.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.8.205:8080
|
||||||
|
}
|
||||||
|
|
||||||
|
photos.hubris.network {
|
||||||
|
# Mulimage 2.0 — PhotoPrism + Go sidecar + SvelteKit (LXC 120)
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
encode zstd gzip
|
||||||
|
# PhotoPrism API + static assets + share links
|
||||||
|
@pp path /api/v1/* /api/v1 /static/* /share/*
|
||||||
|
reverse_proxy @pp 192.168.8.136:2342
|
||||||
|
# OIDC hand-off: PhotoPrism redirects to /library/login after SSO;
|
||||||
|
# bounce back to / so the SvelteKit SPA picks up the session.
|
||||||
|
redir /library / 302
|
||||||
|
redir /library/* / 302
|
||||||
|
# Go sidecar — marks, folder mutations, duplicates, heap convert
|
||||||
|
@sc path /api/sidecar/*
|
||||||
|
reverse_proxy @sc 192.168.8.136:8000
|
||||||
|
# SvelteKit frontend (catch-all)
|
||||||
|
reverse_proxy 192.168.8.136:3000
|
||||||
|
}
|
||||||
|
|
||||||
|
prism.hubris.network {
|
||||||
|
# PhotoPrism — direct access for Prismatic mobile client (LXC 120)
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
encode zstd gzip
|
||||||
|
reverse_proxy 192.168.8.136:2342
|
||||||
|
}
|
||||||
|
|
||||||
|
auth.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy https://auth.hubris.network:443 {
|
||||||
|
transport http {
|
||||||
|
tls_server_name auth.hubris.network
|
||||||
|
}
|
||||||
|
header_up Host auth.hubris.network
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
artifacto.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
# Public paths: share URLs, static assets, health — no SSO
|
||||||
|
@public path /p/* /static/* /healthz
|
||||||
|
handle @public {
|
||||||
|
reverse_proxy 192.168.8.205:3100
|
||||||
|
}
|
||||||
|
# Admin + login surface: Authentik forward-auth + shared-secret header
|
||||||
|
# so the app can auto-login an Authentik-authenticated user.
|
||||||
|
handle {
|
||||||
|
import authentik
|
||||||
|
reverse_proxy 192.168.8.205:3100 {
|
||||||
|
header_up X-Artifacto-Gateway {env.ARTIFACTO_GATEWAY_SECRET}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plato.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.8.190:8080
|
||||||
|
}
|
||||||
|
|
||||||
|
zimaos.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.8.195:80
|
||||||
|
}
|
||||||
|
|
||||||
|
# Homelab MCP server (read-only context + management tools).
|
||||||
|
# Mesh+LAN-gated by the service itself + nftables; no SSO so agent clients work.
|
||||||
|
sso.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy https://auth.hubris.network:443 {
|
||||||
|
transport http {
|
||||||
|
tls_server_name auth.hubris.network
|
||||||
|
}
|
||||||
|
header_up Host auth.hubris.network
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Matrix Synapse federation + client API.
|
||||||
|
# No authentik gate — Synapse handles its own auth.
|
||||||
|
|
||||||
|
|
||||||
|
trmnl.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.8.211:9851
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
teddy.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy https://192.168.8.150:8443 {
|
||||||
|
transport http {
|
||||||
|
tls_insecure_skip_verify
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ─── Oikos (Go rewrite, Docker on mac-mini) ───
|
||||||
|
# Phase 6 cutover — replaces apps/105 Python MCP + console.
|
||||||
|
# /api/v1/clients/enroll bypasses Authentik (IP-gated in the API handler).
|
||||||
|
# The SPA is its own container (:8091, compose/web/Dockerfile in the oikos
|
||||||
|
# repo) — not served by api itself, which no longer embeds it.
|
||||||
|
oikos.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
@enroll path /api/v1/clients/enroll /oidc-callback
|
||||||
|
handle @enroll {
|
||||||
|
reverse_proxy 192.168.178.182:8090
|
||||||
|
}
|
||||||
|
@api path /api/v1/* /mcp /agent/*
|
||||||
|
handle @api {
|
||||||
|
reverse_proxy 192.168.178.182:8090
|
||||||
|
}
|
||||||
|
handle {
|
||||||
|
import authentik
|
||||||
|
reverse_proxy 192.168.178.182:8091
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mcp.hubris.network {
|
||||||
|
reverse_proxy 192.168.178.182:8090
|
||||||
|
}
|
||||||
|
|
||||||
|
hermes.hubris.network {
|
||||||
|
reverse_proxy 192.168.178.182:8092
|
||||||
|
}
|
||||||
|
|
||||||
|
tube.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.178.44:8082
|
||||||
|
}
|
||||||
83
hosts/strong/Caddyfile
Normal file
83
hosts/strong/Caddyfile
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
import /etc/caddy/shared/*
|
||||||
|
|
||||||
|
media.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
# SSO plugin handles auth via OIDC redirect to Authentik.
|
||||||
|
# No forward-auth gate — Jellyfin login page shows SSO button directly.
|
||||||
|
reverse_proxy 192.168.8.246:8096
|
||||||
|
}
|
||||||
|
|
||||||
|
books.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.8.247:6060
|
||||||
|
}
|
||||||
|
|
||||||
|
roms.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.8.249:80
|
||||||
|
}
|
||||||
|
|
||||||
|
jellyseerr.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.8.245:5056
|
||||||
|
}
|
||||||
|
|
||||||
|
qbit.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
@api path /api/*
|
||||||
|
handle @api {
|
||||||
|
reverse_proxy 192.168.8.245:8080
|
||||||
|
}
|
||||||
|
handle {
|
||||||
|
import authentik
|
||||||
|
reverse_proxy 192.168.8.245:8080
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sab.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
handle {
|
||||||
|
import authentik
|
||||||
|
reverse_proxy 192.168.8.245:8082
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
matrix.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.8.242:8008
|
||||||
|
}
|
||||||
|
|
||||||
|
element.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.8.242:8080
|
||||||
|
}
|
||||||
|
|
||||||
|
house.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.8.244:3000
|
||||||
|
}
|
||||||
|
|
||||||
|
seanime.hubris.network {
|
||||||
|
tls {
|
||||||
|
dns ionos {env.IONOS_AUTH_API_TOKEN}
|
||||||
|
}
|
||||||
|
reverse_proxy 192.168.8.248:43211
|
||||||
|
}
|
||||||
324
hosts/vps/traefik-dynamic.yaml
Normal file
324
hosts/vps/traefik-dynamic.yaml
Normal file
@@ -0,0 +1,324 @@
|
|||||||
|
tcp:
|
||||||
|
serversTransports:
|
||||||
|
pp-v2:
|
||||||
|
proxyProtocol:
|
||||||
|
version: 2
|
||||||
|
|
||||||
|
tls:
|
||||||
|
certificates:
|
||||||
|
- certFile: /letsencrypt/fullchain.crt
|
||||||
|
keyFile: /letsencrypt/privkey.key
|
||||||
|
- certFile: /letsencrypt/blog.fullchain.crt
|
||||||
|
keyFile: /letsencrypt/blog.privkey.key
|
||||||
|
- certFile: /letsencrypt/trmnl.fullchain.crt
|
||||||
|
keyFile: /letsencrypt/trmnl.privkey.key
|
||||||
|
- certFile: /letsencrypt/sso.fullchain.crt
|
||||||
|
keyFile: /letsencrypt/sso.privkey.key
|
||||||
|
- certFile: /letsencrypt/media.fullchain.crt
|
||||||
|
keyFile: /letsencrypt/media.privkey.key
|
||||||
|
- certFile: /letsencrypt/paperless.fullchain.crt
|
||||||
|
keyFile: /letsencrypt/paperless.privkey.key
|
||||||
|
|
||||||
|
http:
|
||||||
|
serversTransports:
|
||||||
|
caddy-hubris:
|
||||||
|
serverName: mcp.hubris.network
|
||||||
|
proxmox:
|
||||||
|
serverName: proxmox.hubris.network
|
||||||
|
insecureSkipVerify: true
|
||||||
|
|
||||||
|
routers:
|
||||||
|
artifacto-public:
|
||||||
|
rule: 'Host(`artifacto.hubris.network`) && (PathPrefix(`/p/`) || PathPrefix(`/static/`) || Path(`/healthz`))'
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
priority: 10
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
middlewares:
|
||||||
|
- artifacto-strip-sso
|
||||||
|
- artifacto-ratelimit
|
||||||
|
service: artifacto-public
|
||||||
|
blog-public:
|
||||||
|
rule: 'Host(`blog.hubris.network`)'
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
priority: 10
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
middlewares:
|
||||||
|
- blog-ratelimit
|
||||||
|
service: blog-public
|
||||||
|
trmnl-public:
|
||||||
|
rule: 'Host(`trmnl.hubris.network`)'
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
priority: 10
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
middlewares:
|
||||||
|
- trmnl-ratelimit
|
||||||
|
service: trmnl-public
|
||||||
|
matrix-public:
|
||||||
|
rule: 'Host(`matrix.hubris.network`) && !PathPrefix(`/.well-known/matrix/`)'
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
priority: 10
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
middlewares:
|
||||||
|
- matrix-ratelimit
|
||||||
|
service: matrix-public
|
||||||
|
matrix-wellknown:
|
||||||
|
rule: 'Host(`matrix.hubris.network`) && (PathPrefix(`/.well-known/matrix/`) || PathPrefix(`/.well-known/acme-challenge/`))'
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
priority: 20
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
service: matrix-wellknown-svc
|
||||||
|
house-public:
|
||||||
|
rule: 'Host(`house.hubris.network`)'
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
priority: 10
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
middlewares:
|
||||||
|
- house-ratelimit
|
||||||
|
service: house-public
|
||||||
|
sso-public:
|
||||||
|
rule: 'Host(`sso.hubris.network`)'
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
priority: 10
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
middlewares:
|
||||||
|
- sso-ratelimit
|
||||||
|
service: sso-public
|
||||||
|
media-public:
|
||||||
|
rule: 'Host(`media.hubris.network`)'
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
priority: 10
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
middlewares:
|
||||||
|
- media-ratelimit
|
||||||
|
service: media-public
|
||||||
|
paperless-api-public:
|
||||||
|
rule: 'Host(`paperless.hubris.network`) && PathPrefix(`/api/`)'
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
priority: 20
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
middlewares:
|
||||||
|
- paperless-ratelimit
|
||||||
|
service: paperless-public
|
||||||
|
paperless-public:
|
||||||
|
rule: 'Host(`paperless.hubris.network`)'
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
priority: 10
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
middlewares:
|
||||||
|
- authentik-forwardauth
|
||||||
|
- paperless-ratelimit
|
||||||
|
service: paperless-public
|
||||||
|
git-public:
|
||||||
|
rule: 'Host(`git.hubris.network`)'
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
priority: 10
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
middlewares:
|
||||||
|
- git-ratelimit
|
||||||
|
service: git-public
|
||||||
|
mcp-public:
|
||||||
|
rule: 'Host(`mcp.hubris.network`)'
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
priority: 10
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
middlewares:
|
||||||
|
- mcp-ratelimit
|
||||||
|
service: mcp-public
|
||||||
|
oikos-public:
|
||||||
|
rule: 'Host(`oikos.hubris.network`)'
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
priority: 10
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
middlewares:
|
||||||
|
- oikos-ratelimit
|
||||||
|
service: oikos-public
|
||||||
|
proxmox-public:
|
||||||
|
rule: 'Host(`proxmox.hubris.network`)'
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
priority: 10
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
middlewares:
|
||||||
|
- proxmox-ratelimit
|
||||||
|
service: proxmox-public
|
||||||
|
|
||||||
|
middlewares:
|
||||||
|
admin-allowlist:
|
||||||
|
ipAllowList:
|
||||||
|
sourceRange:
|
||||||
|
- "5.61.168.0/24"
|
||||||
|
artifacto-strip-sso:
|
||||||
|
headers:
|
||||||
|
customRequestHeaders:
|
||||||
|
X-Artifacto-Gateway: ""
|
||||||
|
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: ""
|
||||||
|
artifacto-ratelimit:
|
||||||
|
rateLimit:
|
||||||
|
average: 50
|
||||||
|
period: 1s
|
||||||
|
burst: 100
|
||||||
|
blog-ratelimit:
|
||||||
|
rateLimit:
|
||||||
|
average: 100
|
||||||
|
period: 1s
|
||||||
|
burst: 200
|
||||||
|
trmnl-ratelimit:
|
||||||
|
rateLimit:
|
||||||
|
average: 20
|
||||||
|
period: 1s
|
||||||
|
burst: 40
|
||||||
|
matrix-ratelimit:
|
||||||
|
rateLimit:
|
||||||
|
average: 30
|
||||||
|
period: 1s
|
||||||
|
burst: 60
|
||||||
|
house-ratelimit:
|
||||||
|
rateLimit:
|
||||||
|
average: 30
|
||||||
|
period: 1s
|
||||||
|
burst: 60
|
||||||
|
sso-ratelimit:
|
||||||
|
rateLimit:
|
||||||
|
average: 30
|
||||||
|
period: 1s
|
||||||
|
burst: 60
|
||||||
|
media-ratelimit:
|
||||||
|
rateLimit:
|
||||||
|
average: 30
|
||||||
|
period: 1s
|
||||||
|
burst: 60
|
||||||
|
paperless-ratelimit:
|
||||||
|
rateLimit:
|
||||||
|
average: 20
|
||||||
|
period: 1s
|
||||||
|
burst: 40
|
||||||
|
authentik-forwardauth:
|
||||||
|
forwardAuth:
|
||||||
|
address: "http://192.168.8.6:9000/outpost.goauthentik.io/auth/traefik"
|
||||||
|
trustForwardHeader: true
|
||||||
|
authResponseHeaders:
|
||||||
|
- 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
|
||||||
|
git-ratelimit:
|
||||||
|
rateLimit:
|
||||||
|
average: 30
|
||||||
|
period: 1s
|
||||||
|
burst: 60
|
||||||
|
mcp-ratelimit:
|
||||||
|
rateLimit:
|
||||||
|
average: 30
|
||||||
|
period: 1s
|
||||||
|
burst: 60
|
||||||
|
oikos-ratelimit:
|
||||||
|
rateLimit:
|
||||||
|
average: 30
|
||||||
|
period: 1s
|
||||||
|
burst: 60
|
||||||
|
proxmox-ratelimit:
|
||||||
|
rateLimit:
|
||||||
|
average: 20
|
||||||
|
period: 1s
|
||||||
|
burst: 40
|
||||||
|
|
||||||
|
services:
|
||||||
|
artifacto-public:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: 'http://192.168.8.205:3100'
|
||||||
|
blog-public:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: 'http://192.168.8.205:8080'
|
||||||
|
trmnl-public:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: 'http://192.168.8.211:9851'
|
||||||
|
matrix-public:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: 'http://192.168.8.242:8008'
|
||||||
|
matrix-wellknown-svc:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: 'http://matrix-wellknown:80'
|
||||||
|
house-public:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: 'http://192.168.8.244:3000'
|
||||||
|
sso-public:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: 'http://192.168.8.6:9000'
|
||||||
|
media-public:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: 'http://192.168.8.246:8096'
|
||||||
|
paperless-public:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: 'http://192.168.8.130:8000'
|
||||||
|
git-public:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: 'http://192.168.8.121:3000'
|
||||||
|
mcp-public:
|
||||||
|
loadBalancer:
|
||||||
|
serversTransport: caddy-hubris
|
||||||
|
servers:
|
||||||
|
- url: 'https://192.168.8.175:443'
|
||||||
|
oikos-public:
|
||||||
|
loadBalancer:
|
||||||
|
serversTransport: caddy-hubris
|
||||||
|
servers:
|
||||||
|
- url: 'https://192.168.8.175:443'
|
||||||
|
proxmox-public:
|
||||||
|
loadBalancer:
|
||||||
|
serversTransport: proxmox
|
||||||
|
servers:
|
||||||
|
- url: 'https://192.168.8.77:8006'
|
||||||
31
shared/authentik
Normal file
31
shared/authentik
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Internal forward-auth upstream proxy (no TLS between Caddy handlers)
|
||||||
|
:8099 {
|
||||||
|
@outpost path /outpost.goauthentik.io/*
|
||||||
|
reverse_proxy @outpost https://auth.hubris.network:443 {
|
||||||
|
transport http {
|
||||||
|
tls_server_name auth.hubris.network
|
||||||
|
}
|
||||||
|
header_up Host auth.hubris.network
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Authentik forward-auth snippet (domain-level mode).
|
||||||
|
# Usage: add "import authentik" inside any site block to gate it.
|
||||||
|
(authentik) {
|
||||||
|
route {
|
||||||
|
reverse_proxy /outpost.goauthentik.io/* https://auth.hubris.network:443
|
||||||
|
forward_auth http://127.0.0.1:8099 {
|
||||||
|
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
|
||||||
|
trusted_proxies private_ranges
|
||||||
|
header_up X-Forwarded-Host {host}
|
||||||
|
header_up X-Forwarded-Proto {scheme}
|
||||||
|
header_up X-Forwarded-Uri {uri}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Internal webhook receiver for auto-deploy from Gitea
|
||||||
|
:8080 {
|
||||||
|
reverse_proxy 127.0.0.1:8081
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user