NodeRings Docs

Get Started

Fast path from registration to your first plan in marketplace search

This guide takes you from sign-up to a live, sellable plan in marketplace search, in order.

Before you start

You needMinimum
HypervisorProxmox VE with API access
Agent VMUbuntu 22.04+, 2 vCPU, 4 GB RAM, outbound HTTPS
DomainOne you control (DNS or HTTPS verify)
Guest IPsDual-stack pool (IPv4 and IPv6) for customer VMs
OS templatesImages on Proxmox ready to register
Proxmox API tokenDedicated user + token for the agent operator (see below)

Proxmox API user and token

The agent stack (proxmox-operator, prometheus-pve-exporter, vnc-gateway) uses one Proxmox API token you create locally. NodeRings never stores it. You enter it during agent install.

Create a dedicated user (for example nrings-operator@pve) and token (for example nrings-operator-token) with privilege separation (--privsep 1). Assign noderings-role to both the user and the token.

AreaPrivilegesPurpose
VM lifecycleVM.Allocate, VM.Clone, VM.Audit, VM.PowerMgmtClone templates; create, delete, start, stop, and read VMs
BackupsVM.Backup, Datastore.AllocateSpace, Datastore.AuditCreate, restore, and delete vzdump backups
SnapshotsVM.Snapshot, VM.Snapshot.RollbackCreate, delete, and rollback snapshots
Guest firewallVM.Config.Network, VM.Config.OptionsFirewall rules and IP sets on guest VMs
VM configVM.Config.CPU, VM.Config.Memory, VM.Config.Disk, VM.Config.Cloudinit, VM.Config.CDROM, VM.Config.HWTypeCPU, RAM, disks, cloud-init ISO, console VGA
VNC consoleVM.Consoleproxmox-operator + vnc-gateway: qemu/{id}/vncproxy, vncwebsocket
StorageDatastore.AllocateSpace, Datastore.AllocateTemplate, Datastore.AuditVM disks, cloud-init ISO upload/delete
Metrics and preflightSys.Audit, VM.Audit, Datastore.AuditMetrics sidecar for node health and capacity checks (pve_up, cluster status, storage)

Datacenter → Permissions → create role noderings-role → add user nrings-operator@pve → create token nrings-operator-token with privilege separation → Add ACL for the token and user on / (propagate), then on each storage path.

Create role with operator privileges

Step 1 of 6

Run on a Proxmox shell (adjust storage IDs):

pveum role add noderings-role -privs "Datastore.AllocateSpace Datastore.AllocateTemplate Datastore.Audit Sys.Audit VM.Allocate VM.Audit VM.Backup VM.Clone VM.Console VM.PowerMgmt VM.Snapshot VM.Snapshot.Rollback VM.Config.CDROM VM.Config.Cloudinit VM.Config.CPU VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options"
pveum user add nrings-operator@pve --comment "NodeRings operator"
pveum user token add nrings-operator@pve nrings-operator-token --privsep 1
pveum acl modify / -token 'nrings-operator@pve!nrings-operator-token' -role noderings-role --propagate 1
pveum acl modify / -user nrings-operator@pve -role noderings-role --propagate 1
pveum acl modify /storage/local-lvm -token 'nrings-operator@pve!nrings-operator-token' -role noderings-role
pveum acl modify /storage/local-lvm -user nrings-operator@pve -role noderings-role
pveum acl modify /storage/local -token 'nrings-operator@pve!nrings-operator-token' -role noderings-role
pveum acl modify /storage/local -user nrings-operator@pve -role noderings-role

Save the token secret when it's shown. It cannot be read again. Repeat the storage pveum acl modify /storage/... lines for every backup and ISO storage ID, once for the token and once for the user.

Notes

  • Grant ACLs for both the user and the token on / (propagate) and each storage you use for VM disks, backups, and cloud-init. Missing storage ACLs cause permission errors on clone, backup, or ISO upload.
  • The role is cluster-wide, but the operator only manages VMs named NR-{uuid}; your other guests are not touched.

