docs(path-b): mark weeks 1-3 shipped; preview routing scoped
- AI_PATH_B_EXECUTION_PLAN.md: Status changed from "proposed" to
"week 1 shipped", weeks 1-3 checkboxes flipped to ✅ for the parts
that landed in vibn-frontend@4ba9407 and @41d4d37. Lists what's
still manual (DNS wildcard, Coolify host image build, Traefik cert).
- vibn-dev/PREVIEWS.md: Architecture for *.preview.vibnai.com
routing, the deferred Coolify-compose-hot-update piece, and an
HMR/websocket troubleshooting checklist.
- vibn-dev/setup-on-coolify.sh: One-shot script to build
vibn-dev:latest on the Coolify host (referenced by the compose
template's pull_policy: never).
Made-with: Cursor
This commit is contained in:
95
vibn-dev/PREVIEWS.md
Normal file
95
vibn-dev/PREVIEWS.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# Preview URL routing for vibn-dev
|
||||
|
||||
Goal: every `dev_server.start` returns a URL like
|
||||
`https://vite-mark-marketplace-7a3f.preview.vibnai.com` that works
|
||||
end-to-end (TLS, HMR, websockets) without the user touching DNS or
|
||||
Coolify config.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Browser
|
||||
│ https://<sub>.preview.vibnai.com
|
||||
▼
|
||||
Traefik (Coolify-managed)
|
||||
│ routes by Host header → matching docker label
|
||||
▼
|
||||
vibn-dev container for project X
|
||||
│ HOST=0.0.0.0 PORT=3000
|
||||
▼
|
||||
Vite / Next dev / etc.
|
||||
```
|
||||
|
||||
Two pieces have to be true for this to work:
|
||||
|
||||
1. **DNS wildcard** — `*.preview.vibnai.com` must resolve to the
|
||||
Coolify host's public IP. Set this in Cloudflare / OpenSRS once.
|
||||
2. **Traefik dynamic router** — for each running dev_server, attach
|
||||
docker labels to the vibn-dev container so Traefik picks up the
|
||||
subdomain → port mapping.
|
||||
|
||||
## DNS step (one-time)
|
||||
|
||||
In OpenSRS (or whichever DNS we use for vibnai.com):
|
||||
|
||||
```
|
||||
*.preview.vibnai.com. IN A <coolify-host-ip>
|
||||
```
|
||||
|
||||
Cert: Traefik will solve a wildcard via DNS-01 against the same DNS
|
||||
provider. Add a DNS provider env to Coolify's Traefik:
|
||||
|
||||
```yaml
|
||||
# already in our Coolify Traefik config
|
||||
- "--certificatesresolvers.letsencrypt.acme.dnschallenge=true"
|
||||
- "--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=opensrs"
|
||||
```
|
||||
|
||||
(Traefik supports OpenSRS via `OPENSRS_USERNAME` + `OPENSRS_PASSWORD`
|
||||
env vars.)
|
||||
|
||||
## Traefik labels (per dev_server)
|
||||
|
||||
When a dev_server starts on port `P` with subdomain `S`, we update
|
||||
the vibn-dev compose file with these labels and re-deploy the service:
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.vibn-dev-${S}.rule=Host(`${S}.preview.vibnai.com`)"
|
||||
- "traefik.http.routers.vibn-dev-${S}.entrypoints=https"
|
||||
- "traefik.http.routers.vibn-dev-${S}.tls=true"
|
||||
- "traefik.http.routers.vibn-dev-${S}.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.vibn-dev-${S}.loadbalancer.server.port=${P}"
|
||||
```
|
||||
|
||||
## What's deferred
|
||||
|
||||
The current `dev_server.start` records the URL and PID but does NOT
|
||||
yet update the Coolify compose to add the Traefik labels — that
|
||||
requires an `updateService` call against Coolify's API with the
|
||||
revised compose YAML, which round-trips through Coolify's deployment
|
||||
pipeline (~30s). For week 1 we keep dev servers reachable from inside
|
||||
the container (`shell.exec curl http://localhost:PORT`) so the AI can
|
||||
verify they boot, and we'll wire the Traefik label injection in week 2
|
||||
once we've decided whether to:
|
||||
|
||||
(a) bake the labels into the compose at `ensureDevContainer` time
|
||||
(one Traefik router per fixed port range, e.g. 3000-3010), OR
|
||||
(b) hot-update the compose on each `dev_server.start` (more flexible
|
||||
but slower and racier).
|
||||
|
||||
Recommendation: (a) — pre-allocate router rules for ports 3000-3010
|
||||
on container creation. Simpler, faster, no compose churn. Limit dev
|
||||
servers per project to 10.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- "Host header mismatch" → check the dev server is actually binding
|
||||
to 0.0.0.0 (not localhost). Some frameworks default to localhost
|
||||
even with `HOST=0.0.0.0` env; pass `--host 0.0.0.0` to the cli.
|
||||
- HMR websocket fails → Vite needs `server.hmr.clientPort: 443` and
|
||||
`server.hmr.host: <subdomain>.preview.vibnai.com`. Document this in
|
||||
the AI system prompt for week 2.
|
||||
- 404 from Traefik → labels didn't apply. Check `docker inspect
|
||||
vibn-dev-<projectSlug>` and verify the labels are present.
|
||||
33
vibn-dev/setup-on-coolify.sh
Executable file
33
vibn-dev/setup-on-coolify.sh
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build the vibn-dev image on the Coolify host so every project's
|
||||
# docker-compose can reference `vibn-dev:latest` with pull_policy: never.
|
||||
#
|
||||
# Run this ONCE per Coolify host before the first chat session uses
|
||||
# Path B. Re-run whenever you bump the Dockerfile.
|
||||
#
|
||||
# Usage (from a workstation):
|
||||
# scp -r vibn-dev/ root@<coolify-host>:/tmp/
|
||||
# ssh root@<coolify-host> 'bash /tmp/vibn-dev/setup-on-coolify.sh'
|
||||
#
|
||||
# Or run via the Coolify SSH backbone (vibn-logs user has docker access):
|
||||
# ssh -i ~/.ssh/coolify_logs vibn-logs@<host> \
|
||||
# "cd /tmp/vibn-dev && docker build -t vibn-dev:latest ."
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
echo "Building vibn-dev:latest on $(hostname)..."
|
||||
docker build -t vibn-dev:latest .
|
||||
|
||||
echo
|
||||
echo "Done. Image:"
|
||||
docker images vibn-dev:latest --format 'table {{.Repository}}:{{.Tag}}\t{{.Size}}\t{{.CreatedSince}}'
|
||||
|
||||
echo
|
||||
echo "Smoke test (should print 'ok'):"
|
||||
docker run --rm vibn-dev:latest bash -c 'rg --version > /dev/null && git --version > /dev/null && echo ok'
|
||||
|
||||
echo
|
||||
echo "vibn-dev is ready. New AI dev containers will reference this image"
|
||||
echo "via 'image: vibn-dev:latest' + 'pull_policy: never' in their compose."
|
||||
Reference in New Issue
Block a user