Choosing a deployment
The server is one application, packaged four ways. They run the same binary and
read the same CLOUDPDF_* configuration, so the
choice is purely about how you want to operate it — not what it can do.
| Method | Best for | Typical database | Typical storage | Scaling |
|---|---|---|---|---|
| Node / npm | Local dev, existing Node platforms, custom hosts | SQLite or Postgres | Disk or cloud | Manual |
| Docker | Single host, simple self-hosting, CI | SQLite or Postgres | Disk or cloud | Manual / your orchestrator |
| Docker Compose | A full self-hosted stack on one box | Postgres (included) | MinIO / S3 (included) | A few replicas, one host |
| Helm / Kubernetes | Production, startup → enterprise | Postgres (managed) | S3 / GCS / Azure (managed) | Autoscaling, multi-replica, HA |
You can always start small and grow. Because storage is configured, not compiled in, moving from SQLite + disk to Postgres + S3 — or from Docker to Kubernetes — is a configuration change, not a rewrite.
A quick decision guide#
- Just exploring, or developing locally? Use npm or the Quick start Docker one-liner.
- Self-hosting on a single server or VM? Use Docker for the server alone, or Docker Compose for the server plus Postgres and object storage in one file.
- Running in production, or need high availability? Use Helm. You get multiple replicas, autoscaling, managed schema migrations, and a clean separation of secrets — the things that matter when downtime is expensive.
What every method needs#
No matter how you deploy, the server needs:
- A signing secret —
CLOUDPDF_JWT_SECRET, shared with the backend that mints tokens. See Authentication. - A database — SQLite (default) or Postgres. See Database.
- An object store — local disk (default) or a cloud bucket. See Storage.
- Persistent volumes for
/datawhen you use SQLite, local storage, or the local cache.
For anything customer-facing: set
CLOUDPDF_ENGINE_ISOLATION=host so a native PDF crash costs a
sub-second engine respawn instead of the instance, and run more
than one replica (Compose or Helm) so a single failure can’t take
you offline. Details in
Health & scaling.