More detail: Agents · Troubleshooting → Storage or backup errors.


Onboarding path

Provider platform illustration

1. Organization

Create a provider organization, verify your domain, and complete your business profile before NodeRings unlocks infrastructure and billing.

Create organization

Step 1 of 5

Create a provider organization

In the sidebar, open the organization menu → Add organization → choose Provider (sells services to clients) → enter your company name → Create Organization.

Verify your domain

On Provider onboarding, enter the domain you will list on the marketplace (for example acme.com) and choose a verification method:

At your DNS host, add a TXT record:

  • Name: _nrings-challenge.<your-domain> (for acme.com, use _nrings-challenge.acme.com)
  • Value: the verification code shown in the dashboard

On your public web server, create:

  • URL: https://<your-domain>/.well-known/nrings-challenge.json
  • Content: { "_nrings-challenge": "<verification-code>" } (use the code from the dashboard)

Click Add Domain, apply the challenge, then Verify. DNS can take a few minutes to propagate.

Complete your organization profile

Fill in the details NodeRings uses for marketplace review and customer-facing listings:

  • Organization name (legal company name)
  • Support email, billing email, and support phone
  • Business address (country, region, city, postcode)
  • Tax identifiers (VAT ID, tax ID where applicable)
  • DDoS provider and ASN (if you operate your own network)
  • Provider logo (PNG or SVG, max 512 KB)
  • Business owner name and social profiles (optional)

Request review

Click Request review and save. NodeRings reviews your listing; infrastructure unlocks after approval. Set up Stripe Connect under Organization → Billing → Payout when ready.

More detail: Organization · Domain verification.


2. Stripe Connect

Marketplace revenue is paid out through Stripe Connect. NodeRings charges the customer, keeps the platform commission for your tier, and transfers the rest to your Stripe account. Until Connect is active with charges and payouts enabled, you can still build infrastructure, but you cannot receive marketplace payouts.

A Community platform subscription is attached when you create the organization. Connect is available on Community and paid tiers. Open /billing/payoutPayout MethodsConnect Account.

Create Connect Account

Step 1 of 4

Create a Connect account

On Payout MethodsConnect Account, click Create Connect Account. NodeRings creates a Stripe Connect account linked to your provider organization and shows Connect Account Details (still Pending until Stripe onboarding finishes).

Complete Stripe onboarding

While status is Pending, charges and payouts stay disabled. Click Complete Setup & Onboarding to open Stripe’s hosted flow. Provide business and identity details (or reuse an existing Stripe account), then return to the dashboard.

Confirm Active

When onboarding succeeds, the account shows Active with Charges Enabled and Payouts Enabled. You can set a payout schedule under Payout Schedule. If Stripe Connect is not available in your country, use Manual Payout instead (funds are held longer before release).

Stripe Connect is recommended: customer payments split at charge time and transfer to your Stripe account. Disconnecting only removes the link in NodeRings; it does not delete the Stripe account.

More detail: Billing & Payouts.


3. Region

A region is where you tell NodeRings where your infrastructure lives. It is the geography customers see when they pick a plan, for example “Frankfurt, Germany” or “Akron, United States”. Behind that label you map your real site: country, city, datacenter, and availability zone.

Regions page

Step 1 of 2

Pick the geography

Select country and city that reflect where your Proxmox nodes actually run. This is what customers use to choose your plans.

Choose datacenter

Select the facility from the list, or choose Other if you do not want to disclose your datacenter provider on the marketplace. Other still lets you sell, only the specific facility name is hidden.

Choose availability zone

Pick zone_a, zone_b, or another zone only when the infrastructure is truly separate (distinct top-of-rack switches, routers, or hypervisor rows). If everything shares one fabric, use a single zone. Splitting zones without real isolation misleads customers about fault tolerance.

Save the region

Click Create Region. The region is then available when you attach nodes and plans.

