Deployment view
The frontend, Express API, worker, and PostgreSQL database stay logically separate even when a hosting plan places more than one of them on the same machine. Sharing a machine is an operational choice. Sharing a database credential with the public Next.js runtime is not allowed.
Webhook routes on Express are the only API routes that must be reachable from Stripe. Browser traffic reaches Next.js. Next.js calls Express with the access token. Customer browsers do not receive DATABASE_URL or the storage secret.
Confirmation required before placement
ScalaHosting is the named host. Assign a process to a plan only after that plan is confirmed to support the row.
| Capability | Needed by | Confirm |
|---|---|---|
| Node.js 20 or newer | Next.js, Express, worker | Runtime version and process manager. |
| More than one long-running Node process | API and worker beside the site | Supervisor, systemd, or the panel equivalent. |
| PostgreSQL 15 or newer | All business data | Major version, TLS, and a private network path. |
| Private S3-compatible bucket, or a disk that is not under the web root | Originals and thumbnails | The bucket or directory cannot be fetched by URL. |
| HTTPS certificate | Public site, API webhooks, docs | Certificate renewal. |
| Outbound HTTPS | Stripe, email, storage | Egress allowed from the API and worker. |
| Backup target | PostgreSQL and object storage | Where dumps and object versions are stored. |
If the plan can run only one Node process, do not fold the worker's secrets into the marketing site. Run Express and the worker as separate OS processes on a host that can do that, and keep Next.js as the public application. The logical diagram above still holds.
Network rules
- PostgreSQL accepts connections from the API and the worker only.
- The database role used by the application is not a superuser. Migrations use a separate role.
- Object storage blocks public
GetObject. Access is a signed URL issued by the API after the gallery check. - Webhook endpoints accept POST from Stripe and verify the signature. They do not accept an access token as proof of payment.
- The documentation site is static. It has no database credential.
Production host names are set when the ScalaHosting layout is chosen. This design uses placeholders until then. The checklist and the infrastructure page are the decision record.