7.1 KiB
7.1 KiB
Backend deploy — admin handoff
This is the list of access, environment variables, and platform decisions needed to deploy CommunityRule (the new Next.js + Postgres app in this repo) onto MEDLab's Cloudron. Hand it to the Cloudron admin; once they confirm what is checked below, the actual deploy happens in the follow-up tickets listed in §8.
1. Context
- This app replaces the old Express + MySQL backend at
CommunityRule/CommunityRuleBackend. - It is packaged as a real Cloudron app (Docker image +
CloudronManifest.json). No/app/datadrop-in. Norun.shwatchdog — Cloudron's container supervisor handles restarts. - Greenfield Postgres. No data migration from the old MySQL addon.
Old auth (4-digit OTP in
email_otp) is replaced by hashed magic-link tokens; old API andrules/version_historytables do not map to anything in the new app.
2. Access I need
Check off as granted:
- Cloudron admin login for the MEDLab instance, or "deploy app" capability scoped to one app slot.
- Container registry credentials — read/write to wherever images get pushed (Docker Hub, GHCR, MEDLab self-hosted registry — admin's choice; see §6).
- DNS — ability to add/edit a subdomain record pointing at the Cloudron host, or confirmation that admin will add the records I specify.
cloudronCLI access from my workstation (token-based; no SSH needed for normal ops).- Cloudron app log access — web UI is fine; SSH only if web logs aren't enough.
- Read access to the existing legacy app's Cloudron config so I can confirm domain / cert / SMTP setup before cutover.
3. Environment variables
Cloudron auto-injects (admin: confirm the addons are enabled)
CLOUDRON_POSTGRESQL_URL— from the postgresql addon. The app readsDATABASE_URL; bridging is a small in-app code change (see §8 ticket 1).CLOUDRON_MAIL_SMTP_SERVER/_PORT/_USERNAME/_PASSWORD— from the sendmail addon. The app readsSMTP_URL; bridged the same way.
I set manually via cloudron configure --app <id> --set-env
SESSION_SECRET— long random (openssl rand -hex 32). Required, ≥ 16 chars. Rotating it logs everyone out.SMTP_FROM— visible "From:" address on sign-in emails. Cloudron does not inject this. Recommendhello@communityrule.info(same as the old service) unless admin wants a new address.NEXT_PUBLIC_ENABLE_BACKEND_SYNC=true— turns on Postgres draft persistence for signed-in users. Recommended for production.
4. Platform settings to confirm
- Container
httpPort: 3000 (matchesDockerfileENV PORT=3000). - Health-check path:
/api/health(app/api/health/route.tsreturns200 {"ok":true,"database":"connected"}when healthy,503otherwise). - Memory limit: start at 512 MB; raise if Next.js standalone OOMs under load.
- Backups: confirm Cloudron's daily snapshot is on for both this app and its postgresql addon.
- TLS, DNS, SPF/DKIM: handled by Cloudron for the chosen subdomain — confirm.
5. Decisions I need from admin
- Subdomains for staging and production. Default proposal:
staging-app.communityrule.info+app.communityrule.info. - Sender address — reuse legacy
hello@communityrule.info, or pick a new one? - Container registry — MEDLab self-hosted, Docker Hub (under what org), or GHCR?
- Cutover overlap — how many days should the old service keep running in parallel before we uninstall it?
- Backup retention beyond Cloudron defaults? (If "defaults are fine," say so.)
6. What is intentionally NOT in this doc
So admin doesn't expect more than this scope:
- The deploy runbook itself (build / push / install / migrate / smoke / rollback) — written after access in §2 is granted; see §8 ticket 5.
- Code changes to bridge
CLOUDRON_*env vars toDATABASE_URL/SMTP_URL— I do those locally and ship the image with bridging built in; see §8 ticket 1. - Decommissioning the legacy Express/MySQL service — does not happen until the new app is green in production; see §8 ticket 6.
7. Old vs new backend deltas
So nothing surprises admin or users at cutover:
- Old addons: MySQL + sendmail. New addons: postgresql + sendmail + localstorage. Different DB addon entirely; do not reuse the old one.
- Old service ran from
/app/data/public/communityRuleBackendwith a 30-minlsof-basedrun.shwatchdog — not a packaged Cloudron app. New app is a proper Cloudron app; Cloudron supervises it. - Old auth = plaintext 4-digit OTP. New auth = magic link in email. If users report "I'm not getting a code," remind them to look for a link.
- Old code hardcoded
from: 'hello@communityrule.info'incontrollers/emailController.jsbecause Cloudron does not inject aMAIL_FROM. New app readsSMTP_FROM— see §3. - Old API surface (
/api/send_otp,/api/publish_rule, etc.) and schema (rules+version_historytables, soft-delete viadeletedcolumn) do not overlap. No data migration.
8. Follow-up tickets
All filed in Linear, titled [Backend] …, assigned to me, in the
Community-rule team, Backlog state.
- CR-96
—
[Backend] Bridge CLOUDRON_* env vars to canonical names. No admin dependency; can land now. - CR-97
—
[Backend] Container image registry: choose, build, push. Depends on registry decision (§5). - CR-98
—
[Backend] Cloudron staging install + smoke. Blocked by CR-96- CR-97; needs Cloudron CLI access + staging DNS.
- CR-99
—
[Backend] Cloudron production install + DNS cutover. Blocked by CR-98 green for the agreed overlap window. - CR-100
—
[Backend] Steady-state operator runbook. Blocked by CR-98 (we write it after we've actually done it). - CR-101
—
[Backend] Decommission legacy Express/MySQL backend. Blocked by CR-99 + sign-off window. Priority: Low.
9. Related docs
docs/guides/backend-roadmap.md§11 (environments) and §8 (Prisma migrations policy).docs/guides/backend-linear-tickets.mdTicket 12 / CR-83 — this doc satisfies it.CONTRIBUTING.md— local dev setup (Postgres, magic-link, draft sync).