You can operate multiple regions (different cities or zones). Customers buy a region; you assign each Proxmox node to the region and zone where it physically sits.

More detail: Regions.


4. Agent

An agent is a lightweight k3s Kubernetes cluster you install on a VM inside your own infrastructure. You provision and operate it. NodeRings has no direct shell or root access. VM orders reach your Proxmox through a scoped, encrypted peering channel and Custom Resources, not by NodeRings logging into your network.

Agents page

Step 1 of 3

Register the agent

Enter an agent name and the VM’s public IPv4 address. These are the only required fields to establish the secure channel between your site and NodeRings. Description is optional.

Choose gateway region

Select the gateway region closest to your agent VM. This is the datacenter where the NodeRings control-plane cluster runs. Picking a nearby gateway keeps the peering tunnel short and stable (for example Amsterdam if your agent sits in western Europe).

Provision on your agent VM

After you create the agent it appears as Unprovisioned. Select it in the list, open the Provisioning tab, and copy the Installation command. SSH into your Ubuntu agent VM and paste the command there. The script installs k3s, peers with NodeRings, and connects to your chosen gateway.

When prompted during install, provide your Proxmox URL and API token from Proxmox API user and token.

More detail: Agents.


5. Platform and node

Your agent controls one or more platforms. Each platform is the API endpoint for a hypervisor or controller; nodes are the individual physical hosts underneath it that actually run customer VMs.

Before you add a platform, confirm your agent is provisioned and shows a green status in /infrastructure/agents. If the agent is still Unprovisioned or offline, finish §4 Agent first, or see Troubleshooting.

Platform

A platform is your hypervisor or controller: the system the agent operator talks to. Proxmox is supported today via the Proxmox driver; other drivers may be added later.

The agent you provisioned in the previous step will reconcile VM orders against this platform. When you create a platform you must link it to that agent.

Platforms & Nodes page

Step 1 of 2

Add a platform

Click Add Platform. Give it a name, select driver Proxmox, and choose the agent you provisioned.

Set the endpoint URL

Enter the full API URL of your Proxmox cluster or host, for example https://192.168.1.100:8006/. Proxmox typically listens on port 8006 over HTTPS.

This can be a private or internal IP. The key requirement: the agent VM must be able to reach this URL. If it cannot call the Proxmox API, orders fail.

Node

A node is a physical server (or hypervisor host) under that platform: the machine that actually runs VMs. You can register one or many nodes on the same platform.

The node name must match your hypervisor exactly: character for character. Copy it from Proxmox (Datacenter → your node in the tree, for example proxmox01-lab01-dev). If the name in NodeRings does not match, the agent operator cannot place or manage VMs on that host.

Add Node

Step 1 of 3

Add a node

Under your platform, click Add Node. Paste the node name exactly as shown in Proxmox.

Attach region

Select the region from §3 Region where this host physically sits. Customers buy by region; the node must belong to the correct one.

Set storage paths

Enter the Proxmox storage ID for new VM disks (VM disk storage) and for backups (Backup storage), for example local-lvm and local, as they appear under your node in Proxmox.

Backup compression and VMID seed

Choose backup compression (None, LZO, Gzip, or Zstd). Backups use vzdump snapshot mode so VMs keep running.

Set VMID seed to the first VM ID you want NodeRings to use on this node. If you set 9900, the first customer VM is 9900, the next 9901, and so on. Pick a range that does not collide with your existing VMs or templates.

Resource overallocation

Set CPU, memory, and storage overallocation percentages for this node:

SettingMeaning
100%No overselling, each VM gets dedicated resources up to the physical limit
200%Up to 2× sell-through on that resource (for example an 8-core node can host two 8 vCPU VMs)

At 100%, assets get dedicated resources; higher values allow resource sharing. The trade-off is yours, based on the quality of service and customer mix you target. The same logic applies separately to CPU, memory, and storage. A plan still cannot exceed a single node’s physical size (an 8-core node cannot sell a 16 vCPU plan regardless of overallocation).

