Context
We currently provision PowerSync via three hand-run shell scripts in `infra/dokku/`. After Jeeves's parameterization pass (so the scripts work for any `` / `` pair), the scripts will already encode the right deployment recipe — but each new PowerSync consumer (lease-manager + two more planned products) still has to copy them and remember the order.
A proper Dokku service plugin (`dokku-powersync`) would replace the scripts with first-class commands that mirror `dokku-postgres` / `dokku-redis`:
```
dokku powersync:create
dokku powersync:set-rules < sync-rules.yaml
dokku powersync:link # auto-derives PS_SECRET_KEY_B64,
# PS_DATA_SOURCE_URI; sets POWERSYNC_URL
dokku powersync:unlink
dokku powersync:destroy
```
Why not now
We're deferring this until Jeeves has run on PowerSync in production for ~2-4 weeks. Building the abstraction before validating the underlying tech encodes assumptions we haven't tested. The scripts give us deployment ergonomics good enough to get Jeeves shipped; the plugin gets built once we have prod scar tissue to inform its design.
Trigger
Build this when product #2 is ready to adopt PowerSync. By then we'll have:
- Operational data on what config / lifecycle rough edges exist
- A second consumer to validate that the plugin's abstraction generalizes (one consumer is not enough to design an abstraction)
Design forks to settle when work begins
- Repo: separate repo (`dokku-powersync`, installable via `dokku plugin:install `) — recommended over keeping it in Jeeves's repo, otherwise lease-manager would depend on Jeeves's repo to deploy.
- Sync rules ingestion: `dokku powersync:set-rules < rules.yaml` (stdin → storage volume), explicit and Dokku-idiomatic.
- Link semantics: on `link`, derive `PS_SECRET_KEY_B64` from backend's `SECRET_KEY` and `PS_DATA_SOURCE_URI` from backend's `DATABASE_URL`; set `POWERSYNC_URL` on backend. Open question: hook into `post-config-update` to auto-rotate when backend's `SECRET_KEY` changes, or require explicit re-link?
- Image version pinning: per-instance flag (`--image 1.20.5`) with a plugin-level default.
Out of scope (for this issue)
- The Jeeves-specific PowerSync deployment itself — handled by the parameterized scripts.
- CD automation — separate concern; the plugin makes per-instance ops easier but standing up a new instance from CI is a different question.
Acceptance criteria
- `dokku-powersync` plugin installable via `dokku plugin:install` on the production host
- All four lifecycle commands (`create`, `set-rules`, `link`, `destroy`) implemented
- Jeeves's existing PowerSync deployment migrates to the plugin without downtime
- README documents installation, the four commands, and the link auto-derivation rules
Context
We currently provision PowerSync via three hand-run shell scripts in `infra/dokku/`. After Jeeves's parameterization pass (so the scripts work for any `` / `` pair), the scripts will already encode the right deployment recipe — but each new PowerSync consumer (lease-manager + two more planned products) still has to copy them and remember the order.
A proper Dokku service plugin (`dokku-powersync`) would replace the scripts with first-class commands that mirror `dokku-postgres` / `dokku-redis`:
```
dokku powersync:create
dokku powersync:set-rules < sync-rules.yaml
dokku powersync:link # auto-derives PS_SECRET_KEY_B64,
# PS_DATA_SOURCE_URI; sets POWERSYNC_URL
dokku powersync:unlink
dokku powersync:destroy
```
Why not now
We're deferring this until Jeeves has run on PowerSync in production for ~2-4 weeks. Building the abstraction before validating the underlying tech encodes assumptions we haven't tested. The scripts give us deployment ergonomics good enough to get Jeeves shipped; the plugin gets built once we have prod scar tissue to inform its design.
Trigger
Build this when product #2 is ready to adopt PowerSync. By then we'll have:
Design forks to settle when work begins
Out of scope (for this issue)
Acceptance criteria