SoConnective

Operations

Deployment & Operations

Overview

SoConnective is self-hosted on a VPS. Orchestration is handled by Coolify behind Traefik, with git hosted on Forgejo. Deploys are push-driven: pushing to the repo triggers a build and release. This page covers how that pipeline works and the runtime posture of the apps. Detailed infrastructure runbooks live under infra/runbooks/ and are referenced — not duplicated — here.

The apps

AppStackRole in production
apps/cmsPayload CMS 3.85 · Postgres (payload schema) · multi-tenant pluginAPI, auth, data, hooks, the engine
apps/crmNext.js 16 · React 19 · Tailwind v4 · shadcnThe agency/sub-account UI
apps/docsThis documentation siteProduct & security docs

The CRM communicates with the CMS over the Payload REST API at PAYLOAD_URL; sessions are carried by the httpOnly fs_session cookie, forwarded to the CMS as a JWT.

How deploys work

  1. Push to git (Forgejo). A push to the tracked branch is the trigger — there is no separate manual release step for routine deploys.
  2. Coolify builds with nixpacks. Coolify picks up the change and builds the affected app(s) using nixpacks, producing the runtime image.
  3. Traefik routes the release. Once healthy, the new release is served behind Traefik.

Migrations on deploy

The CMS applies Payload migrations on deploy. Schema changes ship as committed migrations and run as part of the release, so the database schema moves forward in lockstep with the code.

Migrations are additive, which keeps deploys safe to roll out and avoids destructive schema changes during a routine push. (Operations that are intentionally not part of a routine push — such as the RLS runtime cutover — are handled as documented maintenance-window steps; see ADR 0011 — RLS cutover runbook.)

Redis

Redis (the fs-cache service) backs runtime concerns that need fast, shared, ephemeral state:

  • Caching
  • Rate-limiting
  • Metering

Media volume

Media uploads persist on a Docker volume, so uploaded files survive container rebuilds and redeploys. The volume is the durable store for media — application containers are replaceable; the media volume is not.

Environment & secrets posture

Secrets never live in the repo or in the documentation. They are provided as environment variables and managed through the deployment platform. Notable server-only values:

  • DATABASE_URI — the Postgres connection. The app currently connects as a superuser; the planned RLS cutover repoints this at the non-superuser app_user role (see ADR 0009 — Row-Level Security).
  • PAYLOAD_SERVICE_KEY — the server-only Payload API key used for privileged, unauthenticated invite operations and audit-log writes. It never reaches the browser.
  • PAYLOAD_URL — the base URL the CRM uses to reach the CMS REST API.

The stack is also de-identified at the edge: the session cookie is the neutral fs_session, X-Powered-By is disabled, and baseline security headers are set. See the security model for the full posture.

Runbooks

Step-by-step operational procedures — provisioning, recovery, the RLS cutover, and related maintenance — are maintained as runbooks under infra/runbooks/. This page is the orientation; the runbooks are the authoritative procedures.

Previous
Runbook 04 — Platform CMS deployment (Payload)