The hub manages servers via SSH. The automation that bootstraps a fresh box (docker, certbot, netdata, mailcow, chainweb-node, sysbench / fio / perf / stress-ng for benchmarks) is tested against a specific list of operating systems. Running the hub against anything else is not supported — most automation will still work on near-neighbours, but regressions are not caught and no fixes are promised.
16.1 · Operating system policy
Three Ubuntu LTS releases are the entire supported surface:
| Release | Codename | Status | LTS support window |
|---|---|---|---|
| Ubuntu 24.04 | Noble Numbat | primary target | Apr 2024 → Apr 2029 (standard); → 2034 (ESM) |
| Ubuntu 26.04 | Resolute Raccoon | accepted (new) | Apr 2026 → Apr 2031 (standard); → 2036 (ESM) |
| Ubuntu 22.04 | Jammy Jellyfish | accepted | Apr 2022 → Apr 2027 (standard); → 2032 (ESM) |
Everything else is unsupported.That includes Debian (any version), Rocky / Alma / CentOS Stream, Fedora, Arch, Alpine, FreeBSD, non-LTS Ubuntu (24.10, 25.04, 25.10, …), and anything older than 22.04. The hub’s probe records the OS codename but the gating layer is permissive — non-supported OSes may register, but the install handlers may surface unexpected errors against unfamiliar package layouts.
16.1.1 · Why Ubuntu, and why only these two
- Ubuntu is the most-deployed server distribution. Picking one target that covers most of the operator base beats picking four that each cover a quarter and divide QA effort.
- LTS only.Interim releases (24.10, 25.04, …) get six months of support; the hub’s infrastructure needs to outlast that. Five-year standard support plus extended five-year ESM gives every registered node a decade of patchable runway from registration.
- Noble (24.04) primary. The most-deployed LTS in the fleet today;
docker,systemd-detect-virt, and the benchmark toolchain all behave predictably. Stays primary until 26.04 has been validated against the install handlers + UFW parser on a real box. - Resolute (26.04) accepted, freshest LTS. Released Apr 2026. Operators provisioning new VPSes today should pick 26.04 to maximise the patchable runway (5 years standard + 5 years ESM = 2036). The hub’s gating layer accepts it; install handlers + the firewall parser may surface 26.04-specific quirks that we’ll patch reactively as they appear.
- Jammy (22.04) accepted, not pushed. Many operators already run Jammy from earlier seeds; forcing an in-place distro upgrade would cause more breakage than it prevents. Jammy stays on the green path until it falls out of standard support in Apr 2027.
- Why not Debian.Not all of the hub’s bootstrap scripts have been validated against Debian 12+. Adding a second distribution family (different apt metadata, different systemd unit layout, different certbot hook behaviour) doubles the QA surface without doubling the user count. If a compelling reason emerges — major operator base on Debian, shared systemd behaviour — the policy gets revisited.
16.2 · Kernel + init
Linux kernel 5.15+ on Jammy, 6.8+ on Noble, 6.14+ on Resolute, HWE enabled is fine. systemd is required (the benchmark hw_type detection, chainweb-node supervision, and the auto-start/stop cycle all rely on it). Non-systemd init systems (OpenRC, SysV, runit) are not supported.
16.3 · Minimum hardware
These are floors, not sweet spots. Below them the benchmark will produce a low ServerScore and accrual will be correspondingly small; below by a large margin, some phases (fio, librespeed) may fail outright.
| Resource | Floor | Notes |
|---|---|---|
| CPU | 2 cores / 4 threads | High-frequency preferred; cores-penalty was retired in v0.7.7u. |
| RAM | 7 GB | Minimum for Prime / Stoa Node tier (lowered from 8 in v0.7.12m12 to qualify mid-range home boxes). RAM slot is linear — 16 GB scores 2× the slice, no ceiling. |
| Disk | NVMe or SATA SSD, 100 GB free | Spinning rust fails the 4K-random fio test budget. Commitment must be ≥ the fleet’s minRequiredGb. |
| Network | 500 Mbps symmetric, dedicated public IPv4 | Reference baseline for 1.0 × the net slice; slower links earn proportionally less. Dedicated public IPv4 (static OR dynamic) is non-negotiable; a CGNAT-shared IP will not work even with port-forwarding. See §16.6 for the three-kinds-of-IP distinction + CGNAT test. |
| hw_type | barebone or vps | Container-classified hosts (docker / lxc) are rejected at stamp time — see §15.4. |
16.4 · Package prerequisites
Everything below is installed by the hub’s bootstrap script (/api/admin/nodes/[id]/bootstrap) when an operator registers a node — the list is here for transparency and for operators who want to pre-bake an image.
docker-ce,docker-compose-plugin— chainweb-node runs as a docker container by default (“dockerised” profile). Bare-metal profiles skip docker but gain operational complexity.certbot+ ECDSA P-256 cert formail.<yourdomain>. Bootstrap runs certbot in nginx-hook mode; deploy-hook chains the cert into chainweb’s TLS path.netdata— monitoring agent; drives the Monitoring tab on the admin surface. Installed from Netdata’s own stable channel, not the distro repo (distro version lags).sysbench,fio,linux-tools-common(forperf),stress-ng,curl— benchmark toolchain. See §15 Benchmarking.NOPASSWDsudoers entry for the hub’s SSH user, scoped to the specific commands bootstrap needs. The operator reviews + consents to the scope via the transparency modal on first sign-in.
16.5 · Firewall and ports
22/tcp— SSH (or a non-default port; the hub picks it up from the node row).1024–65535/tcp— one port for chainweb p2p (operator picks; declared in--p2p-port). Must be publicly reachable — mandatory flag, a closed port zeros Stoicism accrual.443/tcp— chainweb service-api TLS (inbound from the hub + from peer nodes).19999/tcp— netdata agent (localhost-bind or hub-only via UFW allowlist).
16.6 · Public IPv4 address (hard requirement)
A dedicated, publicly routable IPv4 address is a prerequisite for running a StoaChain node. This is not negotiable at the protocol level— chainweb’s P2P layer advertises each peer as hostname:portin the network registry, and other peers dial that address directly, cold, with no signaling protocol to negotiate NAT traversal. If the packet addressed to your node can’t reach your specific router, peering doesn’t happen and the node accrues zero Stoicism regardless of how fast the hardware is.
The three kinds of IPv4 you might have
| Kind | Works? | What it is + what you need to know |
|---|---|---|
| Static public IP | ✅ yes, directly | Permanent IPv4 assigned only to you. Doesn’t change across ISP sessions or reboots. Typically offered on business tariffs or as a paid add-on on residential. Point an Arecord at it in your DNS provider once and you’re done — no dynamic-DNS needed. Most expensive option but simplest operationally. |
| Dynamic public IP | ✅ yes, with DuckDNS | Dedicated to you WHILE you hold the lease. Changes on reconnect / ISP lease renewal (typically daily or weekly). Fully routable inbound during each lease. Works with dynamic-DNS services (DuckDNS, No-IP, Cloudflare dynamic DNS): a cron job pushes your current IP to the provider, who updates the A record. Peers always resolve to your current IP. Common on residential fiber across EU — often free or a few lei/euros per month on request. This is the sweet spot for most operators. |
| CGNAT (shared IP) | ❌ no, never | Your “public IP” is shared with dozens or hundreds of other subscribers. The ISP’s NAT box decides per-packet which customer to route inbound to, but only when an outbound session already exists for that flow. Cold dials from a peer that doesn’t know you produce no outbound state, so the NAT silently drops the packet. DuckDNS does not helphere — it resolves your hostname to the shared IP, but the shared IP can’t route to you specifically. Common on mobile internet (almost always) and on some residential tariffs in Romania, Italy, Spain, SE Asia. |
| CGNAT + VPS tunnel | ✅ yes, ~1 €/mo | The working path for CGNAT operators: rent a small cloud VPS with a real public IP (IONOS VPS XS+ at 1 €/month, or Hetzner / Contabo at 3–5 €/month), install a reverse tunnel (frp) between the VPS and your home node, advertise the VPS’s address as p2p-hostname. The VPS fronts inbound peer connections and pipes them to your chainweb-node over the tunnel. Your home node stays behind CGNAT; only outbound to the VPS is needed (which CGNAT allows). Cert stays on the home node where chainweb-node runs — VPS just moves raw TCP bytes. See §18 — VPS tunnel setup for the complete walkthrough (rent → DuckDNS → two install scripts → cert → register). Setup takes ~30 minutes once. |
Key point about dynamic public vs CGNAT: both are "non-static IPv4", but they behave fundamentally differently. Dynamic public = you own the IP for the duration of your lease; anyone dialing it reaches you. CGNAT = many customers share the IP at the same time; inbound traffic has no way to pick you. DuckDNS handling the IP-rotation problem is only relevant to the first case.
How to tell which one you have (2-minute test)
- Open your router’s admin UI (typically
192.168.1.1or192.168.0.1). Find WAN status / Network map / similar. Note the WAN IP the router reports. - On the same machine, open
https://whatismyip.com. Note the IP it shows.
- Router WAN IP == whatismyip.com IP→ you have a dedicated public IP (static or dynamic; doesn’t matter which for reachability). Set up port-forwarding and you’re done.
- Router WAN IP != whatismyip.com IP → CGNAT. Another NAT layer (operated by your ISP) sits between your router and the real internet. No amount of configuration on your side can reach past it.
Extra signal: if your router’s WAN IP falls in 100.64.0.0/10, that range is reserved for carrier-NAT and you’re definitely CGNAT’d. RFC1918 ranges (10., 172.16–31., 192.168.) on the WAN interface also mean some other NAT is in front of you — equally blocking for P2P.
If you’re on CGNAT — three options
- Call your ISP and ask for public IPv4. This is by far the most common fix and works on most residential fiber tariffs in the EU. At Romanian providers (RCS & RDS / Digi, Orange, Vodafone) the explicit phrasing that works is: “vreau IP public dedicat IPv4, pentru un serviciu care are nevoie de conexiune inbound” (I want a dedicated public IPv4, for a service that requires inbound connectivity). Result is usually a dynamic public IP — fine for StoaChain. Cost ranges from free to a few lei per month. Do NOT let the agent sell you a "business static IP" tariff (often €100–300/month) — that’s for enterprise customers who need an IP that never changes, which is overkill for a node. Dynamic public is enough.
- VPS jump-host + reverse tunnel.Rent a small cloud VPS (3–5 €/month, Hetzner CX11 or Contabo) with a public IPv4. Run a reverse TCP tunnel from your home node to the VPS (options: frp, rathole, wireguard + socat). Your node’s
p2p-hostnamebecomes the VPS’s hostname; peers dial the VPS and the tunnel pipes into your home box. Works today and is fully supported by chainweb — the VPS looks like a normal peer to the network. Trade-offs: +3–5 €/month recurring cost, +5–30 ms peering latency, one more failure domain (tunnel drop or VPS reboot = node offline until recovery), and you need to monitor the tunnel. Treat it as a bridge to a proper public IP, not a permanent solution. - Switch ISP.If your current provider insists they can’t give you public IPv4, a different provider in your area likely can. In Romania the three main residential fiber providers (RDS, Orange, Vodafone) all offer public IP on request, though coverage and willingness varies by region.
Mobile / 4G-LTE / 5G home internet is a dead end. Cellular operators essentially always use CGNAT on residential mobile data. Even premium “5G Fixed Wireless” home broadband products are typically CGNAT’d. A StoaChain node cannot be hosted on a cellular connection.
What about IPv6?
chainweb-node technically supports IPv6 — you can set --p2p-interface :: and advertise an AAAArecord. But that doesn’t help an IPv6-only operator in practice today:
- The majority of existing StoaChain peers run on VPS instances that are IPv4-only. They cannot dial an IPv6-only hostname.
- Peer reachability is a mutual condition — a node peers aren’t actually able to contact is operationally invisible, same as if it had no public address at all.
- As the network matures to dual-stack, IPv6 will become a real alternative. For now, plan on IPv4.
16.7 · Pre-registration checklist
Before you register a node at /admin/nodes/new:
- Dedicated public IPv4 confirmed per §16.6 — either static or dynamic-public is fine (DuckDNS or similar for the dynamic case). What is NOT fine is CGNAT-shared IP. Run the 2-minute router-WAN vs whatismyip.com test in §16.6 and confirm they match before you go any further. Without this, stop here— registering a CGNAT’d node wastes the operator’s hardware for zero Stoicism and no peering.
- Fresh Ubuntu 26.04 Resolute, 24.04 Noble (or 22.04 Jammy) install.
- SSH reachable on your chosen port from the hub’s public IP.
- A non-root user with
sudo, or root SSH password-login enabled (the hub prefers non-root + NOPASSWD sudoers; root is accepted but some distros block root SSH password-login by default). - NVMe or SATA SSD mounted with ≥ 100 GB free on the mount you intend to commit. The mount path goes into
--database-directoryduring the install wizard. - Domain name with an A record pointing at the box — needed for the certbot step in bootstrap.
The register-and-bootstrap flow takes 2–10 minutes depending on the network and the freshness of the image. The hub streams a live log of every step through the install wizard so the operator sees exactly what’s happening on their box.