Guides

Storage and backups

Run stateful apps on nyxory — durable volumes you roll out in one manifest, and a backup/restore engine that snapshots any app on demand.

nyxory runs stateful software, not just stateless web tiers. A database, an upload directory, a queue — anything that has to keep its data across restarts gets a persistent volume, and on top of that a backup and restore engine that snapshots a whole app on demand and rolls it back in three modes. Both are first-class: your agent provisions them from a manifest, and you drive backups from the console or over MCP. Most stateless workloads need nothing here — reach for this the moment an app has data it can’t afford to lose.

Persistent volumes

A container’s own filesystem is scratch space — restart or reschedule the pod and anything not on a volume is gone. Durable storage is a PersistentVolumeClaim mounted at the app’s real data directory: your agent adds it to the Deployment and nyxory provisions backing storage from your project’s pool. That’s the whole setup — a database that survives redeploys is one PVC away.

The default shape is a single-replica Deployment plus one PVC — simple, and the PVC is a normal owned object that lives and dies with clear rules. When you need stable per-pod identity and DNS — replication, clustering — reach for a StatefulSet with a headless Service (clusterIP: None) and per-pod storage via volumeClaimTemplates.

Getting it right on first init:

  • Size from 10 GB up. A LimitRange enforces a 10 Gi minimum per PVC, and a PVC can be grown later but never shrunk — so start at what the data actually needs.
  • Point databases at a subdirectory. A fresh PVC already contains a lost+found directory, and the official database images (Postgres, MariaDB, MySQL, MongoDB, Elasticsearch) refuse to initialize into a non-empty directory. Aim the data path at a subfolder of the mount — PGDATA=/var/lib/postgresql/data/pgdata, or a subPath on the mount. This only matters on the very first boot.
  • Storage today is single-node (RWO). A customer app PVC is ReadWriteOnce — it binds to one node — so a PVC-backed pod stays at one replica by design; you scale it out through a StatefulSet with app-level replication, not a bigger replicas number. The full picture, and how to scale the stateless tiers freely, is in Scaling and RAM.

Deleting an app cascades through everything it owns, but PVCs are deliberately kept — “app deleted” never means “data thrown away.” After a teardown you free storage explicitly: kubectl get pvc -l app.kubernetes.io/instance=<app>, then delete what you no longer need; a leftover PVC still counts against your pool on the next deploy.

Backups and restore

Every app can be backed up on demand — a point-in-time, crash-consistent capture of its volumes (CSI snapshots), plus its manifests and the exact image it was running. Take one before a risky migration, on a release, or any time you want a known-good point to return to. Each backup lands against your plan’s keep-N slots — three on the free tier, more on paid plans — with its trigger, size, phase, and image on the record.

Drive it from whichever surface fits: the console’s Backups tab, point-and-click, or your coding agent over MCP — nyx_backup_create to take one, nyx_backup_list to see them.

Restore runs through nyx_restore (or the console) in one of three modes:

  • data — roll the volumes back in place, app definition untouched.
  • app — roll the image and definition back, data left as-is.
  • full — the whole app, and it works even after the app was deleted.

Restore is safe by construction: it takes an automatic safety backup before it touches anything, and it pauses auto-deploy for app and full restores so a push can’t race the rollback.

Coming: unattended schedules. The engine can also run backups for you on a nightly cadence — that automation is built and rolling out behind a flag while the on-demand path soaks. Until it’s on by default, schedule your own with a CronJob (a nightly dump to your bucket is the classic shape — see Jobs and CronJobs).

Object storage

For blobs — uploads, media, static assets, backup targets — nyxory’s model is bring your own bucket, and it’s a deliberate one: the platform gives you compute, persistent volumes, and ingress, and stays out of the managed-blob-store business so you’re never locked to ours. Wire any S3-compatible endpoint — AWS S3, Cloudflare R2, GCS, Backblaze B2 — as a secret scoped to the project or a single app, consumed via envFrom. One secret, and every language’s S3 client just works. Never bake keys into an image or ConfigMap.

Self-hosting MinIO as an app is possible if you want an in-cluster bucket, but it’s opt-in, not a default — it’s a stateful pod with its own PVC drawing from your storage pool, and its backups are then yours to run.

Export your data

Your data is yours, and you can take it out yourself. From an app’s page in the console, Export snapshots the volume, moves it to object storage, and hands back a time-limited download link — a self-service action, no ticket, no negotiation. Manifests and secrets export the same way, so nothing about your project is locked in. It’s available from Builder plans up.

Ask any AI about nyxory