thundercode commited on
Commit
08c9328
·
verified ·
1 Parent(s): 0adf671

release: add docs/DEPLOYMENT.md

Browse files
Files changed (1) hide show
  1. docs/DEPLOYMENT.md +126 -0
docs/DEPLOYMENT.md ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Deployment
2
+
3
+ **Status tags:** `IMPLEMENTED` · `VERIFIED` · `MEASURED` · `OPEN` · `DEFERRED` · `BLOCKED`.
4
+
5
+ The live system is deployed across three **private** repositories plus one **public** umbrella repo.
6
+ The monorepo working copy is **not** the deployed source. This document records the live topology,
7
+ the environment variables, the deploy mechanics, and the traps that cost real debugging time.
8
+
9
+ ---
10
+
11
+ ## 1. Live revisions (VERIFIED)
12
+
13
+ | Component | Repository | Visibility | Branch | Revision | Host |
14
+ |---|---|---|---|---|---|
15
+ | Frontend | `Anish-lab-blip/SatQuery-Frontend` | private | `main` | **`2d7ae53b482d`** | Cloudflare Pages → `satquery.pages.dev` |
16
+ | Backend / orchestrator | `Anish-lab-blip/SatQuery-Backend` | private | `main` | **`89d80eaddec5`** | Render → `satquery-backend-m4yv.onrender.com` |
17
+ | Inference | `Anish-lab-blip/SatQuery-Inference` | private | `main` | **`5a0936ace491`** | Codespace `potential-space-trout-r4ppw969w45j2pvvw`, port 8000 |
18
+ | Public umbrella | `Anish-lab-blip/SatQuery-AI` | **public** | `main` | `3dcabd32da41` | this release home |
19
+ | Monorepo (working copy) | `C:/Users/anish/satquery-ai` | local only | `master` | `9d57aed` | **no remote**; 334 dirty entries |
20
+
21
+ > **Trap.** `deploy/` inside the monorepo is **stale and untracked**. It is **not** the deployed
22
+ > source. Edits must go to the three real repositories.
23
+
24
+ ## 2. Live health (VERIFIED, probed)
25
+
26
+ ```json
27
+ {"status":"ok","service":"satquery-orchestrator",
28
+ "tunnel":{"agent_connected":true,"agent_id":"codespaces-fd1038","pending":0,"completed":97},
29
+ "config":{"codespace_name":"potential-space-trout-r4ppw969w45j2pvvw\n","codespace_port":8000,
30
+ "transport_mode":"auto","tunnel_timeout_s":150.0,"wake_timeout_s":120.0,
31
+ "upstream_timeout_s":90.0,"device":"cpu","has_github_token":true}}
32
+ ```
33
+
34
+ Note `codespace_name` still carries a trailing `\n` — the cosmetic B-02 patch is **not** deployed.
35
+
36
+ ## 3. Environment variables
37
+
38
+ ### 3.1 Render (gateway) — measured live
39
+
40
+ | Variable | Value (live) |
41
+ |---|---|
42
+ | `CODESPACE_NAME` | `potential-space-trout-r4ppw969w45j2pvvw` |
43
+ | `CODESPACE_PORT` | `8000` |
44
+ | `SATQUERY_ALLOWED_ORIGINS` | `https://satquery.pages.dev` |
45
+ | `SATQUERY_DEVICE` | `cpu` |
46
+ | `SATQUERY_TRANSPORT` | `auto` |
47
+ | `SATQUERY_TUNNEL_TIMEOUT_S` | `150` |
48
+ | `SATQUERY_WAKE_TIMEOUT_S` | `120` |
49
+ | `SATQUERY_UPSTREAM_TIMEOUT_S` | `90` |
50
+ | `GITHUB_TOKEN` | present |
51
+
52
+ > There is **no** `SATQUERY_UPSTREAM_URL` and **no** `HF_TOKEN` in the live config — the transport is
53
+ > the outbound tunnel, not a forwarded port.
54
+
55
+ ### 3.2 Codespace (inference)
56
+
57
+ | Variable | Purpose |
58
+ |---|---|
59
+ | `PORT` | platform-assigned; **must be read** |
60
+ | `SATQUERY_DEVICE` | `cpu` \| `cuda` \| `mps` \| `null`; read **without importing torch** |
61
+ | `SATQUERY_MAX_FILE_BYTES` | per-file cap (shared with Render) |
62
+ | `SATQUERY_ASSET_ENABLED` / `SATQUERY_ASSET_DIR` | both required for `/v1/assets`; fails closed (503) otherwise |
63
+ | `SATQUERY_ASSET_MAX_FILES` / `SATQUERY_ASSET_TTL_S` | optional handle capacity / lifetime |
64
+
65
+ ## 4. Deploy mechanics
66
+
67
+ - **Frontend → Cloudflare Pages.** Staged by `scripts/stage_pages.mjs`, deployed with
68
+ `npx wrangler pages deploy`.
69
+ - **Backend → Render.** `render.yaml` blueprint; `main.py` exposes `app`.
70
+ - **Inference → Codespace.** `deploy/codespace/serve.py` serves `build_space_app()` on `$PORT`;
71
+ `.devcontainer/` forwards port 8000 and runs the tunnel agent on start via `postStartCommand`.
72
+ - **Repository writes** are performed through the **GitHub Git Data API** (blob → tree → commit →
73
+ `PATCH` ref) with **sha256 byte-verification** of every uploaded blob. Deletions are expressed as
74
+ `sha: null` tree entries. This is used instead of `git push` so each deployed file is verified by
75
+ content hash.
76
+
77
+ ### 4.1 Deployed-artifact integrity
78
+
79
+ Deployed files were re-read from the GitHub API and compared byte-for-byte against the local copies:
80
+ **9 files sha256 byte-identical**, and the deployed HEAD re-read from the API. See
81
+ `verify_deployed_head.py`.
82
+
83
+ ## 5. Cold start (documented, not hidden)
84
+
85
+ Render's free tier sleeps when idle and the Codespace may be stopped. The frontend shows
86
+ *"Waking inference engine…"* while Render starts the Codespace and polls health. Cold start is
87
+ therefore **tens of seconds**, and this is documented rather than papered over.
88
+
89
+ ## 6. Known deployment issues
90
+
91
+ | ID | Issue | State |
92
+ |---|---|---|
93
+ | **B-07** | Transient tunnel-agent gaps → a request can hang or return 504. Patch prepared, **NOT deployed**. | **OPEN** |
94
+ | — | B-07 root shape: in `auto` mode a tunnel timeout **falls through** to the forward path (`main.py:546`), burning `wake_timeout_s = 120` on a `302` (~249 s ≈ 150 + 120). | measured |
95
+ | **B-02** | `/api/health` `codespace_name` trailing `\n`. Cosmetic; the wake path strips it. | **OPEN (cosmetic)** |
96
+ | — | Frontend/Backend/Inference repos are **private**, so their links 404 for an outside audience. | by design |
97
+
98
+ ## 7. Platform traps (recorded so they are not rediscovered)
99
+
100
+ - **Cloudflare `_headers` rules CONCATENATE, they do not override.** Two matching rules are merged;
101
+ Chromium takes the **first** `max-age` it encounters. A later rule cannot "fix" an earlier one.
102
+ - **Cloudflare 308-redirects `X.html` → `/X`.** Reference the extensionless path.
103
+ - **A forwarded Codespace port returns `302` for a private repo** — which is *why* the tunnel exists.
104
+ - **The tunnel agent must be started by the devcontainer `postStartCommand`**, or a restarted
105
+ Codespace comes up with `agent_connected:false`.
106
+ - **Never retry `POST /api/infer` at the gateway** — a retry consumes inference twice.
107
+
108
+ ## 8. Preconditions for a fresh deploy (open items)
109
+
110
+ 1. Cloudflare Pages project name / domain (needed for the deploy command and `robots.txt` sitemap).
111
+ 2. Artifacts present, or capabilities honestly ship `available: false` (the service **degrades rather
112
+ than crashes** on absent artifacts).
113
+ 3. `HF_TOKEN` set on Render **if** the HF proxy path is used (not used in the live config).
114
+ 4. Codespace `.devcontainer/` forwarding `:8000` and starting the tunnel agent.
115
+ 5. The five historical backend blockers closed and verified on the first live run (ASGI stack in
116
+ requirements; `$PORT` read; `OPTIONS` preflight; fail-fast app construction; adapter integrity
117
+ compared against an expected digest).
118
+
119
+ ## 9. Historical context
120
+
121
+ The superseded design ran inference on an **HF Space with ZeroGPU** behind a **Railway** gateway. The
122
+ active design moves to **Render + Codespace**, CPU-first, with an **outbound tunnel**. The four-endpoint
123
+ contract, the gateway responsibility table, the env-var vocabulary and the config freeze are
124
+ unchanged — only host names moved. `configs/deploy.yaml` still describes the old HF-Space/ZeroGPU
125
+ target and is left **undisturbed as frozen paperwork** (editing it would move the config hash); no
126
+ Gradio runtime exists in code.