More detail: Platforms & nodes.


6. Cloud-init

After your platform and node are online, create a cloud-init template in NodeRings. Your operator injects it when cloning customer VMs. NodeRings assigns static IPs only through IPAM.

NodeRings ships a read-only seed template named Ubuntu/Debian. Copy it into your organization. You cannot attach the seed directly to a VM template.

Cloud-Init Templates page

Step 1 of 2

Copy Ubuntu/Debian

In the sidebar, click NewUbuntu/Debian. NodeRings opens a draft with user_data, vendor_data, and network_data pre-filled for static IP provisioning.

Adjust for your guest OS

Review network-data: the seed matches any Proxmox virtio NIC (match: driver: virtio_net), so it works across Ubuntu, Debian, Rocky, Fedora, and other distros without hard-coding interface names. Set storage to the Proxmox datastore ID used for cloud-init ISOs on your nodes (default local).

Save your template

Save each file (user_data, vendor_data, network_data) from the editor. NodeRings pushes compiled resources to agents linked through your VM templates in the next step.

Give the template a clear name (for example Ubuntu 24.04 cloud-init).

More detail: Cloud-init templates.


7. VM templates

A VM template is a Proxmox image you clone when provisioning customer VMs. NodeRings stores the mapping from distrotemplate ID (VMID)nodecloud-init.

One platform, many nodes: Under each node you can register multiple templates. Every required OS in the catalog must exist on your platform (as a Proxmox template somewhere in the cluster). It does not have to sit on every physical host. Proxmox can clone templates between nodes on the same platform when storage allows.

The template ID is the Proxmox VMID you set in qm create (for example 15000) before you run qm template.

VM Templates page

Step 1 of 4

Create template images on Proxmox

Pick a per-OS tab or Seed all templates for the full catalog (VMIDs 15000–15013; edit VMID_BASE if needed). Install wget curl jq xz-utils qemu-utils libguestfs-tools on the Proxmox node first.

Details on disk size, --cpu host, firmware, and cloud-init: VM templates: CLI scripts.

Suggested VMID 15000 · 1 vCPU · 1024 MB RAM · 5G disk · CPU host · firmware uefi

#!/usr/bin/env bash
# Run on a Proxmox node as root. Adjust STORAGE/BRIDGE if needed.
# UEFI: include Proxmox cloud-init drive (scsi1) at create time. Legacy BIOS: OS disk only.
# NodeRings removes template cloud-init drives and injects cidata on ide2 at provision time.
set -euo pipefail

command -v qm >/dev/null || { echo "Run this on a Proxmox node (qm not found)"; exit 1; }

storage_supports_images() {
  local st=$1 content
  content=$(pvesm status -storage "$st" 2>/dev/null | awk -v s="$st" 'NR>1 && $1==s { print $3; exit }')
  [[ "$content" == *images* ]]
}

resolve_storage() {
  local st
  if [[ -n "${STORAGE:-}" ]]; then
    if storage_supports_images "$STORAGE"; then echo "$STORAGE"; return; fi
    echo "STORAGE=$STORAGE does not support VM disk images" >&2; exit 1
  fi
  for st in local-lvm local; do
    if storage_supports_images "$st"; then echo "$st"; return; fi
  done
  st=$(pvesm status -content images 2>/dev/null | awk 'NR>1 { print $1; exit }')
  [[ -n "$st" ]] && { echo "$st"; return; }
  echo "No storage with VM disk image support. Set STORAGE= explicitly." >&2; exit 1
}

STORAGE=$(resolve_storage)
echo "Using storage: $STORAGE"
BRIDGE="${BRIDGE:-vmbr0}"
WORKDIR="${WORKDIR:-/tmp/noderings-vm-templates}"
VMID=15000
NAME="ubuntu-2204-template"
IMG="ubuntu-2204.img"
URL="https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"

if qm config "$VMID" &>/dev/null; then
  echo "VMID $VMID already exists. Destroy it first: qm destroy $VMID --purge 1"
  exit 1
