feat(web-arm): self-host PowerSync Service for Cloonar fit #87
No reviewers
Labels
No labels
bug
enhancement
in-progress
needs-info
needs-triage
p0
ready-for-agent
ready-for-human
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/nixos!87
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "afk/38"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Retires PowerSync Cloud for the Cloonar fit app by self-hosting
journeyapps/powersync-serviceon web-arm as a podman oci-container, in thesame shape as collabora.nix / rustdesk.nix. Implements #38 (the #37 operator
prereqs are done — the
reptide-powersync-source-dsnsecret is in place).New self-contained module
hosts/web-arm/modules/powersync/:1.21.0@sha256:66e7d37…), onthe v6egress network so it can reach the Supabase direct (IPv6-only)
endpoint; ordered after
init-v6egress-network.service.reptide-powersync-source-dsn,injected as
PS_SOURCE_DSNvia a sops template),verify-fullTLS (PowerSyncbundles Supabase's CA), slot prefix
powersync_selfhost.powersync_storageDB/role on the local PG14, addedto
services.postgresqlBackup.powersync.reptide.eu(lego DNS-01 via the fueltide token,forceSSL, proxyWebsockets, 3600s timeouts); 8080 bound to
127.0.0.1only./probes/liveness(the open-slot WAL-bloat guard).utils/pkgs/powersync-service/update.shto bump the digest pin (1-line diff).shared_buffers80MB → 512MB (restarts PG on apply, briefly interruptingevery PG-using service).
Sync rules copied byte-for-byte from #37 into
modules/powersync/sync-rules.yaml.Notable deviations from the issue spec (forced by PowerSync)
Postgres layer supports neither — it connects over TCP, rejects ports < 1024,
and throws on an empty password. So storage uses a TCP connection over the
v6egress bridge gateway (
10.89.0.1), authorised by apg_hbatrust rulescoped to exactly the
powersync_storagedb+role from the v6egress subnet(5432 stays closed to the internet). The URI password is a non-secret
placeholder. This needed
enableTCPIP+ a scoped iptables allow. Hardening toa generated-password +
scramrule is a noted follow-up in ADR-0012.slot_name_prefix, notslot_name, so the live Supabaseslot is
powersync_selfhost<suffix>— verify with… WHERE slot_name LIKE 'powersync_selfhost%'.(list-merge) rather than editing
blackbox-exporter.nix, to keep the moduleself-contained.
Verification
Operator functional checks after deploy (per #38):
systemctl status podman-powersyncactive; journal shows replication start +slot creation without errors.
curl -sf https://powersync.reptide.eu/probes/liveness→ 200, valid cert.powersync_selfhost%replication slot is active.sslmodetoverify-cawith the Supabase CA (
PS_PG_CA_CERT).reptide-powersync-source-dsnholds the raw direct DSN (noreplication=database).Closes #38
Landed via
/land-pr. Verdict: PASS.Signal relied on: the repo's commit-time pre-commit dry-build (eval-only; the PR body attests "web-arm OK / all hosts OK"), supplemented by static review of what that gate can't see.
Checked:
afk/38commit,Closes #38present, nosecrets.yaml/stateVersionchange, module imported by explicit path,update.shpresent.10.89.0.1:5432and the firewall10.89.0.0/24both matchv6egress.nix's--subnet=10.89.0.0/24;blacklistDomains, thehttp_200_finalblackbox module, andvictoriametrics.extraScrapeConfigsall exist; both sops keys are present inhosts/web-arm/secrets.yaml; the image is a runtime OCI digest pin (no vendorHash-class build risk).truststorage vs. the spec's unix-socket/passwordless,slot_name_prefixvs.slot_name, the added v6egress-scoped firewall rule, ADR renumber 0007→0012.Runtime-only, deferred to #38's post-deploy checklist (no static gate can prove these): the Supabase replication handshake, the v6 egress path, JWT verification, the lego cert, and the
start -r unifiedinvocation. PG-on-TCP behind a subnet-scopedtrustrule is a conscious tradeoff, with scram hardening noted as an ADR-0012 follow-up.Merging with
--style merge; CD (deploy action → SFTP chroot →bento-upgradenixos-rebuild switchwithin ~5 min) takes it from here.