docs(launch): execute-ready initial-deployment runbook
Locked decisions (Postgres=own, deploy dir /root/docker-compose/pn-crm, DB/Redis localhost-only), prerequisites checklist, ordered gated phases (recon -> CRM -> data -> Documenso -> website cutover), rollback anchors. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -307,3 +307,72 @@ SMTP + alert recipients stay until `WEBSITE_INQUIRY_EMAILS_DISABLED` is set.
|
||||
- residential templates plus a new contact-form alert template, hooked into
|
||||
`/api/public/website-inquiries`. New website env vars documented above. CRM
|
||||
tsc-clean + unit test added; website berth/UTM vue-tsc-clean. Nothing deployed.
|
||||
- 2026-06-02 (later): in-app notifications for website submissions + the
|
||||
structured notification-recipient resolver (emails/users/roles/everyone,
|
||||
backward-compatible) + the admin recipient-picker UI all shipped on the
|
||||
`feat/website-intake-email-ownership` branch (CRM repo). Contact-form client
|
||||
confirmation added on BOTH the website (gated by `WEBSITE_INQUIRY_EMAILS_DISABLED`)
|
||||
and the CRM (gated by `website_intake_email_enabled`). tsc-clean; full vitest
|
||||
suite (1570) green. Picker live browser-verify pending a dev server. Branch is
|
||||
4 commits ahead of `main`, not merged, not pushed.
|
||||
|
||||
---
|
||||
|
||||
## Initial Deployment Runbook — execute-ready (assembled 2026-06-02)
|
||||
|
||||
> The single ordered checklist for go-live; detailed step content is in Phase 1
|
||||
> / Phase 2 above + Initiative 5 (`launch-readiness.md`). **Guardrail stands: no
|
||||
> prod-server mutation without per-action approval; reads/recon are free.** Per
|
||||
> Matt (2026-06-02): assemble ALL inputs + the full plan before executing
|
||||
> anything, including recon.
|
||||
|
||||
### Locked decisions
|
||||
|
||||
- **CRM Postgres:** OWN — compose-default `postgres:16`, isolated `pgdata`.
|
||||
- **Deploy dir:** `/root/docker-compose/pn-crm/` (matches the other compose folders).
|
||||
- **DB/Redis exposure:** bind to `127.0.0.1` ONLY — no public ports (the Documenso
|
||||
`5432` public-exposure + brute-force lesson; the R1 port scan confirms).
|
||||
- **Initial image:** include the email-ownership work — merge
|
||||
`feat/website-intake-email-ownership` -> `main` -> push -> CI builds -> pull.
|
||||
It is all flag-OFF by default, so it ships dormant + safe. (Alternative on
|
||||
record: deploy `main` as-is, merge before the website cutover flip.)
|
||||
|
||||
### Prerequisites — gather BEFORE executing
|
||||
|
||||
| Need | For | Status |
|
||||
| -------------------------------------------------------- | ---------------------------------------- | ------------------------ |
|
||||
| SSH `stefan@45.142.177.246:22022` (key) | all recon + deploy | have |
|
||||
| prod root pass (`su`) | docker / nginx / certbot | VERIFY (creds file) |
|
||||
| Gitea registry pull token | `docker login` -> pull crm images | NEED (generate) |
|
||||
| `WEBSITE_INTAKE_SECRET` (shared) | CRM `.env` + website `CRM_INTAKE_SECRET` | generate at P1 |
|
||||
| Documenso API token + webhook secret | CRM `.env` (login `matt@portnimara.com`) | NEED |
|
||||
| MinIO creds (endpoint/key/secret/bucket) for the new CRM | CRM `.env` storage | confirm (creds §3) |
|
||||
| Legacy MinIO read creds | EOI backfill (D2) | NEED |
|
||||
| Website-server root pass | Phase 4 env wiring | you provide at that step |
|
||||
| Maintenance window | Documenso restart | schedule |
|
||||
|
||||
### Ordered steps (each gated)
|
||||
|
||||
- **Phase 0 [recon]** R1 port scan (external + internal listeners) · R2 NocoDB +
|
||||
Documenso drift vs the 2026-06-01 pull · R3 fresh read-only Documenso `pg_dump`
|
||||
-> re-run the `1.13.1->2.11.0` clone dry-run (final "won't break" check).
|
||||
- **Phase 1 [APPROVAL]** P1 prod `.env` -> P2 `/root/docker-compose/pn-crm`
|
||||
(localhost-bound DB/Redis) -> P3 nginx (HTTP-first) -> P4
|
||||
`certbot --nginx -d crm.portnimara.com` -> P5 `docker login` + pull + up -> P6
|
||||
schema + seed port/admin -> P7 verify (health, login, berths, socket.io).
|
||||
- **Phase 2 [APPROVAL]** D1 load migrated data -> D2 MinIO EOI backfill -> D3
|
||||
reconcile counts.
|
||||
- **Phase 3 [APPROVAL · VITAL · together]** backups (pg_dump + cold volume
|
||||
snapshot + cert + MinIO inventory, off-box) -> staged `1.13.1->2.0.0->2.11.0`
|
||||
-> verify (login, existing envelope renders, test send, webhook reaches CRM,
|
||||
CRM stays on v1 API) -> rollback ready.
|
||||
- **Phase 4 [APPROVAL]** website env wiring on the other server -> cutover flips
|
||||
(`CRM_INTAKE_URL`/`SECRET` on; then `website_intake_email_enabled` ON +
|
||||
`WEBSITE_INQUIRY_EMAILS_DISABLED=1`; then `CRM_BERTHS_ENABLED=1`).
|
||||
|
||||
### Rollback anchors
|
||||
|
||||
- CRM: `docker compose -f docker-compose.prod.yml down` — the pn-crm stack is
|
||||
isolated (own Postgres), zero impact on the other apps on the box.
|
||||
- Documenso: revert the image tag + restore the cold volume snapshot / pg_dump.
|
||||
- Website: unset the `CRM_*` env vars -> instant revert to NocoDB + website email.
|
||||
|
||||
Reference in New Issue
Block a user