fi

mkdir -p "$WORKDIR"
cd "$WORKDIR"

echo "Downloading $NAME ..."
wget --show-progress -L -O "$IMG" "$URL"
[[ -s "$IMG" ]] || { echo "Download failed: empty file"; exit 1; }
[[ $(stat -c%s "$IMG") -gt 100000000 ]] || {
  echo "Download failed: file too small ($(stat -c%s "$IMG") bytes). Check URL:"
  echo "  $URL"
  exit 1
}
qemu-img resize "$IMG" 5G 2>/dev/null || true

qm create "$VMID" --name "$NAME" --memory 1024 --cores 1 --cpu host \
  --net0 "virtio,bridge=${BRIDGE},firewall=1" \
  --bios ovmf --agent enabled=1 \
  --efidisk0 "${STORAGE}:${VMID},efitype=4m" \
  --ostype l26 --serial0 socket --vga serial0 --machine q35 \
  --scsi1 "${STORAGE}:cloudinit" --scsihw virtio-scsi-pci \
  --sockets 1 --numa 0

qm set "$VMID" --scsi0 "${STORAGE}:0,import-from=${WORKDIR}/${IMG}"
qm set "$VMID" --boot c --bootdisk scsi0
qm disk resize "$VMID" scsi0 5G 2>/dev/null || true

VOLID=$(qm config "$VMID" | sed -n 's/^scsi0:.*:\(vm-[0-9]*-disk-[0-9]*\).*/\1/p')
DISK=$(pvesm path "${STORAGE}:${VOLID}")
if [[ -b "$DISK" ]]; then
  [[ $(blockdev --getsize64 "$DISK") -gt 104857600 ]] || { echo "Import empty (block device too small)"; exit 1; }
else
  [[ $(du -k "$DISK" | cut -f1) -gt 102400 ]] || { echo "Import empty"; exit 1; }
fi
disk_has_partitions() {
  local disk_path=$1
  if sgdisk -p "$disk_path" 2>/dev/null | grep -qE '^[[:space:]]*[0-9]+[[:space:]]'; then return 0; fi
  if fdisk -l "$disk_path" 2>/dev/null | grep -qE '^/dev/'; then return 0; fi
  return 1
}
if ! disk_has_partitions "$DISK"; then
  echo "No partition table on imported disk"
  exit 1
fi

qm template "$VMID"
rm -f "$IMG"

echo "Template ready: VMID $VMID ($NAME)"

Register in NodeRings

Click Create VM Template. Select node, distro, enter the Proxmox template ID (VMID), and link your cloud-init from §6.

Cover the full catalog

Preflight expects every OS below on each sell-path node (registered in NodeRings).

OS
Ubuntu 22.04 LTS · Ubuntu 24.04 LTS · Ubuntu 26.04 LTS
Debian 12 · Debian 13
Fedora 44 · Fedora 43
CentOS Stream 9 · CentOS Stream 10
AlmaLinux 9 · AlmaLinux 10
Rocky Linux 9 · Rocky Linux 10
Alpine Linux 3.24

More detail: VM templates.


8. IPAM

Register your public IP ranges in NodeRings so customer VMs receive static IPv4 and IPv6 addresses at order time. NodeRings assigns from your prefixes and injects gateway, DNS, and addresses into cloud-init.

IPAM page

Step 1 of 5

Create a network

Name the network, set DNS servers, and assign nodes that will sell VMs from this pool.

Add prefixes

Add at least one IPv4 and one IPv6 prefix. Set each prefix gateway and mark infrastructure addresses as reserved so NodeRings never auto-assigns them.

Reserve external use

If part of a prefix is used by your own internal customers or DHCP elsewhere, reserve those IPs in NodeRings so they stay out of the customer pool. You can automate reserve/unreserve via the IPAM API.

Marketplace minimum: at least 5 free assignable IPv4 and 10 IPv6 addresses on the network (shared pool across prefixes) for a plan to pass IP Avail. and appear on the marketplace.

