#!/usr/bin/env python3 """Re-apply this server's deltas to a freshly-copied docker-compose.hobby.yml. Upstream's bin/upgrade-hobby overwrites compose.yml from the repo on every upgrade, so these three changes have to be replayed afterwards. Idempotent: running it on an already-patched file is a no-op. Usage: bin/apply-local-patches.py [compose.yml] """ import sys path = sys.argv[1] if len(sys.argv) > 1 else 'compose.yml' s = open(path).read() changed = [] # 1) nginx-proxy-manager owns host 80/443. Publish Caddy on loopback instead and # put it on nginx-bridge so NPM can reach it by name. old = """ ports: - '80:80' - '443:443' """ new = """ ports: # nginx-proxy-manager owns host 80/443. Loopback only; NPM reaches # this container over nginx-bridge as "posthog". - '127.0.0.1:${POSTHOG_HTTP_PORT:-8002}:80' networks: default: nginx-bridge: aliases: - posthog """ if old in s: s = s.replace(old, new) changed.append('proxy ports + nginx-bridge') # 2) TLS terminates at NPM, so Caddy must not try to get its own certs. Take the # site address from .env (CADDY_HOST=:80) instead of the hardcoded domain. old = " CADDY_HOST: '$DOMAIN, http://, https://'\n" if old in s: s = s.replace(old, " CADDY_HOST: $CADDY_HOST\n") changed.append('CADDY_HOST from .env') # 3) Temporal gRPC + UI on loopback, not every interface. for a, b in ((" - 7233:7233\n", " - 127.0.0.1:7233:7233\n"), (" - 8081:8080\n", " - 127.0.0.1:8081:8080\n")): if a in s: s = s.replace(a, b) changed.append(a.strip()) # 4) nginx-bridge is created and owned by ~/Server/Nginx. old = "networks:\n otel_network:\n" if old in s and 'nginx-bridge:\n external: true' not in s: s = s.replace(old, "networks:\n otel_network:\n nginx-bridge:\n external: true\n") changed.append('nginx-bridge external') open(path, 'w').write(s) print(f"{path}: " + (", ".join(changed) if changed else "already patched, no changes"))