🚀 herald: production hardening — SOLARGOD_READONLY gates /snap; unit adapted to the tunnel topology (fable)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
03f1c009f2
commit
a6538fee1c
@ -1,5 +1,7 @@
|
||||
# HERALD — systemd unit for SOLARGOD. serve.py binds 127.0.0.1 only; nginx
|
||||
# reverse-proxies the public domain to it (mirror of the godstrument.pro shape).
|
||||
# HERALD — systemd unit for SOLARGOD on the botchat VPS. serve.py binds
|
||||
# 127.0.0.1 only; the cloudflared tunnel's ingress rule for
|
||||
# solargod.godstrument.pro forwards to it (same shape as godstrument.pro —
|
||||
# no nginx in this topology; nginx-solargod.conf is the alternative shape).
|
||||
# Install: sudo cp deploy/solargod.service /etc/systemd/system/ && sudo systemctl enable --now solargod
|
||||
[Unit]
|
||||
Description=SOLARGOD orrery — serve.py (static + JPL Horizons/SBDB/CAD proxy + disk cache)
|
||||
@ -7,9 +9,10 @@ After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
WorkingDirectory=/opt/solargod
|
||||
ExecStart=/usr/bin/python3 /opt/solargod/serve.py 8147
|
||||
User=humanjing
|
||||
WorkingDirectory=/home/humanjing/solargod
|
||||
Environment=SOLARGOD_READONLY=1
|
||||
ExecStart=/usr/bin/python3 /home/humanjing/solargod/serve.py 8147
|
||||
Restart=on-failure
|
||||
RestartSec=3
|
||||
# serve.py writes its disk cache under WorkingDirectory/cache — keep it writable.
|
||||
|
||||
8
serve.py
8
serve.py
@ -32,6 +32,9 @@ PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8147
|
||||
ROOT = Path(__file__).resolve().parent
|
||||
CACHE_DIR = ROOT / "cache"
|
||||
CACHE_TTL_SEC = 24 * 3600
|
||||
# Production (HERALD): SOLARGOD_READONLY=1 disables the dev-only /snap write
|
||||
# endpoint — behind a public tunnel, the server must accept no writes at all.
|
||||
READONLY = os.environ.get("SOLARGOD_READONLY") == "1"
|
||||
|
||||
UPSTREAMS = {
|
||||
"horizons": "https://ssd.jpl.nasa.gov/api/horizons.api",
|
||||
@ -182,7 +185,10 @@ class Handler(SimpleHTTPRequestHandler):
|
||||
def do_POST(self):
|
||||
# Dev-only screenshot sink: POST /snap?name=<n> with base64 PNG (or a
|
||||
# data:image/png;base64,... URL) → docs/<n>.png. Bound to 127.0.0.1; the
|
||||
# name is sanitized so the write can never escape docs/.
|
||||
# name is sanitized so the write can never escape docs/. Disabled entirely
|
||||
# in production (SOLARGOD_READONLY=1) — a tunneled deploy must not write.
|
||||
if READONLY:
|
||||
return self.send_error(403, "read-only deployment")
|
||||
if not (self.path == "/snap" or self.path.startswith("/snap?")):
|
||||
return self.send_error(404, "not found")
|
||||
_, _, query = self.path.partition("?")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user