Package & publish
So far the app ran on a development cluster as a raw component (--path). A real cluster installs only signed
packages from a registry. A release of your app is a .mpk: a gzip-compressed archive with the app’s
component, its built frontend and a signed manifest.json naming the package and version. Every node that runs it
checks the signature and the digest of each file before it runs anything.
-
Build the frontend. The crate’s
frontend-dir(../app/dist) is packed into the release, and the cluster serves it from the package’s own origin, so build it first (afterpnpm installat the project’s root):Terminal window pnpm -F kv-store build -
Create a signing key, once. The key is your app’s identity: a new version must be signed by the same key, or it is a different app.
/home/you/.calimero/release.key meroctl app signer new ~/.calimero/release.key# signerId: did:key:z6Mk...meroctl app signer id ~/.calimero/release.keyprints the signer id again. Keep the file secret and out of version control: here it lives in~/.calimero, outside the project, wheregit add .cannot pick it up. -
Pack and sign the release, from the app’s crate:
Terminal window meroctl app pack apps/kv-store/logic --key ~/.calimero/release.key --app-version 1.0.0packreads the crate’s[package.metadata.calimero]:package,min-runtime-version,frontend-dir, and the display metadata the registry lists a new package by (name,description,icon,category,tags,author, …). It builds the component, checks the frontend against the node’s rules, writes and signsmanifest.json, and writesapps/kv-store/logic/dist/com.calimero.kv-store-1.0.0.mpk. The version is--app-version, else the crate’sversion.For every release after the first, pass
--previous <last .mpk>:packthen compares the two ABIs, warns about changes that break callers, and refuses a state change made without a state version bump. -
Check it as a node does:
Terminal window meroctl app inspect apps/kv-store/logic/dist/com.calimero.kv-store-1.0.0.mpkIt opens the bundle, checks the signature and every file’s hash, and prints
verified, thesignerId, thebundleHashand the manifest. -
Publish it to the Calimero app registry with a registry API key:
Terminal window export CALIMERO_REGISTRY_API_KEY=...meroctl app publish apps/kv-store/logic/dist/com.calimero.kv-store-1.0.0.mpkWith
--org ORG, the key is a Calimero Cloud organization’s API key instead (ck_live_…, scoperegistry:publish), whichmeroctltrades at the Cloud for a short publish token. A refusal comes back with the registry’s code (version_not_allowed,invalid_signature, …). You can also upload a.mpkfrom the Calimero Cloud console’s Registry page.
A package of several services
Section titled “A package of several services”An app can ship several services in one package: each app instance runs one of them, picked with
meroctl instance create --service NAME. A directory of rooms, for example, is a directory service and a room
service. Name each service and its crate with --service NAME=PATH (a crate directory, which pack builds, or a
built component), and the manifest declares services instead of a single wasm:
meroctl app pack --service directory=crates/directory --service room=crates/room \ --package com.example.rooms --app-version 1.0.0 --key my-signing-key.jsonOr list them in the crate’s [package.metadata.calimero] (a workspace root with no [package] of its own uses
[workspace.metadata.calimero], and its release is [workspace.package] version), and meroctl app pack DIR packs
them with no flags:
[workspace.metadata.calimero]package = "com.example.rooms"services = [ { name = "directory", path = "crates/directory" }, { name = "room", path = "crates/room" },]Each service is packed as services/<name>.wasm, with its compute component and pipelines beside it
(--service-compute, --service-pipeline). From core 1.0.0-rc.25; the full rules are in the
packaging reference.
Private and public packages
Section titled “Private and public packages”A new package is private by default: only the organization that publishes it can deploy it. --public lists it
for everyone:
meroctl app publish apps/kv-store/logic/dist/com.calimero.kv-store-1.0.0.mpk --publicThe signer is the update authority
Section titled “The signer is the update authority”A package’s identity is its package id and its signer. A new release signed by the same key under the same package is an upgrade of the existing app; signed by another key, it is a different app, and existing instances do not pick it up. A node also pins a package to the signer of its first release.
The manifest format and the exact checks a node runs on install are in the core reference’s Packaging & signing.
Next → Deploy & install: run the published package on Calimero Cloud or on a node.