configure.py: optional bare-domain Caddy block (redirect to the watch site by default)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-10-31 01:12:22 -05:00
parent f06ebc1ec1
commit 94db824243
2 changed files with 21 additions and 0 deletions

View File

@@ -18,3 +18,5 @@ MAIN_HOST=media.example.com
LIVE_WEBHOOK_URL= LIVE_WEBHOOK_URL=
BOT_REQUIRE_GROUP=bot-users BOT_REQUIRE_GROUP=bot-users
LIVE_REQUIRE_GROUP= LIVE_REQUIRE_GROUP=
APEX_HOST=
APEX_REDIRECT=

View File

@@ -152,6 +152,14 @@ def gate(required_group=""):
def write_caddy(domain, auth_host="", watch_host="", git_host="", bot_host="", live_host=""): def write_caddy(domain, auth_host="", watch_host="", git_host="", bot_host="", live_host=""):
env = read_env() env = read_env()
extra = "" extra = ""
apex, target = env.get("APEX_HOST", ""), env.get("APEX_REDIRECT", "")
if apex and target:
extra += f"""
# vanguard:apex
{apex} {{
redir {target} 302
}}
"""
if live_host: if live_host:
extra += f""" extra += f"""
# vanguard:live # vanguard:live
@@ -253,6 +261,8 @@ def write_env(watch_host, discord_token=None, discord_guild=None, git_host="", b
if main_host: env["MAIN_HOST"] = main_host if main_host: env["MAIN_HOST"] = main_host
if live_webhook is not None: env["LIVE_WEBHOOK_URL"] = live_webhook if live_webhook is not None: env["LIVE_WEBHOOK_URL"] = live_webhook
env.setdefault("LIVE_WEBHOOK_URL", "") env.setdefault("LIVE_WEBHOOK_URL", "")
env.setdefault("APEX_HOST", "") # bare domain to serve (A record -> this box); empty = skip
env.setdefault("APEX_REDIRECT", "") # where the bare domain sends people, e.g. https://watch.HOST/
env.setdefault("BOT_REQUIRE_GROUP", "bot-users") # Caddy 403s anyone not in this Authentik group; empty = any logged-in member env.setdefault("BOT_REQUIRE_GROUP", "bot-users") # Caddy 403s anyone not in this Authentik group; empty = any logged-in member
env.setdefault("LIVE_REQUIRE_GROUP", "") env.setdefault("LIVE_REQUIRE_GROUP", "")
env["GIT_HOST"] = git_host or env.get("GIT_HOST", "git.example.com") env["GIT_HOST"] = git_host or env.get("GIT_HOST", "git.example.com")
@@ -438,6 +448,8 @@ def apply(domain, admin_pw, streamers, editors, auth_host="", watch_host="", dis
def show(domain, admin_pw, streamers, editors, auth_host="", watch_host="", git_host="", bot_host="", live_host=""): def show(domain, admin_pw, streamers, editors, auth_host="", watch_host="", git_host="", bot_host="", live_host=""):
print(f"\n== domain : {domain or '(not set)'}") print(f"\n== domain : {domain or '(not set)'}")
_e = read_env()
if _e.get("APEX_HOST") and _e.get("APEX_REDIRECT"): print(f"== apex : https://{_e['APEX_HOST']}/ -> {_e['APEX_REDIRECT']}")
print(f"== live : https://{live_host}/ (behind Authentik forward-auth; deploy live/dist -> /srv/live; WebRTC needs 8189 open)" if live_host else "== live : (not set — run --full)") print(f"== live : https://{live_host}/ (behind Authentik forward-auth; deploy live/dist -> /srv/live; WebRTC needs 8189 open)" if live_host else "== live : (not set — run --full)")
print(f"== bot web : https://{bot_host}/ (Authentik forward-auth; Caddy requires group '{read_env().get('BOT_REQUIRE_GROUP','bot-users') or 'any'}')" if bot_host else "== bot web : (not set — run --full)") print(f"== bot web : https://{bot_host}/ (Authentik forward-auth; Caddy requires group '{read_env().get('BOT_REQUIRE_GROUP','bot-users') or 'any'}')" if bot_host else "== bot web : (not set — run --full)")
print(f"== gitea : https://{git_host}/ ssh port 2222 (runner: ./registerGiteaRunner.sh)" if git_host else "== gitea : (not set — run --full)") print(f"== gitea : https://{git_host}/ ssh port 2222 (runner: ./registerGiteaRunner.sh)" if git_host else "== gitea : (not set — run --full)")
@@ -492,6 +504,9 @@ def full(domain, admin_pw, streamers, editors, auth_host="", watch_host="", git_
git_host = ask("Gitea hostname (CNAME to the above)", git_host or default_sub(domain, "git")) git_host = ask("Gitea hostname (CNAME to the above)", git_host or default_sub(domain, "git"))
bot_host = ask("Bot web UI hostname (CNAME to the above)", bot_host or default_sub(domain, "bot")) bot_host = ask("Bot web UI hostname (CNAME to the above)", bot_host or default_sub(domain, "bot"))
live_host = ask("Live portal hostname (CNAME to the above)", live_host or default_sub(domain, "live")) live_host = ask("Live portal hostname (CNAME to the above)", live_host or default_sub(domain, "live"))
env0 = read_env(); parent = default_sub(domain, "x")[2:] if domain else ""
apex = ask("Bare domain to serve too (A record must point here; blank = skip)", env0.get("APEX_HOST", parent))
apex_to = ask(" bare domain redirects to", env0.get("APEX_REDIRECT") or (f"https://{watch_host}/" if watch_host else "")) if apex else ""
print("\n-- Discord bot (optional; the Bot added to the Authentik Discord application). Enter keeps the current value.") print("\n-- Discord bot (optional; the Bot added to the Authentik Discord application). Enter keeps the current value.")
discord_token, discord_guild = ask_discord() discord_token, discord_guild = ask_discord()
live_webhook = ask(" Discord webhook URL for 'is live' notices (optional)", read_env().get("LIVE_WEBHOOK_URL", "")) live_webhook = ask(" Discord webhook URL for 'is live' notices (optional)", read_env().get("LIVE_WEBHOOK_URL", ""))
@@ -517,6 +532,10 @@ def full(domain, admin_pw, streamers, editors, auth_host="", watch_host="", git_
n = ask_name("editor", editors) n = ask_name("editor", editors)
if not n: break if not n: break
editors[n] = ask_pw(n) editors[n] = ask_pw(n)
e = read_env(); e["APEX_HOST"] = apex; e["APEX_REDIRECT"] = apex_to
Path(".env").write_text("".join(f"{k}={v}\n" for k, v in e.items())) if Path(".env").exists() else None
if not Path(".env").exists():
Path(".env").write_text(f"APEX_HOST={apex}\nAPEX_REDIRECT={apex_to}\n"); os.chmod(".env", 0o600)
return domain, admin_pw, streamers, editors, auth_host, watch_host, discord_token, discord_guild, git_host, bot_host, live_host, live_webhook return domain, admin_pw, streamers, editors, auth_host, watch_host, discord_token, discord_guild, git_host, bot_host, live_host, live_webhook
def ask_discord(): def ask_discord():