More detail: IPAM.


9. Plans and addons

A plan is the VM size and price customers buy. Pick fixed (monthly upfront) or usage-based (hourly) billing, set prices per region, and create matching addons. Full reference: Plans & Addons.

Create a plan

Plans tab → Create Plan → choose billing type, region, and template (start with SC-GC-2C-4G-80). Set base price and Bandwidth Egress Gb (free units, overage rate, or unlimited).

Create addons

Addons tab → create addons with the same billing type as the plan (backups, additional IPs, snapshot storage).

Test with Price Calculator

Use the Price Calculator tab (?t=price-calculator) to estimate totals. Testing only.

More detail: Plans & Addons.


10. Preflight check

After plans and addons exist, NodeRings validates that your infrastructure can actually sell them before they appear in marketplace search.

Two stages, both required

StageHow it runsMarketplace impact
PreflightAutomatic; re-runs every few minutesAny red gate removes the plan from search until fixed
Live validationManual; you start each plan × node runPlan lists only after at least one node passes preflight and live validation

Preflight alone is not enough. Even when every gate is green, you still need a successful live validation on each sell-path node you want to offer.

What preflight checks

NodeRings evaluates each plan × node row in your sell regions. The matrix columns map to gates such as Addon, Agent, Platform, Node, Physical fit, Sell capacity, IP Avail., and OS.

Physical fit and Sell capacity are different:

  • Physical fit: can this node run one instance of the plan on real CPU, RAM, and VM disk storage?
  • Sell capacity: with VMs already sold, is there still headroom under your overallocation limits?

A node can pass one and fail the other. See Physical fit vs sell capacity for examples.

Live validation

After preflight is green, scroll to Live validationStart validation. Pick the plan and node, optionally enable Include hardware benchmarks, and wait for the pilot VM run to finish.

Live validation provisions a short-lived VM end to end: clone template, assign IPs, SSH, ping, power stop/start, then cleanup. When Validated: Yes, that plan × node pair is eligible for marketplace listing.

If you enable benchmarks, NodeRings stores CPU, memory, disk, and network scores. That data helps marketplace search surface better-performing offers, not just the cheapest price.

Preflight check dashboard

Step 1 of 5

Wait for preflight to go green

Fix red gates (agent, platform, node, templates, IPAM, addons). The next automatic cycle usually picks up changes within a few minutes.

Run live validation per plan × node

Use Start validation for every combination you sell on. Repeat when you add nodes or plans.

Confirm marketplace ready

Summary shows Ready with no blockers, and live validation shows Validated: Yes for at least one node in the sell region.

Customers can find and buy your plan

On the client marketplace (Create Virtual Machine → filter by region and plan size), your organization name, plan price, and listing details appear under recommendations. If preflight or live validation fails later, the plan drops out of search until you fix it.

Preflight quick fixes

Red gateTry this
agent_onlineAgent provisioned; platform linked to agent
platform_onlineHypervisor API up; metrics flowing (pve_up=1)
node_onlineNode active, in plan region, network attached, not in maintenance
plan_physical_fitNode has enough physical CPU, RAM, and disk for the plan (VM disk storage pool)
plan_capacityNode has sell headroom after overallocation; not the same as physical fit
os_templateRegister missing VM template on that node
ip_availableAdd prefix capacity (dual-stack; see IPAM minimums)
addons_createdCreate addons with same billing type as the plan

More detail: Preflight Check.


Stuck?

See the full Troubleshooting guide, or jump to a common issue:

ProblemRead
Agent not provisioned / no green statusTroubleshooting → Agent
Platform offlineTroubleshooting → Platform
Node name / VM placement issuesTroubleshooting → Node name
Domain verify failsDomain
Proxmox API 403 / permission errorsProxmox API user and token
Red preflightPreflight Check · Troubleshooting → Preflight
Architecture / securityHow it works → What a sale looks like