Files
wehub-resource-sync 542cfa195c
CI / Frontend build (push) Failing after 9m6s
CI / Plugin validate (push) Failing after 9m27s
CI / Python lint (push) Failing after 16m1s
CI / Tests (push) Successful in 18m0s
Deploy / deploy (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:27 +08:00
..

Deploy

How PixelRAG runs in production. (Host-specific details — the actual machine, secrets, live state — are intentionally not in this public repo; they live in an out-of-repo file the root CLAUDE.md imports on the deploy host.)

Topology

  • Frontend (web/) — deployed on Vercel from main, automatically.
  • Search API (serve/) — pixelrag serve behind nginx, run blue-green (two slots).
  • Chat agent (web/agent-server.mjs) — a Node service that calls the search API.

CD — self-hosted runner (egress-only)

Continuous deployment uses a self-hosted GitHub Actions runner on the deploy box. The runner dials out to GitHub (no inbound access, no SSH keys or hostnames in the repo/secrets), so the machine stays private and works behind a firewall.

.github/workflows/deploy.yml triggers only on push to main (post-merge = trusted code) and manual dispatch — never pull_request — so fork PRs can't run on the runner. All CI stays on GitHub-hosted runners.

On each deploy, deploy/deploy.sh fast-forwards the checkout and restarts only what changed:

  • uv.lockuv sync
  • web/agent-server.mjs → restart the agent (cheap)
  • serve/** → flagged only (a search-index reload is expensive — use blue-green instead)

It refuses to run unless the checkout is on a clean main (the deploy box doubles as a dev machine, so it must never clobber in-progress work).

Blue-green search API

Two slots — blue and green — each an independent pixelrag serve on its own port, fronted by an nginx upstream (pixelrag-api-upstream.conf/etc/nginx/conf.d/). To roll out a new index or model with zero downtime:

  1. Bring up the idle slot with the new config (pixelrag-api-green.service is the green slot).
  2. deploy/api-switch.sh <port> — health- and smoke-checks the target, flips the nginx upstream with a graceful reload (no dropped connections), and repoints + restarts the agent.
  3. Rollback = deploy/api-switch.sh <other-port>.

This is preferred over restarting a slot in place, which reloads the (large) FAISS index and would mean minutes of downtime.

Files

  • deploy.sh — CD restart logic (invoked by the Deploy workflow)
  • api-switch.sh — blue-green cutover + rollback
  • pixelrag-api.service, pixelrag-api-green.service — the two search-API slots
  • pixelrag-agent.service — the chat agent
  • pixelrag-api-upstream.conf — nginx upstream the switch script rewrites