Node CLI
relay-button includes a small Node-only CLI wrapper around the same reusable
runners used by the GitHub Action and workflow layers.
It does not use any browser package code. It simply dispatches into:
packages/node/src/action-runner.tspackages/node/src/rootfs-runner.ts
Command
From the repository root:
pnpm relay-button <command>
For machine-readable JSON output without the pnpm run banner, use the local
binary directly:
pnpm exec relay-button <command>
Supported commands:
deploylist-crnsretainrootfs-planrootfs-buildrootfs-publishhelp
Examples:
pnpm exec relay-button list-crns | jq
pnpm exec relay-button deploy
pnpm exec relay-button rootfs-publish
Deploy A VM
Manifest-driven uc-go-peer example:
cd /path/to/relay-button
export ALEPH_VM_PRIVATE_KEY=0x...
export ALEPH_VM_NAME=uc-go-peer
export ALEPH_VM_SSH_PUBLIC_KEY="$(cat ~/.ssh/id_ed25519.pub)"
export ALEPH_VM_ROOTFS_MANIFEST_URL='https://connect.nicokrause.com/rootfs/uc-go-peer/latest.json'
export ALEPH_VM_PREFERRED_COUNTRY_CODE=DE
export ALEPH_VM_ENABLE_CADDY_PROXY=true
pnpm relay-button deploy
When ALEPH_VM_ROOTFS_MANIFEST_URL is set, the shared CLI derives:
rootfsItemHashrootfsSizeMiBrequiredPortForwards- the manifest version string
from the remote manifest automatically.
Direct item-hash example:
cd /path/to/relay-button
export ALEPH_VM_PRIVATE_KEY=0x...
export ALEPH_VM_NAME=orbitdb-relay-01
export ALEPH_VM_SSH_PUBLIC_KEY="$(cat ~/.ssh/id_ed25519.pub)"
export ALEPH_VM_ROOTFS_ITEM_HASH=a83b2623e664f05671a7279003134f6fdb804527b17c97bbd571dc3c05d3b74f
export ALEPH_VM_PROFILE=orbitdb-relay
export ALEPH_VM_ROOTFS_VERSION=orbitdb-relay-v0.9.1
export ALEPH_VM_ROOTFS_SIZE_MIB=81920
export ALEPH_VM_VCPUS=4
export ALEPH_VM_MEMORY_MIB=8192
export ALEPH_VM_REQUIRED_PORTS_JSON='[
{"port":22,"tcp":true,"udp":false,"purpose":"SSH"},
{"port":80,"tcp":true,"udp":false,"purpose":"Temporary setup endpoint"},
{"port":443,"tcp":true,"udp":false,"purpose":"HTTPS / WSS proxy"},
{"port":9090,"tcp":true,"udp":false,"purpose":"Metrics"},
{"port":9091,"tcp":true,"udp":false,"purpose":"Relay TCP"},
{"port":9093,"tcp":false,"udp":true,"purpose":"WebRTC"},
{"port":9094,"tcp":false,"udp":true,"purpose":"QUIC"}
]'
pnpm relay-button deploy
Important:
ALEPH_VM_REQUIRED_PORTS_JSONmust be a JSON array of structured port-forward objects.- Do not pass raw port numbers like
[22,80,443,9095,9097]. - For
uc-go-peer, use the manifest-derived shape shown above so the required Aleph port-forward aggregate is published correctly.
Minimum required environment for deploy:
ALEPH_VM_PRIVATE_KEYALEPH_VM_NAMEALEPH_VM_SSH_PUBLIC_KEY- either
ALEPH_VM_ROOTFS_ITEM_HASHorALEPH_VM_ROOTFS_MANIFEST_URL
Common optional environment:
ALEPH_VM_PROFILEALEPH_VM_ROOTFS_MANIFEST_URLALEPH_VM_ROOTFS_VERSIONALEPH_VM_ROOTFS_SIZE_MIBALEPH_VM_VCPUSALEPH_VM_MEMORY_MIBALEPH_VM_CRN_HASHALEPH_VM_PREFERRED_COUNTRY_CODEALEPH_VM_REQUIRED_PORTS_JSONALEPH_VM_BOOTSTRAP_PUBLISHER_PRIVATE_KEYALEPH_VM_BOOTSTRAP_OWNER_PRIVATE_KEY
Dual-key bootstrap note:
ALEPH_VM_PRIVATE_KEYstill owns the Aleph VM deployment itself- if
ALEPH_VM_BOOTSTRAP_PUBLISHER_PRIVATE_KEYis provided, bootstrap registration can be published by that separate publisher identity instead of the deployer wallet - if
ALEPH_VM_BOOTSTRAP_OWNER_PRIVATE_KEYis also provided, deploy-time publication mints the owner authorization needed for dual-key verification - the current deploy flow writes that signed authorization record back into the
guest with a second
no_startconfigure call, so the VM can later refresh with publisher keyBwithout keeping owner keyAas the preferred long-lived guest secret
Build Or Publish A RootFS
cd /path/to/relay-button
export ALEPH_ROOTFS_PROJECT_DIR=/path/to/consumer-repo
export ALEPH_ROOTFS_CONTRACT_PATH=/path/to/consumer-repo/go-peer/aleph/root-profiles/uc-go-peer.json
pnpm relay-button rootfs-plan
pnpm relay-button rootfs-build
pnpm relay-button rootfs-publish
OrbitDB relay example:
cd /path/to/relay-button
export ALEPH_ROOTFS_PROJECT_DIR=/path/to/relay-deployer-pwa
export ALEPH_ROOTFS_CONTRACT_PATH=/path/to/relay-button/packages/rootfs/reference/orbitdb-relay/contract.json
export ALEPH_ROOTFS_ORBITDB_RELAY_DIR=/path/to/orbitdb-relay
pnpm relay-button rootfs-build
pnpm relay-button rootfs-publish
Minimum required environment for rootfs-publish:
ALEPH_ROOTFS_PROJECT_DIRALEPH_ROOTFS_CONTRACT_PATH
Common optional environment:
ALEPH_ROOTFS_VERSIONALEPH_ROOTFS_DRIVERALEPH_ROOTFS_UPLOAD_DRIVERRootfs image upload path. Defaults toaleph-ipfs, which streams the image through the configured IPFS add endpoint(s), then publishes an AlephSTOREpin withitem_type=ipfsand credit payment. Usealeph-api-ipfsto match the Rust CLI upload path: compute the CID locally, build the signedSTOREmessage, and send both the file andmetadata={"message":...,"sync":true}to Aleph's authenticated/api/v0/ipfs/add_fileendpoint. Useheliato import the image into a local public-IPFS Helia node, orapi-fetch/api-curlfor direct IPFS add endpoint variants.ALEPH_ROOTFS_STORE_PAYMENT_TYPEPayment type for the rootfsSTOREpin. Defaults tocredit;creditsis accepted as an alias. Useholdonly for locked-stake pinning.ALEPH_ROOTFS_SKIP_UPLOADALEPH_ROOTFS_SKIP_BUILDALEPH_ROOTFS_HELIA_PROVIDER_KEEPALIVE_SECONDSSeconds to keep the local Helia provider online after Aleph accepts theSTOREmessage. GitHub automation defaults this to300; local CLI runs default to60.ALEPH_ROOTFS_HELIA_PROVIDE_TIMEOUT_MSALEPH_ROOTFS_HELIA_BOOTSTRAP_DIAL_TIMEOUT_MSALEPH_ROOTFS_HELIA_BOOTSTRAP_MULTIADDRSExtra comma or whitespace-separated public IPFS bootstrap multiaddrs. The default list already includes the verified Aleph IPFS peer/ip4/46.255.204.209/tcp/4001/p2p/12D3KooWHWNCn8t9NKQPBPZU61Fq6BoVw9XV37YsWTuMLwZXrEtjplus the public IPFS bootstrap nodes.ALEPH_ROOTFS_IPFS_ADD_URL/ALEPH_ROOTFS_IPFS_ADD_URLSIPFS add endpoint(s) for rootfs image upload. The plural form accepts comma or whitespace-separated URLs and is tried in order.ALEPH_ROOTFS_IPFS_GATEWAY_URL/ALEPH_ROOTFS_IPFS_GATEWAY_URLSIPFS gateway base URL(s) used to verify that the uploaded rootfs CID is retrievable without downloading the whole image.ALEPH_ROOTFS_ALEPH_API_HOSTALEPH_ROOTFS_ORBITDB_RELAY_DIRRequired when the contract/profile isorbitdb-relay.
Retry tip:
If the qcow2/rootfs image was already built successfully but Aleph rejected the
later STORE publish step, for example due to insufficient Aleph balance, you
can retry the upload/publication step without rebuilding the image:
export ALEPH_ROOTFS_DRIVER=docker
export ALEPH_ROOTFS_SKIP_BUILD=true
pnpm relay-button rootfs-publish
The shared rootfs runner now auto-detects docker / virt-customize when
those flags are omitted. ALEPH_ROOTFS_HAS_DOCKER,
ALEPH_ROOTFS_DOCKER_DAEMON_RUNNING, and
ALEPH_ROOTFS_HAS_VIRT_CUSTOMIZE remain available as manual overrides when
you need to force or debug toolchain selection.
Relationship To GitHub Automation
This CLI does not add a new deployment implementation. It exposes the existing shared Node runners in a local command-line form.
pnpm relay-button deploymatches the same shared deploy path used by thealeph-vm-deployactionpnpm relay-button rootfs-publishmatches the same shared RootFS publish path used by the reusable workflow