mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 22:41:09 +02:00
chore(infra): make cloudflared-config.yml the single source of truth
Reconciles the in-repo cloudflared-config.yml with the actually-loaded
ingress map on the Mac Mini production tunnel — the previous repo file
was missing 30+ hostnames (per-app subdomains, mana-api, sync, llm,
media, credits, subscriptions, etc.) because it was last updated
before the unified Mana web app rollout. Adds the new mana-api.mana.how
ingress for apps/api on port 3060 so the unified backend has a public
client URL for the SvelteKit web app's PUBLIC_MANA_API_URL_CLIENT.
Drops the dead matrix.mana.how / element.mana.how routes — the matrix
subsystem was removed in 2514831a3 and those services no longer exist.
Adds scripts/mac-mini/sync-tunnel-config.sh — the one-command flow for
shipping a tunnel-config change: pull on the server, validate the
yaml, kickstart cloudflared via launchctl. setup-cloudflared-service.sh
already wires the launchd plist with --config <repo-path> pointing at
this file, so a fresh Mac Mini install + setup script + sync script
gives you a fully reproducible tunnel.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8adef1b39c
commit
3993400013
2 changed files with 225 additions and 25 deletions
|
|
@ -1,53 +1,157 @@
|
|||
# Cloudflare Tunnel Configuration for the Mac Mini production server.
|
||||
#
|
||||
# This file is the SINGLE SOURCE OF TRUTH for which public hostnames
|
||||
# the tunnel exposes. The cloudflared launchd plist is started with
|
||||
# `--config <this-file> run` so any change here is one `git pull` +
|
||||
# `launchctl kickstart -k gui/501/com.cloudflare.cloudflared` away
|
||||
# from being live in production.
|
||||
#
|
||||
# Adding a new public hostname:
|
||||
# 1. Append the hostname / service line below in the matching section
|
||||
# 2. Make sure the corresponding Cloudflare DNS record exists (the
|
||||
# tunnel needs the hostname pointing at its CNAME — see
|
||||
# `cloudflared tunnel route dns <tunnel-id> <hostname>` if not)
|
||||
# 3. Run `./scripts/mac-mini/sync-tunnel-config.sh` to copy this file
|
||||
# onto the Mac Mini and reload cloudflared
|
||||
# 4. Verify with `curl -sI https://<hostname>/health` (or the route's
|
||||
# equivalent) — expect a non-404 status line
|
||||
#
|
||||
# Removing a hostname: same steps, just delete the lines.
|
||||
#
|
||||
# Catch-all at the bottom returns http_status:404 for any hostname
|
||||
# Cloudflare routes here that we don't have an explicit ingress rule
|
||||
# for. This is the desired failure mode.
|
||||
|
||||
tunnel: bb0ea86d-8253-4a54-838b-107bb7945be9
|
||||
credentials-file: /Users/mana/.cloudflared/bb0ea86d-8253-4a54-838b-107bb7945be9.json
|
||||
|
||||
ingress:
|
||||
# SSH Access (requires cloudflared on client)
|
||||
# ============================================
|
||||
# SSH (requires cloudflared on the client)
|
||||
# ============================================
|
||||
- hostname: ssh.mana.how
|
||||
service: ssh://localhost:22
|
||||
|
||||
# Mana Dashboard (Main)
|
||||
# ============================================
|
||||
# Unified Mana Web App (Port 5000)
|
||||
# ============================================
|
||||
# Every per-product subdomain points at the same SvelteKit container.
|
||||
# The container's hooks.server.ts reads the host header and renders
|
||||
# the matching module surface. mana.how itself is the dashboard.
|
||||
- hostname: mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: chat.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: todo.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: calendar.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: clock.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: contacts.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: zitare.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: skilltree.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: planta.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: cards.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: storage.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: presi.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: nutriphi.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: photos.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: mukke.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: picture.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: calc.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: citycorners.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: inventar.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: times.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: uload.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: memoro.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: context.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: questions.mana.how
|
||||
service: http://localhost:5000
|
||||
- hostname: moodlit.mana.how
|
||||
service: http://localhost:5000
|
||||
|
||||
# Auth Service
|
||||
# ============================================
|
||||
# Auth Service (Hono/Bun)
|
||||
# ============================================
|
||||
- hostname: auth.mana.how
|
||||
service: http://localhost:3001
|
||||
|
||||
# ============================================
|
||||
# Unified Backend API (Hono/Bun, port 3060)
|
||||
# ============================================
|
||||
# apps/api hosts every product compute module (calendar, chat,
|
||||
# picture, planta, news, who, …) under /api/v1/{module}/*. The
|
||||
# unified web app's PUBLIC_MANA_API_URL_CLIENT points here.
|
||||
- hostname: mana-api.mana.how
|
||||
service: http://localhost:3060
|
||||
|
||||
# ============================================
|
||||
# API Gateway (Go)
|
||||
# ============================================
|
||||
# Older gateway in front of the per-service compute layer. New
|
||||
# services should go directly through mana-api above; this gateway
|
||||
# only handles legacy entry points.
|
||||
- hostname: api.mana.how
|
||||
service: http://localhost:3016
|
||||
|
||||
# ============================================
|
||||
# Forgejo (Git + CI/CD)
|
||||
# ============================================
|
||||
- hostname: git.mana.how
|
||||
service: http://localhost:3041
|
||||
|
||||
# NOTE: Individual app backends (chat, todo, calendar, contacts, storage,
|
||||
# nutriphi, music, planta, picture, etc.) have been REMOVED — all migrated
|
||||
# to local-first architecture. Web apps run as routes under mana.how.
|
||||
# Only uload-server and memoro-server remain as app-specific backends.
|
||||
# ============================================
|
||||
# Standalone microservices
|
||||
# ============================================
|
||||
- hostname: uload-api.mana.how
|
||||
service: http://localhost:3070
|
||||
- hostname: media.mana.how
|
||||
service: http://localhost:3011
|
||||
- hostname: llm.mana.how
|
||||
service: http://localhost:3025
|
||||
- hostname: sync.mana.how
|
||||
service: http://localhost:3010
|
||||
- hostname: credits.mana.how
|
||||
service: http://localhost:3002
|
||||
- hostname: subscriptions.mana.how
|
||||
service: http://localhost:3063
|
||||
|
||||
# Games
|
||||
- hostname: whopxl.mana.how
|
||||
service: http://localhost:5100
|
||||
# ============================================
|
||||
# Standalone web apps (separate containers)
|
||||
# ============================================
|
||||
- hostname: playground.mana.how
|
||||
service: http://localhost:5050
|
||||
- hostname: arcade.mana.how
|
||||
service: http://localhost:5210
|
||||
- hostname: manavoxel.mana.how
|
||||
service: http://localhost:5028
|
||||
- hostname: whopxl.mana.how
|
||||
service: http://localhost:5100
|
||||
|
||||
# Public Status Page (generated every 60s by mana-status-gen container)
|
||||
# ============================================
|
||||
# Self-hosted landing pages (Nginx on port 4400)
|
||||
# ============================================
|
||||
- hostname: status.mana.how
|
||||
service: http://localhost:4400
|
||||
|
||||
# Monitoring & Tools
|
||||
- hostname: grafana.mana.how
|
||||
service: http://localhost:8000
|
||||
- hostname: stats.mana.how
|
||||
service: http://localhost:8010
|
||||
|
||||
# GlitchTip Error Tracking
|
||||
- hostname: glitchtip.mana.how
|
||||
service: http://localhost:8020
|
||||
|
||||
# Self-Hosted Landing Pages (via Nginx on port 4400)
|
||||
- hostname: it.mana.how
|
||||
service: http://localhost:4400
|
||||
- hostname: chats.mana.how
|
||||
|
|
@ -63,7 +167,22 @@ ingress:
|
|||
- hostname: docs.mana.how
|
||||
service: http://localhost:4400
|
||||
|
||||
# GPU Server (Windows PC, LAN: 192.168.178.11)
|
||||
# ============================================
|
||||
# Monitoring & observability
|
||||
# ============================================
|
||||
- hostname: grafana.mana.how
|
||||
service: http://localhost:8000
|
||||
- hostname: stats.mana.how
|
||||
service: http://localhost:8010
|
||||
- hostname: glitchtip.mana.how
|
||||
service: http://localhost:8020
|
||||
|
||||
# ============================================
|
||||
# GPU server forwarders (Windows PC, LAN: 192.168.178.11)
|
||||
# ============================================
|
||||
# The Mac Mini fronts the Windows GPU box's services so they're
|
||||
# reachable through the same tunnel without exposing the LAN box
|
||||
# to the public internet directly.
|
||||
- hostname: gpu-llm.mana.how
|
||||
service: http://192.168.178.11:3025
|
||||
- hostname: gpu-stt.mana.how
|
||||
|
|
@ -77,5 +196,7 @@ ingress:
|
|||
- hostname: gpu-ollama.mana.how
|
||||
service: http://192.168.178.11:11434
|
||||
|
||||
# Catch-all
|
||||
# ============================================
|
||||
# Catch-all (returns 404 for any unmapped hostname)
|
||||
# ============================================
|
||||
- service: http_status:404
|
||||
|
|
|
|||
79
scripts/mac-mini/sync-tunnel-config.sh
Executable file
79
scripts/mac-mini/sync-tunnel-config.sh
Executable file
|
|
@ -0,0 +1,79 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Sync the in-repo cloudflared-config.yml onto the Mac Mini and reload
|
||||
# the tunnel. Run this whenever cloudflared-config.yml changes — it's
|
||||
# the only step needed to make a new public hostname go live.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/mac-mini/sync-tunnel-config.sh
|
||||
#
|
||||
# Requires:
|
||||
# - SSH access to the `mana-server` host (configured in ~/.ssh/config)
|
||||
# - The launchd plist on the server already started cloudflared with
|
||||
# `--config <repo-path>/cloudflared-config.yml run`. If not, run
|
||||
# ./scripts/mac-mini/setup-cloudflared-service.sh on the server
|
||||
# once first.
|
||||
#
|
||||
# Why a kickstart instead of unload+load: launchctl kickstart -k
|
||||
# preserves the launchd state, doesn't race with KeepAlive, and
|
||||
# returns when the new process is up. unload/load is the legacy form
|
||||
# and tends to leave the agent in a stuck state on macOS 14+.
|
||||
|
||||
set -e
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
CONFIG_FILE="$REPO_ROOT/cloudflared-config.yml"
|
||||
REMOTE_HOST="mana-server"
|
||||
REMOTE_PATH='~/projects/mana-monorepo/cloudflared-config.yml'
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
if [ ! -f "$CONFIG_FILE" ]; then
|
||||
echo -e "${RED}Error:${NC} $CONFIG_FILE not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}=== Syncing cloudflared-config.yml ===${NC}"
|
||||
echo ""
|
||||
|
||||
# 1. Validate the YAML locally before pushing — cloudflared has a
|
||||
# `tunnel ingress validate` subcommand that catches duplicate
|
||||
# hostnames, malformed services, and missing tunnel-id. We rely on
|
||||
# the server's cloudflared install to do the actual validation
|
||||
# after the file lands so we don't need cloudflared on the dev box.
|
||||
|
||||
echo -e "${YELLOW}1. Pulling latest from origin (in case the local file is stale)...${NC}"
|
||||
( cd "$REPO_ROOT" && git fetch --quiet origin main && git diff --quiet origin/main -- cloudflared-config.yml ) || \
|
||||
echo -e "${YELLOW} warning: local cloudflared-config.yml differs from origin/main${NC}"
|
||||
|
||||
echo -e "${YELLOW}2. Ensuring repo on the server is up to date...${NC}"
|
||||
ssh "$REMOTE_HOST" 'cd ~/projects/mana-monorepo && git pull --quiet'
|
||||
|
||||
echo -e "${YELLOW}3. Validating the config on the server...${NC}"
|
||||
if ! ssh "$REMOTE_HOST" "/opt/homebrew/bin/cloudflared tunnel --config $REMOTE_PATH ingress validate"; then
|
||||
echo -e "${RED}Validation failed — aborting reload.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}4. Reloading cloudflared via launchctl kickstart...${NC}"
|
||||
ssh "$REMOTE_HOST" 'launchctl kickstart -k gui/$(id -u)/com.cloudflare.cloudflared'
|
||||
|
||||
echo -e "${YELLOW}5. Waiting for the tunnel to register...${NC}"
|
||||
sleep 5
|
||||
|
||||
echo -e "${YELLOW}6. Sanity-checking the tunnel is back up...${NC}"
|
||||
if curl -sf -o /dev/null https://mana.how; then
|
||||
echo -e "${GREEN}✓ https://mana.how is reachable${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ https://mana.how is NOT reachable — check 'tail -f /tmp/cloudflared.log' on the server${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ Tunnel config synced and reloaded.${NC}"
|
||||
echo ""
|
||||
echo "List currently-loaded routes:"
|
||||
echo " ssh $REMOTE_HOST 'grep INF /tmp/cloudflared.log | grep \"Updated to new configuration\" | tail -1'"
|
||||
Loading…
Add table
Add a link
Reference in a new issue