Volumes
A volume is a persistent storage device that keeps data across restarts and even redeployments.
Typical workflow
Creating a persistent volume
You can create an instance with attached volumes in a single API operation. This ties the volumes' lifetimes to the instance - when you delete the instance, the volumes disappear. This use case is still valid, because an instance with no volumes attached will write all its files into RAM and eventually exhaust its memory.
To start, create the volume with the CLI, with size 100 MiB and name my-volume:
You can list the volume with:
The volume is in available state because it isn't attached to any instance yet.
It's also marked as persistent because it will persist even after instance deletion.
Importing local data
To populate an empty volume with local data, use the CLI import subcommand.
For example, assuming the data you want to import is in your my-data directory, you would run:
You should see output like:
Creating an instance
Start from this guide to create a simple Flask web server:
Code
Replace the contents of server.py with:
server.py
On every request, this simple server will write a timestamp to a file on the mounted persistent volume and print out the current contents of the file.
Build and deploy the Flask web server and mount the my-volume volume at /mnt:
You should see output like:
To confirm that the platform attached the volume, run:
You should see output like:
Testing
The Flask server writes the time and date to /mnt/log.txt for each request.
Test it by running curl several times.
Example output:
Code
To test data persistence, you can stop the instance, then detach the volume from the instance:
You should see that the volume is now available again.
While the instance is stopped, the volume is still attached to it, but not mounted.
Mounting of an attached volume happens automatically when the instance starts.
This is different from a snapshotted instance, which is in standby state and has its volumes still mounted.
If you try to detach a volume while the instance is running, the platform will queue the operation.
The detach operation will trigger when the instance goes into stopped.
Now start another instance:
This should output something like:
Attach the volume to the new instance:
Run one final curl to this new address.
You should see the previous contents plus a new entry at the bottom:
Code
Cleaning up
To clean up, first detach the volume from all instances and then remove it:
If the instance is already in stopped state, the detach operation will trigger immediately.
Otherwise, the platform will queue it and trigger when the instance fully stops.
Do not confuse a stopped instance with a snapshotted instance, which is in standby state and has its volumes still mounted.
Warm-plug volume operations
The platform supports warm-plug volume operations. This lets you attach volumes in more lifecycle states than before, but with important timing constraints.
What's supported
- You can attach a volume to an instance created from a snapshot (for example, from a template).
- You can attach a volume to an instance that's currently
running.
Current behavior and limitations
- Attaching to a
runninginstance isn't applied instantly. - The platform schedules the attach operation and completes it on the next scale-to-zero cycle.
- This is warm-plug support, not full hot-plug support.
- Detaching a volume still requires the instance to be fully shut down (not only scaled to zero).
- If you request detach while the instance isn't yet shut down, the platform schedules the update and applies it automatically once shutdown happens.
API usage note
For now, volume attach and detach updates are available through dedicated endpoints:
/v1/volumes/attach/v1/volumes/detach
You can invoke these endpoints via the CLI using unikraft volumes attach and unikraft volumes detach.
The instance PATCH endpoint doesn't currently support volume operations.
Volume templates
A volume template is a volume that you can use as a base to create new volumes with the same data. When you create a volume template, the platform converts the source volume to a template.
Once a volume transitions to template state, it's immutable: you can clone it but not write to it or delete it while active clones exist.
Volume templates have their own create, read, update, and delete endpoints at /volumes/templates.
They support delete locks and tags.
Volume templates are useful because you can clone them.
You can create volume templates from existing volumes using the CLI as well:
You can list all volume templates with:
The platform converts attached volumes to templates automatically when you convert an instance into an instance template.
Volume cloning
A volume clone is an independent copy of an existing volume.
The clone operation is asynchronous: the platform creates the new volume immediately in a pending state, and the data copy completes in the background.
To clone one or more volumes, you can use the POST /volumes/clone endpoint.
You can also use the unikraft CLI to clone a volume:
unikraft
unikraft
The platform clones volumes implicitly when you clone an instance or create one from a template. It clones each attached volume and attaches the clone to the new instance.
You can't delete a source volume while it has active clones.
You can't clone a volume template.
Filesystems
By default, volumes are block devices with ext4 filesystem.
There's also a virtiofs filesystem option, which is a shared filesystem that allows more than one instance to read and write the same volume simultaneously.
To specify the filesystem, use the filesystem field when creating a volume with POST /volumes:
POST /volumes
You can also use the unikraft CLI:
unikraft
For BYOC or on-prem Unikraft Cloud installations, you can configure custom filesystems that can be backed by other media, such as S3 or network storage.
Custom filesystem drivers support lifecycle hooks for format, fscheck, mount, unmount, and delete, so operators can control how storage is prepared, attached, and cleaned up.
This is useful when you want shared storage semantics over non-block backends, for example exposing S3 through a POSIX layer such as JuiceFS while still integrating with the platform's volume lifecycle.
Managed volumes
Limited Access
Managed volumes are available as part of enterprise plans. To enable them for your account, reach out to the Unikraft Cloud Discord or send an email to support@unikraft.com. Quotas aren't yet enforced by the platform for managed volumes, so use them with caution to avoid filling up your host's disk.
A managed volume points to an existing directory on the host rather than a platform-allocated storage file.
Create a managed volume with a host_path field instead of size_mb when calling POST /volumes:
POST /volumes
Restrictions apply:
host_pathmust be an absolute, normalised path to an existing directory on the host (no.,.., or:components).uidandgidset the ownership used when accessing the volume from the guest. Both default to0if not specified.size_mbandtemplateare mutually exclusive withhost_path.- The platform doesn't create, format, resize, or delete the backing directory for managed volumes.
Access modes
On creation, you can specify an access_mode that controls how instances can access or share the volume:
| Access mode | Description |
|---|---|
rwo | Read-write once. The volume can only be mounted in read-write mode by a single instance at a time. This is the default access mode. |
rox | Read-only many. The volume can be mounted in read-only mode by multiple instances simultaneously. |
rwx | Read-write many. The volume can be mounted in read-write mode by multiple instances simultaneously. This access mode is only supported for volumes with virtiofs filesystem. |
You can specify the access mode when creating a volume with the access_mode field:
POST /volumes
You can also use the unikraft CLI:
unikraft
Read-only many
More than one instance can mount the same rox volume simultaneously as long as all mounts are in read-only mode.
Read-only sharing is always permitted regardless of how many other instances have the volume mounted.
Specify readonly: true when attaching a volume at instance creation or via the attach endpoint:
POST /instances
Read-write many
Read-write many (rwx) volumes are only supported for volumes with the virtiofs filesystem.
The downside is that virtiofs volumes are slower than block volumes, so only use them for rwx or managed volumes.
To create a rwx volume, you can use the POST /volumes endpoint:
POST /volumes
You can also use the unikraft CLI:
unikraft
Learn more
- The CLI reference and the legacy CLI reference.
- Unikraft Cloud's REST API reference, in particular the section on volumes.
- Tutorial explaining the difference of storage media on Unikraft Cloud.