Web · Infrastructure
A containerised Next.js + Payload CMS template with automatic SSL, shared Postgres, off-site backups and a documented restore path.
Client catalog sites share about ninety percent of their requirements and differ in the last ten. Building each one from scratch wastes the ninety; running each on its own server wastes the hosting. I built a template that treats a new client as a deployment, not a project.
Every new catalog client meant repeating the same work: provisioning, TLS certificates, a database, an admin panel, image hosting, backups. Done by hand, that is a day of setup per client and a growing number of one-off servers to remember.
It also does not degrade gracefully. Three bespoke deployments means three different things to debug at 2 a.m., and no confidence that any of them can actually be restored.
The boundaries that shaped every decision that followed.
Small clients cannot justify a server each. Multiple tenants had to be isolated from one another while sharing hardware and a Postgres instance.
Clients update their own catalogs. That requires a real CMS with media handling, not a repository they file pull requests against.
Backups that have never been restored are not backups. The restore path had to be scripted and documented, not improvised.
A single containerised Next.js 14 and Payload CMS 3 application serves as the template. Each client is a container built from it with its own configuration and its own database inside a shared Postgres — isolated data, shared hardware.
Traefik routes by hostname and issues Let's Encrypt certificates automatically. Adding a domain means adding a label, not editing nginx configuration and remembering to renew a certificate in ninety days.
A new client is a scripted operation: create the database, generate configuration, build and deploy. Deployment and updates are the same — the process that puts a client live is the process that updates them, so it gets exercised constantly.
Uploads go to Cloudflare R2 rather than local disk. Containers stay stateless and disposable, and image storage scales independently of the VPS.
Databases back up daily to R2, off the machine they came from. Restore is a documented script, and the recovery procedure is written down alongside deployment and troubleshooting runbooks — so recovery does not depend on whoever remembers the most.
Watchtower handles container updates and Uptime Kuma watches every tenant, so a site going down is something I find out about before the client does.
Tell me what you are building and where it is stuck. I will tell you honestly whether I am the right person for it — and roughly what it would take.
Mobile · Android release
A Flutter learning app with stroke-order grading, spaced repetition, AdMob and Google Play Billing 8 — running entirely on-device.
Automation · AI tooling
A resumable Python pipeline that produced 68 style-matched illustrations on local hardware — averaging 9 KB each, with the licensing actually checked.