shipyard staging gets a stable URL: b3.dannydannydanny.me

Drop the cloudflared Quick Tunnel (URL changed on every restart →
unworkable for shipyard's apps.json). Move to the same pattern
every other tenant uses:

- vps-relay Caddy: new virtualHost b3.dannydannydanny.me →
  reverse_proxy to sunken-ship's ZT IPv6 :8081.
- sunken-ship: open port 8081 on the zt+ firewall interface
  (was 8080 + 8091, now 8080 + 8081 + 8091).
- fitness-bot-shipyard service: set WEBAPP_URL=https://b3...
  so start.py skips its own tunnel attempt; drop pkgs.cloudflared
  from path now that nothing in the unit needs it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Danny 2026-05-10 14:00:39 +02:00
parent 067bab125b
commit 83dd92d738
2 changed files with 25 additions and 13 deletions

View file

@ -95,10 +95,10 @@
networking.firewall = { networking.firewall = {
allowedTCPPorts = [ 7000 7001 7100 4533 ]; allowedTCPPorts = [ 7000 7001 7100 4533 ];
allowedUDPPorts = [ 5353 6000 6001 7011 ]; allowedUDPPorts = [ 5353 6000 6001 7011 ];
# 8080: bbbot HTTP backend. 8091: mulbo-server companion service. # 8080: bbbot HTTP backend. 8081: bbbot SHIPYARD STAGING (B3Bot beta).
# Both ZT-only — see vps-relay.nix for reverse proxy if exposing # 8091: mulbo-server companion service. All ZT-only — see vps-relay.nix
# publicly later. # for the reverse proxies that expose them publicly.
interfaces."zt+".allowedTCPPorts = [ 8080 8091 ]; interfaces."zt+".allowedTCPPorts = [ 8080 8081 8091 ];
}; };
# Navidrome — self-hosted music streaming server (Subsonic API). # Navidrome — self-hosted music streaming server (Subsonic API).
@ -210,17 +210,22 @@
timerConfig.RandomizedDelaySec = "2min"; timerConfig.RandomizedDelaySec = "2min";
}; };
# ── Shipyard staging — second instance for verifying changes pre-prod ─ # ── Shipyard staging — B3Bot beta tenant under shipyard_poc_bot ──────
# Working dir: /home/danny/tg_fitness_bot_shipyard (separate clone of the same repo). # Mini-App-only HTTP server (no Telegram polling — shipyard_poc_bot on
# phantom-ship owns the polling loop; this service only validates Telegram
# WebApp initData HMACs against the shared bot token).
#
# Working dir: /home/danny/tg_fitness_bot_shipyard (separate clone of the
# same repo, gitignored workouts.db kept across pulls).
# Branch: origin/staging (push there to deploy here; push to origin/main for prod). # Branch: origin/staging (push there to deploy here; push to origin/main for prod).
# Bot: shipyard_poc_bot — the shared "POC slot" Telegram bot. While B3Bot
# staging is the active POC, shipyard_poc_bot polls into this service.
# Token file: /home/danny/.secrets/shipyard_poc_bot.env # Token file: /home/danny/.secrets/shipyard_poc_bot.env
# File contents: BOT_TOKEN=<shipyard_poc_bot token> # File contents: BOT_TOKEN=<shipyard_poc_bot token>
# Service won't start until this file exists (ConditionPathExists). # Service won't start until this file exists (ConditionPathExists).
# Mini App URL: ephemeral cloudflared Quick Tunnel (no VPS Caddy). # Mini App URL: https://b3.dannydannydanny.me (vps-relay Caddy →
# Workflow: git push origin <branch>:staging → wait ~15 min → /start # ZT IPv6 → here:8081). Stable across restarts — listed in
# shipyard_poc_bot in Telegram → test → git push origin <branch>:main. # ~/python-projects/26_shipyard/apps.json.
# Workflow: git push origin <branch>:staging → wait ~15 min → tap B3Bot
# beta in shipyard_poc_bot's launcher → test → git push <branch>:main.
systemd.services.fitness-bot-shipyard = let systemd.services.fitness-bot-shipyard = let
pythonEnv = pkgs.python3.withPackages (ps: with ps; [ pythonEnv = pkgs.python3.withPackages (ps: with ps; [
python-telegram-bot python-telegram-bot
@ -232,10 +237,12 @@
after = [ "network-online.target" ]; after = [ "network-online.target" ];
wants = [ "network-online.target" ]; wants = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [ pythonEnv pkgs.cloudflared ]; path = [ pythonEnv ];
environment.API_HOST = "::"; environment.API_HOST = "::";
environment.API_PORT = "8081"; environment.API_PORT = "8081";
# No WEBAPP_URL — start.py spins up its own ephemeral cloudflared tunnel. # Stable URL fronted by vps-relay's Caddy → ZT → here:8081.
# WEBAPP_URL set tells start.py to skip cloudflared entirely.
environment.WEBAPP_URL = "https://b3.dannydannydanny.me";
unitConfig.ConditionPathExists = "/home/danny/.secrets/shipyard_poc_bot.env"; unitConfig.ConditionPathExists = "/home/danny/.secrets/shipyard_poc_bot.env";
serviceConfig = { serviceConfig = {
WorkingDirectory = "/home/danny/tg_fitness_bot_shipyard"; WorkingDirectory = "/home/danny/tg_fitness_bot_shipyard";

View file

@ -101,6 +101,11 @@
"bbbot.dannydannydanny.me".extraConfig = '' "bbbot.dannydannydanny.me".extraConfig = ''
reverse_proxy http://[fdd5:53a2:de33:d269:6499:93d5:53a2:de33]:8080 reverse_proxy http://[fdd5:53a2:de33:d269:6499:93d5:53a2:de33]:8080
''; '';
# B3Bot beta — bbbot's staging tenant under shipyard_poc_bot.
# Same backend host as bbbot prod, port 8081.
"b3.dannydannydanny.me".extraConfig = ''
reverse_proxy http://[fdd5:53a2:de33:d269:6499:93d5:53a2:de33]:8081
'';
# Shelfish — phantom-ship's ZT IPv6. # Shelfish — phantom-ship's ZT IPv6.
"shelfish.dannydannydanny.me".extraConfig = '' "shelfish.dannydannydanny.me".extraConfig = ''
reverse_proxy http://[fdd5:53a2:de33:d269:6499:936c:48a:bbdc]:8081 reverse_proxy http://[fdd5:53a2:de33:d269:6499:936c:48a:bbdc]:8081