ROMs
Limited Access
ROMs are only available in BYOC or on-prem Unikraft Cloud installations. General availability on the public Unikraft Cloud offering is coming soon.
Unikraft Cloud supports the ability to attach Read-Only Memory (ROM) blobs to instances. It allows you to create a general-purpose base image and then customize individual instances by attaching code or data as separate ROM blobs. This enables quick deployment of custom functionality to preexisting language environments without rebuilding the entire image.
Overview
With ROMs, you can:
- Deploy variations of an app from a single base image.
- Update app code without rebuilding the base image.
- Reduce image size and deployment time.
The ROM workflow consists of two main components:
- Base Image: A general-purpose image containing the runtime environment (for example, Python interpreter, Node.js, etc.).
- ROM Blobs: Separate, lightweight images containing your app code or any other data you want to customize.
This separation allows you to maintain one base image while deploying many different instances with different data.
By default, the app running inside the base image needs to mount the attached ROM device.
ROM blobs appear as block devices at paths like /dev/ukp_rom_<rom_name>, where <rom_name> is the ROM name you specify when creating the instance.
For convenience, this guide uses automounting by setting the at field on a ROM entry.
When at is present, the platform automatically mounts the ROM at the given path on boot, so your app can read files from it directly without any manual mount step.
Setup
This example shows how to deploy Python functions using ROMs on Unikraft Cloud.
Ensure you have the CLI installed and configured with your Unikraft Cloud account.
Make sure to log into Unikraft Cloud and pick a metro close to you.
This guide uses fra (Frankfurt, 🇩🇪):
The legacy kraft CLI only supports packaging ROMs.
Use the unikraft CLI to create instances with ROMs attached.
Base image
First, create a base image with a Python HTTP server that loads and executes custom Python programs from a ROM.
Dockerfile
The commands below will use the at field to automount the ROM.
That's why the Kraftfile omits the wrapper.sh script and the app can read the ROM file directly from /rom/rom.py.
Package and push the base image:
Wait a few seconds for propagation and check that the image is present:
ROM files
To showcase the benefits of using ROMs, create two files, each containing a Python function that the base image will load and execute. Create a separate directory for each of the ROMs:
Package and push the ROMs:
Wait a few seconds for upload and check that the ROMs are present:
Instances
Create two instances with the same base image and attach different ROMs:
The name field in the ROM entry is optional, and is heplful for identification purposes in the instance configuration.
Check that the instances are up:
Note the roms array in the instances configurations.
Each ROM is available as a readable device at /dev/ukp_rom_python_function.py, in the form of an EROFS filesystem.
In this example, the platform mounts it automatically at /rom, and the app reads /rom/rom.py from that mount point.
Testing
Query the instances to call the Python function from the ROM. You should see different responses:
Code
Code
Cleanup
When done, remove the instances:
Inline ROMs
Instead of pre-packaging and pushing a ROM image to a registry, you can provide file contents directly in the instance creation request.
This is useful when you create instances from a template where the snapshot locks ENV and ARGS, but you still need to inject instance-specific data.
To use inline ROMs with unikraft, specify a local directory as source:
unikraft
API format
The API allows you to specify the contents of an inline ROM directly in the JSON request body when creating an instance.
Add a files array to a ROM entry instead of an image field:
POST /instances
Each file in the files array has three fields:
| Field | Description |
|---|---|
path | File path inside the ROM filesystem. The platform creates directories automatically. |
encoding | Either text (UTF-8 string) or base64 (base64-encoded binary data). |
data | The file contents in the specified encoding. |
The platform packages the provided files into an EROFS filesystem and attaches it as a ROM device, the same way image-based ROMs work.
The at field is optional and works the same as for image-based ROMs—when present, the platform mounts the ROM at the given path automatically.
Combining with image-based ROMs
You can mix inline ROMs and image-based ROMs in the same request:
POST /instances
Limits
The platform enforces the following default limits on inline ROMs:
| Limit | Default |
|---|---|
| ROMs per instance | 8 (inline and image-based combined) |
| Files per inline ROM | 16 |
| Total size per inline ROM | 1 MB (across all files) |
| Max API request body | 8 MB |
No per-file size limit exists. The total size limit applies to the combined size of all files in a single inline ROM. Since inline ROM data is base64-encoded in the JSON request body, the 8 MB request body limit is the practical upper bound on total data per API call.
Learn more
Use the --help option for detailed information on using Unikraft Cloud:
Or visit the CLI Reference or the legacy CLI reference. For more information on the features used in this use case and how to use them, check out the following documentation:
- Unikraft Cloud's REST API reference, and in particular the instances API.
- Tutorial explaining the difference of storage media on Unikraft Cloud.
- Running serverless functions packaged as ROMs on Unikraft Cloud.
- Running and customizing game servers using ROMs on Unikraft Cloud.