Public: anyone can read this; the crew can change it.

Platform app move gap: Postgres apps have no home on the forge #11709

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

mason/forge:mason/11698-platform-app-move-gap-postgres-apps-have → main 1 commit fork

  • Merged. mason/11698-platform-app-move-gap-postgres-apps-have was merged into main as 9f7edea.

Review

Sign in to review this change.
3 files changed +31 −2
docs/APPS.md +27
@@ -1884,6 +1884,33 @@ by the hour.
18841884
18851885 ## What is deliberately not here
18861886
1887 **A managed Postgres per app.** Decided (#11698): the forge does not run
1888 one. An app's state is `bun:sqlite` under `FORGE_APP_DATA` because that is
1889 what makes production data, preview data, backup and restore one directory
1890 each, with no second process to run, secure, upgrade or restore. A managed
1891 Postgres would add a server, credentials per app, a network path out of the
1892 cell and a backup of its own, for apps that are one process on one box. The
1893 way for a Postgres app is a documented port, in this order:
1894
1895 1. **Port to `bun:sqlite`** (the default). Keep the schema's tables and
1896 constraints, replace Postgres-only types (`jsonb` becomes `TEXT` with
1897 `json_*`, `timestamptz` an ISO-8601 or epoch `INTEGER`, `serial` an
1898 `INTEGER PRIMARY KEY`, arrays a child table), move queries behind one
1899 module, and prove it with characterization tests run on both sides before
1900 the switch. Load the dump through a script that reads the `pg_dump --data-only
1901 --inserts` output and compares per-table counts and checksums.
1902 2. **Keep an external Postgres** only when the port is not worth it
1903 (extensions such as PostGIS, data too large for one file). Declare its
1904 host in `forge.json` `egress`; the connection string is an app secret set
1905 by name in the app's settings, never in the repository. A preview then
1906 shares or lacks that database: point previews at a scratch database, never
1907 at production. The forge does not back it up; its owner does.
1908
1909 Writes are single-process and WAL mode carries the release overlap, so an app
1910 that needs many writers across machines is the case for option 2, not a
1911 reason to build a database service into the forge. If many apps hit option 2,
1912 reopen this with the count.
1913
18871914 Containers. A cell (rule 9) is namespaces and a watch, not an image: an
18881915 app runs the machine's own `bun` and tools, read-only, and its limits are
18891916 enforced by stopping it, not by throttling it — a container cannot create
docs/EXTRACT.md +2 −1
@@ -105,7 +105,8 @@ https://forge.example/trevato/forge.git main && systemctl restart forge`
105105 forge.
106106 - **Postgres and object storage per app.** Forge apps keep SQLite under
107107 `FORGE_APP_DATA`; an app that needs a bucket needs the forge to hand it
108 one, which it does not yet.
108 one, which it does not yet. Postgres is decided against: see
109 `APPS.md`, "What is deliberately not here".
109110 - **Dashboards.** No Prometheus, no Grafana. The forge's own pages —
110111 Crew, the audit, the ledger — are the observability it has; a
111112 `/metrics` for the forge itself is a small addition if wanted.
docs/features/platform-app-move.md +2 −1
@@ -23,6 +23,7 @@ Write the answers in the migration issue; names of secrets, never values.
2323 `forge.json` says, and declare `schedules` for its jobs.
2424 The forge's store is `bun:sqlite`; a Postgres app is ported (the crew's work)
2525 or keeps an external Postgres reached by an egress entry. The pull says which.
26 The decision and both paths are in docs/APPS.md, "What is deliberately not here".
2627
2728 ## 3. Copy the data (person runs, crew writes the script)
2829 Dump with `pg_dump`, load, then compare per-table row counts and a per-table
@@ -50,7 +51,7 @@ counts. The old copy stays until that has passed.
5051
5152 ## What the forge lacks (each is an issue)
5253 - A database import for an app (`migrate` has no data path): upload a dump, load it, report counts and checksums. (#11697)
53 - A Postgres app has no home here: no managed Postgres, only per-app `bun:sqlite`. (#11698)
54 - ~~A Postgres app has no home here.~~ Decided, not built: no managed Postgres; port to `bun:sqlite` or keep an external one by `egress` (docs/APPS.md). (#11698)
5455 - A file and upload copy with a manifest compared on both ends. (#11699)
5556 - A custom domain for an app with certificate issuance, and a one-step revert of it. (#11700)
5657 - Per-app encrypted backup with a restore proof (`docs/features/backup-truth.md` covers the forge's own, not an app's). (#11701)

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs