Persist TB-006 batch 2 media SSO and batch 1 auth fixes to the repo.
Media sites get Caddy forward_auth; Authentik scripts cover all proxy providers. BookStack OIDC and Plane admin routing fixes included, plus ops scripts for external auth on valhalla.
This commit is contained in:
@@ -81,27 +81,57 @@ requests.ginnoir.com {
|
|||||||
# =============================================================
|
# =============================================================
|
||||||
sonarr.ginnoir.com {
|
sonarr.ginnoir.com {
|
||||||
import internal_only
|
import internal_only
|
||||||
|
route {
|
||||||
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
reverse_proxy sonarr:8989
|
reverse_proxy sonarr:8989
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
radarr.ginnoir.com {
|
radarr.ginnoir.com {
|
||||||
import internal_only
|
import internal_only
|
||||||
|
route {
|
||||||
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
reverse_proxy radarr:7878
|
reverse_proxy radarr:7878
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bazarr.ginnoir.com {
|
bazarr.ginnoir.com {
|
||||||
import internal_only
|
import internal_only
|
||||||
|
route {
|
||||||
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
reverse_proxy bazarr:6767
|
reverse_proxy bazarr:6767
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prowlarr.ginnoir.com {
|
prowlarr.ginnoir.com {
|
||||||
import internal_only
|
import internal_only
|
||||||
|
route {
|
||||||
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
reverse_proxy prowlarr:9696
|
reverse_proxy prowlarr:9696
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tautulli.ginnoir.com {
|
tautulli.ginnoir.com {
|
||||||
import internal_only
|
import internal_only
|
||||||
|
route {
|
||||||
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
reverse_proxy tautulli:8181
|
reverse_proxy tautulli:8181
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# =============================================================
|
# =============================================================
|
||||||
@@ -109,27 +139,57 @@ tautulli.ginnoir.com {
|
|||||||
# =============================================================
|
# =============================================================
|
||||||
qbittorrent.ginnoir.com {
|
qbittorrent.ginnoir.com {
|
||||||
import internal_only
|
import internal_only
|
||||||
|
route {
|
||||||
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
reverse_proxy qbittorrent:3232
|
reverse_proxy qbittorrent:3232
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deluge.ginnoir.com {
|
deluge.ginnoir.com {
|
||||||
import internal_only
|
import internal_only
|
||||||
|
route {
|
||||||
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
reverse_proxy deluge:8112
|
reverse_proxy deluge:8112
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nzbget.ginnoir.com {
|
nzbget.ginnoir.com {
|
||||||
import internal_only
|
import internal_only
|
||||||
|
route {
|
||||||
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
reverse_proxy nzbget:6789
|
reverse_proxy nzbget:6789
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
whisparr.ginnoir.com {
|
whisparr.ginnoir.com {
|
||||||
import internal_only
|
import internal_only
|
||||||
|
route {
|
||||||
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
reverse_proxy whisparr:6969
|
reverse_proxy whisparr:6969
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stash.ginnoir.com {
|
stash.ginnoir.com {
|
||||||
import internal_only
|
import internal_only
|
||||||
|
route {
|
||||||
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
reverse_proxy stash:6970
|
reverse_proxy stash:6970
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# =============================================================
|
# =============================================================
|
||||||
@@ -344,15 +404,25 @@ docs.ginnoir.com {
|
|||||||
}
|
}
|
||||||
|
|
||||||
plane.ginnoir.com {
|
plane.ginnoir.com {
|
||||||
|
route {
|
||||||
|
import authentik_outpost
|
||||||
handle /api/* {
|
handle /api/* {
|
||||||
|
import authentik_forward_auth
|
||||||
reverse_proxy plane_api:8000
|
reverse_proxy plane_api:8000
|
||||||
}
|
}
|
||||||
handle /auth/* {
|
handle /auth/* {
|
||||||
|
import authentik_forward_auth
|
||||||
reverse_proxy plane_api:8000
|
reverse_proxy plane_api:8000
|
||||||
}
|
}
|
||||||
|
handle /god-mode/* {
|
||||||
|
import authentik_forward_auth
|
||||||
|
reverse_proxy plane_admin:3000
|
||||||
|
}
|
||||||
handle {
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
reverse_proxy plane_web:3000
|
reverse_proxy plane_web:3000
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# =============================================================
|
# =============================================================
|
||||||
|
|||||||
@@ -0,0 +1,138 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# TB-006 batch 2: disable local auth; Servarr -> External; skip tautulli.
|
||||||
|
# Run on valhalla as ginnoir.
|
||||||
|
|
||||||
|
set_servarr_external() {
|
||||||
|
local app="$1"
|
||||||
|
local cfg="/config/${app}/config.xml"
|
||||||
|
if [[ ! -f "$cfg" ]]; then
|
||||||
|
echo "SKIP ${app}: no ${cfg}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
echo "=== ${app}: set External ==="
|
||||||
|
docker stop "$app" >/dev/null
|
||||||
|
python3 - "$cfg" <<'PY'
|
||||||
|
import sys
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
path = sys.argv[1]
|
||||||
|
tree = ET.parse(path)
|
||||||
|
root = tree.getroot()
|
||||||
|
|
||||||
|
auth_required = None
|
||||||
|
for el in list(root):
|
||||||
|
if el.tag == "AuthenticationRequired" and el.text:
|
||||||
|
auth_required = el.text.strip()
|
||||||
|
break
|
||||||
|
|
||||||
|
for el in list(root):
|
||||||
|
if el.tag in ("AuthenticationMethod", "AuthenticationRequired"):
|
||||||
|
root.remove(el)
|
||||||
|
|
||||||
|
ext = ET.SubElement(root, "AuthenticationMethod")
|
||||||
|
ext.text = "External"
|
||||||
|
req = ET.SubElement(root, "AuthenticationRequired")
|
||||||
|
req.text = auth_required or "Enabled"
|
||||||
|
|
||||||
|
tree.write(path, encoding="UTF-8", xml_declaration=True)
|
||||||
|
print(f" wrote External (AuthenticationRequired={req.text})")
|
||||||
|
PY
|
||||||
|
docker start "$app" >/dev/null
|
||||||
|
grep Authentication "$cfg"
|
||||||
|
}
|
||||||
|
|
||||||
|
for app in sonarr radarr prowlarr whisparr; do
|
||||||
|
set_servarr_external "$app"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "=== bazarr: verify auth disabled ==="
|
||||||
|
python3 - <<'PY'
|
||||||
|
import yaml
|
||||||
|
path = "/config/bazarr/config/config.yaml"
|
||||||
|
with open(path) as f:
|
||||||
|
d = yaml.safe_load(f)
|
||||||
|
auth = d.setdefault("auth", {})
|
||||||
|
changed = False
|
||||||
|
if auth.get("type") is not None:
|
||||||
|
auth["type"] = None
|
||||||
|
changed = True
|
||||||
|
if auth.get("username"):
|
||||||
|
auth["username"] = ""
|
||||||
|
changed = True
|
||||||
|
if auth.get("password"):
|
||||||
|
auth["password"] = ""
|
||||||
|
changed = True
|
||||||
|
if changed:
|
||||||
|
with open(path, "w") as f:
|
||||||
|
yaml.safe_dump(d, f, default_flow_style=False, sort_keys=False)
|
||||||
|
print(" updated bazarr auth -> type null")
|
||||||
|
else:
|
||||||
|
print(" already type null / no credentials")
|
||||||
|
PY
|
||||||
|
docker restart bazarr >/dev/null
|
||||||
|
|
||||||
|
echo "=== qbittorrent: disable WebUI auth (keep API key for *arr) ==="
|
||||||
|
QCONF="/config/qbittorrent/qBittorrent/qBittorrent.conf"
|
||||||
|
docker stop qbittorrent >/dev/null
|
||||||
|
python3 - "$QCONF" <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
path = Path(sys.argv[1])
|
||||||
|
lines = path.read_text().splitlines()
|
||||||
|
out = []
|
||||||
|
added = False
|
||||||
|
for line in lines:
|
||||||
|
if line.startswith("WebUI\\AuthenticationEnabled="):
|
||||||
|
out.append("WebUI\\AuthenticationEnabled=false")
|
||||||
|
added = True
|
||||||
|
continue
|
||||||
|
out.append(line)
|
||||||
|
if not added:
|
||||||
|
final = []
|
||||||
|
for line in out:
|
||||||
|
final.append(line)
|
||||||
|
if line.strip() == "[Preferences]":
|
||||||
|
final.append("WebUI\\AuthenticationEnabled=false")
|
||||||
|
added = True
|
||||||
|
out = final
|
||||||
|
path.write_text("\n".join(out) + "\n")
|
||||||
|
print(" WebUI\\AuthenticationEnabled=false")
|
||||||
|
PY
|
||||||
|
grep 'WebUI\\AuthenticationEnabled' "$QCONF" || true
|
||||||
|
docker start qbittorrent >/dev/null
|
||||||
|
|
||||||
|
echo "=== nzbget: disable form auth (API creds unchanged) ==="
|
||||||
|
NZB="/config/nzbget/nzbget.conf"
|
||||||
|
sed -i 's/^FormAuth=.*/FormAuth=no/' "$NZB"
|
||||||
|
sed -i 's/^SecureControl=.*/SecureControl=no/' "$NZB"
|
||||||
|
grep -E '^(FormAuth|SecureControl)=' "$NZB"
|
||||||
|
docker restart nzbget >/dev/null
|
||||||
|
|
||||||
|
echo "=== stash: external authwall (Authentik + internal_only) ==="
|
||||||
|
python3 - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
path = Path("/config/stash/config.yml")
|
||||||
|
text = path.read_text()
|
||||||
|
text = re.sub(r'^dangerous_allow_public_without_auth:.*$', 'dangerous_allow_public_without_auth: "true"', text, flags=re.M)
|
||||||
|
text = re.sub(r'^username:.*$', 'username: ""', text, flags=re.M)
|
||||||
|
text = re.sub(r'^password:.*$', 'password: ""', text, flags=re.M)
|
||||||
|
text = re.sub(r'^security_tripwire_accessed_from_public_internet:.*\n', '', text, flags=re.M)
|
||||||
|
path.write_text(text)
|
||||||
|
print(" dangerous_allow_public_without_auth=true, cleared username/password")
|
||||||
|
PY
|
||||||
|
docker restart stash >/dev/null
|
||||||
|
|
||||||
|
echo "=== deluge: bypass web login (Authentik at edge; patch re-applies on recreate) ==="
|
||||||
|
if docker exec deluge grep -q 'homelab external auth' /lsiopy/lib/python3.12/site-packages/deluge/ui/web/auth.py 2>/dev/null; then
|
||||||
|
echo " already patched"
|
||||||
|
else
|
||||||
|
docker cp /tmp/patch-deluge-auth.py deluge:/tmp/patch-deluge-auth.py
|
||||||
|
docker exec deluge python3 /tmp/patch-deluge-auth.py
|
||||||
|
docker restart deluge >/dev/null
|
||||||
|
echo " patched and restarted"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== done (tautulli untouched) ==="
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
path = Path("/lsiopy/lib/python3.12/site-packages/deluge/ui/web/auth.py")
|
||||||
|
text = path.read_text()
|
||||||
|
if "homelab external auth" in text:
|
||||||
|
print("already patched")
|
||||||
|
raise SystemExit(0)
|
||||||
|
|
||||||
|
text = text.replace(
|
||||||
|
" return s.hexdigest() == config['pwd_sha1']",
|
||||||
|
" return True # homelab external auth",
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
old_login = """ if self.check_password(password):
|
||||||
|
log.info('Login success (ClientIP %s)', __request__.getClientIP())
|
||||||
|
return self._create_session(__request__)
|
||||||
|
else:
|
||||||
|
log.error('Login failed (ClientIP %s)', __request__.getClientIP())
|
||||||
|
return False"""
|
||||||
|
new_login = """ log.info('Login success (ClientIP %s) [homelab external auth]', __request__.getClientIP())
|
||||||
|
return self._create_session(__request__)"""
|
||||||
|
if old_login not in text:
|
||||||
|
raise SystemExit("login() pattern not found")
|
||||||
|
text = text.replace(old_login, new_login, 1)
|
||||||
|
path.write_text(text)
|
||||||
|
print("patched auth.py")
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Apply TB-006 batch 1 forward_auth proxy providers (forward_auth-only sites).
|
"""Apply TB-006 forward_auth proxy providers (admin batch 1 + media batch 2).
|
||||||
|
|
||||||
Native OAuth/OIDC apps (bookstack, gitea, portainer, minio, plane, homarr) use
|
Native OAuth/OIDC apps (bookstack, gitea, portainer, minio, homarr) use
|
||||||
setup-batch1-oidc.py instead. Run this via: ak shell -c exec(open(...).read())
|
setup-batch1-oidc.py instead. Run this via: ak shell -c exec(open(...).read())
|
||||||
"""
|
"""
|
||||||
from authentik.core.models import Application
|
from authentik.core.models import Application
|
||||||
@@ -21,12 +21,25 @@ UPTIME_UNAUTH = """^/status/.*
|
|||||||
^/upload/.*"""
|
^/upload/.*"""
|
||||||
|
|
||||||
SITES = [
|
SITES = [
|
||||||
|
# Batch 1 — admin
|
||||||
("homelab-code", "code", "code-server", "https://code.ginnoir.com", None, None),
|
("homelab-code", "code", "code-server", "https://code.ginnoir.com", None, None),
|
||||||
("homelab-registry-ui", "registry-ui", "Registry UI", "https://registry-ui.ginnoir.com", None, None),
|
("homelab-registry-ui", "registry-ui", "Registry UI", "https://registry-ui.ginnoir.com", None, None),
|
||||||
("homelab-vault", "vault", "Vault", "https://vault.ginnoir.com", None, None),
|
("homelab-vault", "vault", "Vault", "https://vault.ginnoir.com", None, None),
|
||||||
("homelab-uptime", "uptime", "Uptime Kuma", "https://uptime.ginnoir.com", "http://uptime-kuma:3001", UPTIME_UNAUTH),
|
("homelab-uptime", "uptime", "Uptime Kuma", "https://uptime.ginnoir.com", "http://uptime-kuma:3001", UPTIME_UNAUTH),
|
||||||
("homelab-backup", "backup", "Kopia", "https://backup.ginnoir.com", None, None),
|
("homelab-backup", "backup", "Kopia", "https://backup.ginnoir.com", None, None),
|
||||||
("homelab-dbx", "dbx", "DBX", "https://dbx.ginnoir.com", None, None),
|
("homelab-dbx", "dbx", "DBX", "https://dbx.ginnoir.com", None, None),
|
||||||
|
("homelab-plane", "plane", "Plane", "https://plane.ginnoir.com", None, None),
|
||||||
|
# Batch 2 — media *arr stack (internal_only + forward_auth at Caddy)
|
||||||
|
("homelab-sonarr", "sonarr", "Sonarr", "https://sonarr.ginnoir.com", None, None),
|
||||||
|
("homelab-radarr", "radarr", "Radarr", "https://radarr.ginnoir.com", None, None),
|
||||||
|
("homelab-bazarr", "bazarr", "Bazarr", "https://bazarr.ginnoir.com", None, None),
|
||||||
|
("homelab-prowlarr", "prowlarr", "Prowlarr", "https://prowlarr.ginnoir.com", None, None),
|
||||||
|
("homelab-tautulli", "tautulli", "Tautulli", "https://tautulli.ginnoir.com", None, None),
|
||||||
|
("homelab-qbit", "qbit", "qBittorrent", "https://qbittorrent.ginnoir.com", None, None),
|
||||||
|
("homelab-deluge", "deluge", "Deluge", "https://deluge.ginnoir.com", None, None),
|
||||||
|
("homelab-nzbget", "nzbget", "NZBGet", "https://nzbget.ginnoir.com", None, None),
|
||||||
|
("homelab-whisparr", "whisparr", "Whisparr", "https://whisparr.ginnoir.com", None, None),
|
||||||
|
("homelab-stash", "stash", "Stash", "https://stash.ginnoir.com", None, None),
|
||||||
]
|
]
|
||||||
|
|
||||||
providers = []
|
providers = []
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
"""Create OAuth2 providers for batch-1 apps with native SSO (ak shell: exec(open(...).read()))."""
|
"""Create OAuth2 providers for batch-1 apps with native SSO (ak shell: exec(open(...).read()))."""
|
||||||
from authentik.core.models import Application
|
from authentik.core.models import Application
|
||||||
|
from authentik.crypto.models import CertificateKeyPair
|
||||||
from authentik.flows.models import Flow
|
from authentik.flows.models import Flow
|
||||||
from authentik.outposts.models import Outpost
|
from authentik.outposts.models import Outpost
|
||||||
from authentik.providers.oauth2.models import OAuth2Provider, RedirectURI, RedirectURIMatchingMode
|
from authentik.providers.oauth2.models import OAuth2Provider, RedirectURI, RedirectURIMatchingMode, SubModes
|
||||||
from authentik.providers.proxy.models import ProxyProvider
|
from authentik.providers.proxy.models import ProxyProvider
|
||||||
|
|
||||||
AUTHZ = Flow.objects.get(slug="default-provider-authorization-implicit-consent")
|
AUTHZ = Flow.objects.get(slug="default-provider-authorization-implicit-consent")
|
||||||
INVALID = Flow.objects.get(slug="default-provider-invalidation-flow")
|
INVALID = Flow.objects.get(slug="default-provider-invalidation-flow")
|
||||||
DEFAULT_MAPPINGS = OAuth2Provider.objects.get(name="famapp").property_mappings.all()
|
DEFAULT_MAPPINGS = OAuth2Provider.objects.get(name="famapp").property_mappings.all()
|
||||||
|
SIGNING_KEY = CertificateKeyPair.objects.get(name="authentik Self-signed Certificate")
|
||||||
|
|
||||||
# slug, provider name, redirect URI(s)
|
# slug, provider name, redirect URI(s)
|
||||||
OIDC_APPS = [
|
OIDC_APPS = [
|
||||||
@@ -15,7 +17,6 @@ OIDC_APPS = [
|
|||||||
("gitea", "gitea", ["https://gitea.ginnoir.com/user/oauth2/Authentik/callback"]),
|
("gitea", "gitea", ["https://gitea.ginnoir.com/user/oauth2/Authentik/callback"]),
|
||||||
("portainer", "portainer", ["https://portainer.ginnoir.com/"]),
|
("portainer", "portainer", ["https://portainer.ginnoir.com/"]),
|
||||||
("minio", "minio-console", ["https://minio.ginnoir.com/oauth_callback"]),
|
("minio", "minio-console", ["https://minio.ginnoir.com/oauth_callback"]),
|
||||||
("plane", "plane", ["https://plane.ginnoir.com/auth/oidc/callback/"]),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
native_slugs = []
|
native_slugs = []
|
||||||
@@ -25,6 +26,8 @@ for slug, pname, redirects in OIDC_APPS:
|
|||||||
defaults={
|
defaults={
|
||||||
"authorization_flow": AUTHZ,
|
"authorization_flow": AUTHZ,
|
||||||
"invalidation_flow": INVALID,
|
"invalidation_flow": INVALID,
|
||||||
|
"signing_key": SIGNING_KEY,
|
||||||
|
"sub_mode": SubModes.USER_UUID if slug == "bookstack" else SubModes.HASHED_USER_ID,
|
||||||
"redirect_uris": [
|
"redirect_uris": [
|
||||||
RedirectURI(matching_mode=RedirectURIMatchingMode.STRICT, url=url)
|
RedirectURI(matching_mode=RedirectURIMatchingMode.STRICT, url=url)
|
||||||
for url in redirects
|
for url in redirects
|
||||||
@@ -60,7 +63,6 @@ PROXY_NAMES = {
|
|||||||
"gitea": "homelab-gitea",
|
"gitea": "homelab-gitea",
|
||||||
"portainer": "homelab-portainer",
|
"portainer": "homelab-portainer",
|
||||||
"minio": "homelab-minio",
|
"minio": "homelab-minio",
|
||||||
"plane": "homelab-plane",
|
|
||||||
}
|
}
|
||||||
outpost = Outpost.objects.get(name="authentik Embedded Outpost")
|
outpost = Outpost.objects.get(name="authentik Embedded Outpost")
|
||||||
for slug in native_slugs:
|
for slug in native_slugs:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
"""Update proxy providers for forward_auth-only batch-1 apps (ak shell: exec(open(...).read()))."""
|
"""Update proxy providers for forward_auth apps (admin batch 1 + media batch 2)."""
|
||||||
from authentik.core.models import Application
|
from authentik.core.models import Application
|
||||||
from authentik.flows.models import Flow
|
from authentik.flows.models import Flow
|
||||||
from authentik.outposts.models import Outpost, OutpostType
|
from authentik.outposts.models import Outpost, OutpostType
|
||||||
@@ -17,12 +17,25 @@ UPTIME_UNAUTH = """^/status/.*
|
|||||||
|
|
||||||
# Proxy-only sites (native OIDC apps managed by setup-batch1-oidc.py).
|
# Proxy-only sites (native OIDC apps managed by setup-batch1-oidc.py).
|
||||||
SITES = [
|
SITES = [
|
||||||
|
# Batch 1 — admin
|
||||||
("homelab-code", "code", "code-server", "https://code.ginnoir.com", None, None),
|
("homelab-code", "code", "code-server", "https://code.ginnoir.com", None, None),
|
||||||
("homelab-registry-ui", "registry-ui", "Registry UI", "https://registry-ui.ginnoir.com", None, None),
|
("homelab-registry-ui", "registry-ui", "Registry UI", "https://registry-ui.ginnoir.com", None, None),
|
||||||
("homelab-vault", "vault", "Vault", "https://vault.ginnoir.com", None, None),
|
("homelab-vault", "vault", "Vault", "https://vault.ginnoir.com", None, None),
|
||||||
("homelab-uptime", "uptime", "Uptime Kuma", "https://uptime.ginnoir.com", "http://uptime-kuma:3001", UPTIME_UNAUTH),
|
("homelab-uptime", "uptime", "Uptime Kuma", "https://uptime.ginnoir.com", "http://uptime-kuma:3001", UPTIME_UNAUTH),
|
||||||
("homelab-backup", "backup", "Kopia", "https://backup.ginnoir.com", None, None),
|
("homelab-backup", "backup", "Kopia", "https://backup.ginnoir.com", None, None),
|
||||||
("homelab-dbx", "dbx", "DBX", "https://dbx.ginnoir.com", None, None),
|
("homelab-dbx", "dbx", "DBX", "https://dbx.ginnoir.com", None, None),
|
||||||
|
("homelab-plane", "plane", "Plane", "https://plane.ginnoir.com", None, None),
|
||||||
|
# Batch 2 — media
|
||||||
|
("homelab-sonarr", "sonarr", "Sonarr", "https://sonarr.ginnoir.com", None, None),
|
||||||
|
("homelab-radarr", "radarr", "Radarr", "https://radarr.ginnoir.com", None, None),
|
||||||
|
("homelab-bazarr", "bazarr", "Bazarr", "https://bazarr.ginnoir.com", None, None),
|
||||||
|
("homelab-prowlarr", "prowlarr", "Prowlarr", "https://prowlarr.ginnoir.com", None, None),
|
||||||
|
("homelab-tautulli", "tautulli", "Tautulli", "https://tautulli.ginnoir.com", None, None),
|
||||||
|
("homelab-qbit", "qbit", "qBittorrent", "https://qbittorrent.ginnoir.com", None, None),
|
||||||
|
("homelab-deluge", "deluge", "Deluge", "https://deluge.ginnoir.com", None, None),
|
||||||
|
("homelab-nzbget", "nzbget", "NZBGet", "https://nzbget.ginnoir.com", None, None),
|
||||||
|
("homelab-whisparr", "whisparr", "Whisparr", "https://whisparr.ginnoir.com", None, None),
|
||||||
|
("homelab-stash", "stash", "Stash", "https://stash.ginnoir.com", None, None),
|
||||||
]
|
]
|
||||||
|
|
||||||
providers = []
|
providers = []
|
||||||
|
|||||||
@@ -147,12 +147,11 @@ services:
|
|||||||
- DB_PASS=${BOOKSTACK_DB_PASSWORD}
|
- DB_PASS=${BOOKSTACK_DB_PASSWORD}
|
||||||
- DB_DATABASE=bookstack
|
- DB_DATABASE=bookstack
|
||||||
- AUTH_METHOD=oidc
|
- AUTH_METHOD=oidc
|
||||||
- AUTH_AUTO_INITIATE=true
|
- AUTH_AUTO_INITIATE=false
|
||||||
- OIDC_NAME=Authentik
|
- OIDC_NAME=Authentik
|
||||||
- OIDC_CLIENT_ID=${BOOKSTACK_OIDC_CLIENT_ID}
|
|
||||||
- OIDC_CLIENT_SECRET=${BOOKSTACK_OIDC_CLIENT_SECRET}
|
|
||||||
- OIDC_ISSUER=https://auth.ginnoir.com/application/o/bookstack/
|
- OIDC_ISSUER=https://auth.ginnoir.com/application/o/bookstack/
|
||||||
- OIDC_ISSUER_DISCOVER=true
|
- OIDC_ISSUER_DISCOVER=true
|
||||||
|
- OIDC_END_SESSION_ENDPOINT=true
|
||||||
volumes:
|
volumes:
|
||||||
- /config/bookstack:/config
|
- /config/bookstack:/config
|
||||||
ports:
|
ports:
|
||||||
@@ -197,6 +196,23 @@ services:
|
|||||||
- NEXT_PUBLIC_API_BASE_URL=https://plane.ginnoir.com
|
- NEXT_PUBLIC_API_BASE_URL=https://plane.ginnoir.com
|
||||||
- HOSTNAME=0.0.0.0
|
- HOSTNAME=0.0.0.0
|
||||||
|
|
||||||
|
plane-admin:
|
||||||
|
container_name: plane_admin
|
||||||
|
image: makeplane/plane-admin:v0.23.1
|
||||||
|
restart: unless-stopped
|
||||||
|
networks: [dev, edge]
|
||||||
|
command: node admin/server.js
|
||||||
|
env_file:
|
||||||
|
- stack.env
|
||||||
|
environment:
|
||||||
|
- NEXT_PUBLIC_API_BASE_URL=https://plane.ginnoir.com
|
||||||
|
- HOSTNAME=0.0.0.0
|
||||||
|
depends_on:
|
||||||
|
plane-api:
|
||||||
|
condition: service_started
|
||||||
|
plane-web:
|
||||||
|
condition: service_started
|
||||||
|
|
||||||
plane-api:
|
plane-api:
|
||||||
container_name: plane_api
|
container_name: plane_api
|
||||||
image: makeplane/plane-backend:latest
|
image: makeplane/plane-backend:latest
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ BOOKSTACK_DB_PASSWORD=bookstack_d3v_pass
|
|||||||
BOOKSTACK_DB_ROOT_PASSWORD=bookstack_r00t_pass
|
BOOKSTACK_DB_ROOT_PASSWORD=bookstack_r00t_pass
|
||||||
BOOKSTACK_OIDC_CLIENT_ID=8YV4BI2JVIG1QzS2DbylEgqv56sgfiOVRXOgw2Z5
|
BOOKSTACK_OIDC_CLIENT_ID=8YV4BI2JVIG1QzS2DbylEgqv56sgfiOVRXOgw2Z5
|
||||||
BOOKSTACK_OIDC_CLIENT_SECRET=wIyiw7LmGBORDyTdc2crSZryXJHzIq4gtajAKSpOU7e8BkBSO6SstM9gGPrnp4tbJhCFSQggYAgtYd5LOjUvQpSWInzm0JLlmLg1BTlPq5EVVieNYuWRCCQrerj8gRZ0
|
BOOKSTACK_OIDC_CLIENT_SECRET=wIyiw7LmGBORDyTdc2crSZryXJHzIq4gtajAKSpOU7e8BkBSO6SstM9gGPrnp4tbJhCFSQggYAgtYd5LOjUvQpSWInzm0JLlmLg1BTlPq5EVVieNYuWRCCQrerj8gRZ0
|
||||||
|
# BookStack reads OIDC_* directly (env_file); BOOKSTACK_* kept for Portainer UI mirror if using ${} in compose.
|
||||||
|
OIDC_CLIENT_ID=8YV4BI2JVIG1QzS2DbylEgqv56sgfiOVRXOgw2Z5
|
||||||
|
OIDC_CLIENT_SECRET=wIyiw7LmGBORDyTdc2crSZryXJHzIq4gtajAKSpOU7e8BkBSO6SstM9gGPrnp4tbJhCFSQggYAgtYd5LOjUvQpSWInzm0JLlmLg1BTlPq5EVVieNYuWRCCQrerj8gRZ0
|
||||||
|
|
||||||
# Plane project management
|
# Plane project management
|
||||||
# Rotate with: openssl rand -hex 32
|
# Rotate with: openssl rand -hex 32
|
||||||
|
|||||||
Reference in New Issue
Block a user