Files
linumiq_net-docker/dev/README.md
T
linumiq_net-user 7fe0cc3753 dev: add parallel dev environment under /docker/dev
Near-1:1 clone of the prod remote-access stack, isolated on a new external
dev_edge network and fronted by the same shared Caddy instance (dual-homed on
edge + dev_edge). Dev is manual-start (not on boot).

- Hostnames: app-dev / api-dev .linumiq.net, tunnels under *.dev.linumiq.net,
  dev tunnel ingress on port 7001.
- Dev Supabase (project supabase-dev, *-dev containers), web, frps, redis,
  stripe-stub, bandwidth-worker with fresh independent secrets (gitignored).
- Shared Caddyfile: app-dev -> web-dev, api-dev -> dev kong (+webhook block),
  *.dev -> frps-dev vhost. Caddy compose dual-homed on dev_edge.
- On-demand-TLS authorizer (prod check-subdomain, in gitignored volumes/)
  extended additively: app-dev/api-dev -> 200; *.dev delegated to the dev
  authorizer. Prod allow-list logic unchanged.
- dev.sh manual up/down/ps helper; README documents topology + secrets.

Secrets, frps.toml, volumes/, web worktree and data dirs are gitignored.
2026-05-30 13:23:34 +02:00

58 lines
2.4 KiB
Markdown

# Dev environment (`/docker/dev`)
A near-1:1 clone of the production remote-access stack, isolated on its own
Docker network (`dev_edge`) and fronted by the **same shared Caddy** instance as
production. Dev is **manual-start** (not started on boot) to save resources.
## Hostnames
| Purpose | Production | Dev |
| -------------- | --------------------- | ------------------------- |
| Dashboard | `app.linumiq.net` | `app-dev.linumiq.net` |
| Supabase API | `api.linumiq.net` | `api-dev.linumiq.net` |
| Tunnels | `*.linumiq.net` | `*.dev.linumiq.net` |
| Tunnel ingress | `linumiq.net:7000` | `linumiq.net:7001` |
## Topology
- All dev services run on the external `dev_edge` network with `*-dev`
container names and their own internal `supabase-dev_default` network.
- The shared Caddy is dual-homed on `edge` (prod) and `dev_edge` (dev) and
routes the `*-dev` / `*.dev` hostnames to the dev upstreams.
- On-demand TLS for every hostname is authorized by Caddy's single global
`ask` endpoint (the prod `check-subdomain` edge function). It returns 200 for
`app-dev`/`api-dev`, and for `*.dev.linumiq.net` it delegates to the dev
authorizer (`supabase-dev-edge-functions:9000`), which checks the dev
`tunnels` table. To reach it, the prod `functions` container is also attached
to `dev_edge`.
- Dev frps publishes **7001** (tunnel ingress); its dashboard/API (7500) and all
Supabase/web ports stay internal.
## Secrets & data (gitignored, never committed)
- `*/.env`, `supabase/.env`, `redis/.env`, `stripe-stub/.env`,
`bandwidth-worker/.env`
- `frps/frps.toml` (frps dashboard password)
- `.dev-secrets.env` (generated record of all dev secrets)
- `supabase/volumes/` (edge functions, incl. dev `check-subdomain`)
- `web/` (its own git worktree on the `dev` branch of the web-app repo)
- data dirs (`redis/data`, `supabase/volumes/db/data`, ...)
Dev secrets are independent of production and are generated fresh.
## Start / stop
```sh
/docker/dev/dev.sh up # build + start the whole dev stack
/docker/dev/dev.sh down # stop the whole dev stack
/docker/dev/dev.sh ps # status of dev containers
```
The dev database starts empty; apply migrations once after first `up`:
```sh
for m in /docker/dev/supabase/migrations/000*.sql; do
docker exec -i supabase-dev-db psql -v ON_ERROR_STOP=1 -U postgres -d postgres < "$m"
done
```