Volumes
The root filesystem of a Lucity service is ephemeral, and should only be used for temporary files you do not mind losing on the next deploy.
A volume is a disk that outlives the container, and the place to put data you want to keep. It is worth knowing that your application might never need one, because volumes come with limitations that the alternatives do not have. Uploads belong in a bucket and data belongs in a database, both of which any number of instances can reach at once. Reach for a volume when something insists on a real filesystem. Typical examples are self-hosted software with a data directory, a search index it rebuilds on disk, or a database you are running yourself.
Creating and mounting
On the project canvas, click Create and choose Volume. Give it a name between 2 and 16 characters and a size, and it is ready immediately.
A freshly created volume is unmounted. Open it, and under Settings → Mount, pick the service and the path to mount it at. The path is where your application expects to find its data, /var/lib/ghost/content or /data or wherever the software in question insists on. Mounting takes effect immediately and needs no rebuild, like any other configuration change. It restarts the service so the disk is there when it starts.
Unmounting detaches the disk and restarts the service again. Your data stays on the volume, so you can mount it somewhere else, or back on the same service, later.
A volume and the service it mounts into must be in the same environment.
One volume, one service
A volume is a single disk, and a disk can only be attached to one machine at a time. This means volumes can only be attached to services with a single replica.
That is why we generally recommend keeping your application stateless, writing its state into a database, a key-value store or an object storage bucket instead.
Rollout downtime
Since a volume can only be attached to one instance at a time, services with a mounted volume have a short downtime window on every deploy. The old instance has to release the disk before the new one can claim it, so the service stops and starts again instead of handing over.
Plan for it the way you would plan a restart. It is usually a few seconds, and it is the price of keeping state on a disk rather than in a database or a bucket.
Size
Volumes run from 10 GB up to 1 TB. You can add space at any time under Settings → Storage, and the disk grows in place while the service keeps running.
Storage can never be made smaller. Moving to a smaller disk means creating a second volume, copying the data across, and pointing the service at the new one.
The Usage tab charts how much of the volume is actually in use over time, which is what to check before deciding you need more.
File ownership
For services created from an image, the run-as user set under Settings → Run as user also becomes the owner of the mounted volume. That is usually what you need for an image that runs as a non-root user and expects to write to its own data directory.
What's not there yet
Volumes are not backed up. There are no snapshots and no retention window, and deleting a volume deletes its contents for good. If a volume holds something you cannot lose, copy it somewhere else on a schedule: a periodic dump into a bucket from inside the service is the usual answer, and it produces something you can actually restore from.
Under the hood
A volume is a PersistentVolumeClaim in your environment's namespace, mounted into the service's pod at the path you chose. That is why the constraints look the way they do: a single-writer disk, attached to one pod, expandable but not shrinkable. An ejected project keeps its volumes exactly as they are.
Next steps
- Services for what mounting a volume does to a service
- Object storage for files that do not need a filesystem
- PostgreSQL for data that belongs in a database