- /docker/backup: borgmatic container (daily 03:00 Berlin via BACKUP_CRON) - Backs up /docker (ro) to local encrypted repo /var/backups/borg (repokey-blake2) - Postgres prod+dev captured via pg_dumpall; live PG data/logs/build artifacts excluded - Retention: keep_daily 7, keep_weekly 4, keep_monthly 6; runs prune/compact/create/check - Secrets in backup/.env (gitignored, chmod 600)
96 lines
5.1 KiB
Markdown
96 lines
5.1 KiB
Markdown
# /docker — linumiq.net remote access stack
|
|
|
|
## Networks
|
|
Shared external docker network: `edge` (created with `docker network create edge`).
|
|
|
|
## Shared env
|
|
`/docker/.env` — DOMAIN, LE_EMAIL.
|
|
|
|
## Per-service secrets
|
|
`/docker/<svc>/.env`, all `chmod 600`, owned `root:root`. See `/docker/SECRETS.md`
|
|
for the inventory.
|
|
|
|
## Service inventory (Wave A + Wave B)
|
|
|
|
| Service | Compose dir | Container name | Listens | Image |
|
|
|-------------------|------------------------------|--------------------------|----------------------------------|--------------------------------------|
|
|
| Supabase stack | /docker/supabase | supabase-* | kong :8000, edge :9000 (internal)| supabase/* (pinned per compose) |
|
|
| Caddy | /docker/caddy | caddy | :80, :443 | caddy:2.10.2-alpine |
|
|
| frps | /docker/frps | frps | :7000 ctrl, :7080 vhost, :7500 dash | snowdreamtech/frps:0.65.0 |
|
|
| Redis | /docker/redis | redis | :6379 (edge net only) | redis:7.2-alpine |
|
|
| stripe-stub | /docker/stripe-stub | stripe-stub | 127.0.0.1:4242 | stripe-stub:1.0.0 (local build) |
|
|
| bandwidth-worker | /docker/bandwidth-worker | bandwidth-worker | (no inbound) | bandwidth-worker:1.0.0 (local build) |
|
|
|
|
## Start order
|
|
1. `cd /docker/redis && docker compose --env-file .env up -d`
|
|
2. `cd /docker/supabase && docker compose up -d`
|
|
3. `cd /docker/frps && docker compose up -d`
|
|
4. `cd /docker/caddy && docker compose up -d`
|
|
5. `cd /docker/stripe-stub && docker compose up -d`
|
|
6. `cd /docker/bandwidth-worker && docker compose up -d`
|
|
7. (later) `cd /docker/web && docker compose up -d`
|
|
|
|
## Stop order
|
|
Reverse of the above. `docker compose down` per directory.
|
|
|
|
## Edge functions
|
|
Mounted from `/docker/supabase/volumes/functions/`. The `main` function is a
|
|
router that reads the first URL path segment as the function name.
|
|
- Via Kong: `POST http://127.0.0.1:8000/functions/v1/<name>`
|
|
- Direct (intra-`edge` network, e.g. frps auth plugin):
|
|
`POST http://supabase-edge-functions:9000/<name>`
|
|
|
|
After editing a function, `cd /docker/supabase && docker compose restart functions`
|
|
(or `up -d functions` if env changed).
|
|
|
|
## Wave B specifics
|
|
- `frps.toml` enables `[[httpPlugins]] name="auth"` pointing at
|
|
`http://supabase-edge-functions:9000/auth-webhook`.
|
|
- `supabase-edge-functions` reads `REDIS_URL` from `/docker/supabase/.env`.
|
|
- bandwidth-worker polls `http://frps:7500/api/proxy/http` every 60s; deltas go
|
|
to `public.usage_samples` and `public.tunnels.bytes_used` via PostgREST.
|
|
|
|
## Backups
|
|
|
|
Daily encrypted backups via **borgmatic** (`/docker/backup`).
|
|
|
|
| Service | Compose dir | Container | Schedule | Image |
|
|
|-----------|-----------------|-----------|---------------------|------------------------------------------------|
|
|
| borgmatic | /docker/backup | borgmatic | daily 03:00 (Berlin)| ghcr.io/borgmatic-collective/borgmatic:latest |
|
|
|
|
- **Source:** `/docker` (mounted read-only). **Repository:** `/var/backups/borg`
|
|
(local host disk for v1; remote planned later). **Encryption:** repokey-blake2.
|
|
- **Databases:** prod (`supabase-db`) + dev (`supabase-dev-db`) captured via
|
|
`pg_dumpall` (roles + all DBs), streamed into the archive. The container is
|
|
attached to `supabase_default` + `supabase-dev_default` to reach them.
|
|
- **Excluded:** live PG data dirs (`supabase/volumes/db/data`), logs,
|
|
`caddy/.../autosave.json`, `.remediation-backup`, `node_modules`, `.next`.
|
|
- **Retention:** keep_daily 7, keep_weekly 4, keep_monthly 6.
|
|
- **Schedule:** built-in cron via `BACKUP_CRON` env (`0 3 * * *`), running
|
|
`borgmatic --stats -v 0` (default action set: prune, compact, create, check).
|
|
- **Secrets:** `/docker/backup/.env` (chmod 600, gitignored) holds
|
|
`POSTGRES_PASSWORD_PROD`, `POSTGRES_PASSWORD_DEV`, `BORG_PASSPHRASE`.
|
|
**Store `BORG_PASSPHRASE` offsite — losing it makes the repo unrecoverable.**
|
|
|
|
### Operations
|
|
|
|
```sh
|
|
cd /docker/backup
|
|
docker compose up -d # start the scheduler
|
|
docker compose run --rm --entrypoint borgmatic borgmatic list # archives
|
|
docker compose run --rm --entrypoint borgmatic borgmatic create --stats # manual backup
|
|
docker compose run --rm --entrypoint borgmatic borgmatic check # verify integrity
|
|
```
|
|
|
|
Restore a database dump:
|
|
|
|
```sh
|
|
cd /docker/backup
|
|
ARCH=$(docker compose run --rm --entrypoint borgmatic borgmatic list --json \
|
|
| python3 -c "import sys,json;print(json.load(sys.stdin)[0][\"archives\"][-1][\"archive\"])")
|
|
docker compose run --rm -v /tmp/restore:/restore --workdir /restore \
|
|
--entrypoint borgmatic borgmatic extract --archive "$ARCH" \
|
|
--path "borgmatic/postgresql_databases/supabase-db:5432/all"
|
|
# then: psql -U postgres -f /tmp/restore/borgmatic/postgresql_databases/supabase-db:5432/all
|
|
```
|