Provide an OCI Runtime inside the Cartesi Machine

Objective

As a way to abstract the internals of how an application should be prepared to run inside the Cartesi Machine, and make the lives of developers easier, we propose to make it possible to run an OCI Image inside the Cartesi Machine through an OCI Runtime.

What’s an OCI Runtime?

OCI stands for Open Container Initiative, and many standards are defined by this initiative like OCI Image, OCI Runtime, OCI Distribution just to name a few.

An OCI Image is just a container image assembled into a tarball with some JSON for metadata, AKA docker image. To generate such tarball from a container image using a tool like docker, one could simply run docker image save debian:slim -o image.tar and that would save the OCI Image into image.tar.

With an OCI Image, we can use it to start a container using any tool that implements the OCI Runtime, and we could have this tool inside the Cartesi Machine.

We already use a Dockerfile as input so that sunodo build generates a Cartesi Machine snapshot. Still we require the developer to provide things like MACHINE_EMULATOR_VERSION a sunodo-sdk-version and other variables.

If it’s possible to run an OCI Image inside the cartesi machine, we could only ask the developer to provide us that image and we take care of using this image to start the application processes.

What are the benefits?

The benefits of such approach are that we’re using standards that are broadly accepted and used by the industry to provide services like application hosting (AWS ECS, Azure Containers, Kubernetes …).

Some benefits are:

  • Easy packaging (OCI Image) and distribution (OCI Distribution) of the application and its dependencies using public OCI-based registries;
  • The developer could have the same code (Dockerfile) for the applications even if used to run without a Cartesi Machine;
  • An OCI Image has its layers and files using a content addressable format, which gives us confidence that the content was not tampered with (I know we have the templateHash);

Concerns

Some concerns may arise when adopting this strategy.

For example:

  • The final Cartesi Machine snapshot file could be bigger;
  • It can be harder to debug issues since we’ll have another layer between booting the machine and calling the application process

How to get there?

Ideally, this feature should be implemented in the sunodo CLI (future cartesi CLI) and the implementation should create the smallest possible layer with all the Cartesi Machine initialization taken care of.

What’s in the future?

The Cartesi Machine will provide a hypervisor functionality, and promoting this approach of having the application isolated using an OCI Image format, we can reuse this to make it easy to run multiple applications inside the Cartesi Machine isolated by the hypervisor. We could even start experimenting with the isolation provided by the OCI Runtime even before having a hypervisor-level isolation.

Distributing the OCI Image via IPFS would be another approach to make this more web3-ish, since both IPFS and OCI Image share the content addressable functionality, they can be matched and there are already opensource projects that combine an OCI Distribution implementation backed by IPFS.

It’s hard for me to judge the technical aspects of this proposal, since it’s very far away from my (rather tiny) area of expertise.

But I can comment that the proposed objectives/goals seem quite positive/desirable. Do you have any idea, percentage wise, on how much bigger the snapshots would be? I believe we’ll rarely need to have multiple snapshots for the same application - maybe just the most recent one and the one for the last unsettle epoch?

Anyway, just wanted to highlight that I think the goals here are quite desirable.

1 Like

The proposed OCI Runtime layer will be squashfs read-only filesystem of aprox. 15MB.