Skip to content
 
 

Repository files navigation

Web3 Pi Staking — vOS

Ethereum solo-staking OS for Raspberry Pi 5, based on Armbian Minimal. Pre-configured Geth + Nimbus split architecture, LUKS-encrypted validator keys, nftables firewall, and a full TUI — the Control Panel — to drive everything.

WARNING — DEVELOPMENT STAGE This project is in active development. Use at your own risk. Always validate on a testnet (hoodi) before considering mainnet.

Web3 Pi Control Panel — main menu

The Control Panel — single TUI entry point for every operation

Documentation Map

This README is the entry point. For deeper material, jump to:

Document What's in it
desc.md Full system reference — architecture, users, LUKS internals, nftables rules, services, packages, every Control Panel option
getting-started.md Step-by-step staking walkthrough (network choice, keys import, daily ops)

If you want to understand how the system is wired internally (build phases, user model, encrypted partition layout, service dependencies, port table, firewall chains), read desc.md. Build defaults and installed paths are defined by the checked-in userpatches configuration and scripts.

Table of Contents

What This Image Provides

A headless Ubuntu 26.04 LTS (RELEASE=resolute) image targeting the Raspberry Pi 5, pre-configured to run a solo-staking validator:

  • Execution LayerGeth (Ethereum PPA)
  • Consensus LayerNimbus beacon node (apt.status.im)
  • Validator Client — Nimbus validator, isolated from the beacon node, keys on LUKS
  • Local monitoring — fullscreen w3p-dashboard, optional HDMI autostart, and the w3p-hwm SPI LCD dashboard
  • UPS integrationw3p-ups host metrics, service control and graceful shutdown with Web3 Pi UPS hardware
  • Optional services — MEV-Boost relay configuration and LTE internet failover, both disabled by default

Hardening highlights:

  • nftables firewall, restrictive INPUT, IPv6 disabled
  • Locked root, separated system users (ethereum, el, cl, signer)
  • LUKS2 (AES-XTS, Argon2id) partition for validator keys, manually unlocked per boot
  • SSH with rate-limited brute-force protection, optional FIDO2 hardware-key enforcement
  • Systemd sandboxing on the Ethereum client units (NoNewPrivileges, PrivateTmp, ProtectSystem=strict)

Full details: desc.md.

Hardware Requirements

  • Raspberry Pi 5 (16 GB RAM recommended — required for mainnet)
  • NVMe SSD via PCIe HAT (2 TB+ for mainnet; system boots from NVMe, no SD card)
  • Active cooling (fan + heatsink; passive is not enough under sustained load)
  • Official 5.1 V / 5 A power supply
  • Wired Ethernet — Wi-Fi/LTE not recommended for staking
  • Optional: Web3 Pi UPS for power-loss protection

Building the Image

The image is produced by the Armbian Build Framework, configured via userpatches/config-w3p.conf.

Build

git clone https://github.com/Web3-Pi/Web3-Pi-vOS.git
cd Web3-Pi-vOS
./compile.sh w3p

The profile sets PREFER_DOCKER=yes and uses an ubuntu:noble build container; the resulting image uses the separately configured resolute userspace. Have Docker running before starting, including Docker Desktop on macOS. The build downloads its dependencies and client packages; keep the checkout path free of spaces.

Optional release packaging (compress + checksum):

./compress.sh
# → output/images/Web3Pi-SoloStakingOS.img.xz
# → output/images/Web3Pi-SoloStakingOS.img.xz.sha256

What ./compile.sh w3p does

  1. Loads userpatches/config-w3p.confBOARD=rpi4b-w3p, BRANCH=current, RELEASE=resolute, BUILD_MINIMAL=yes.
  2. Builds the kernel, bootloader, and rootfs in a chroot.
  3. Runs userpatches/customize-image.sh inside the chroot — installs Geth/Nimbus, creates users, deploys the Control Panel and service files, configures SSH/firewall and installs the dashboards and optional services.
  4. The customization script installs selected files from userpatches/overlay/ into their runtime locations (/opt/web3pi, /etc, /usr/local). The overlay is not a mirror of the target root filesystem.
  5. Packages an .img.

Output

output/images/Armbian-unofficial_<ver>_Rpi4b-w3p_resolute_current_<kver>.img

Image size and boot time depend on the build and hardware. The customization script fetches the latest UPS and LCD release binaries at build time; if downloads are unavailable, it logs a warning and leaves those components for installation through the Control Panel. MEV-Boost uses a pinned version with a SHA-256 check and also remains optional if its download fails.

Note on the board name: BOARD=rpi4b-w3p targets the Raspberry Pi 5 despite the name. This is a quirk of the Armbian bcm2711 board family, which covers both Pi 4 and Pi 5.

Flashing & First Boot

1. Flash to NVMe

Use Balena Etcher (or dd) to write the .img to an NVMe drive connected to your workstation. There is no SD-card path — the Pi boots directly from NVMe.

2. First boot

  1. Insert the NVMe into the Pi 5's PCIe slot.
  2. Connect Ethernet.
  3. Power on and allow first-boot setup to finish. Its rc.local setup checks internet access, synchronizes time and finalizes the user account.

3. Find the Pi and SSH in

# Try mDNS first
ssh ethereum@rpi4b-w3p.local

# Or use the IP from your router's DHCP table
ssh ethereum@<IP_ADDRESS>

Default credentials:

  • Username: ethereum
  • Password: ethereum

You will be forced to change the password on first login.

Forced password change on first login

Left: forced password change on first login. Right: MOTD banner with system stats — launch the Control Panel from here.

The Control Panel

The Control Panel is a whiptail-based TUI for node setup and operations. It wraps the configuration files and systemd actions used by this image.

Launch it

sudo control-panel

The full path also works, and first boot creates a control-panel.sh symlink in /home/ethereum:

sudo /opt/web3pi/control-panel.sh

The panel permits one session at a time to avoid concurrent configuration changes. Its central config uses W3P_* keys; saving through the current panel migrates recognized legacy names to this format.

Top-level menu

# Section What it does
1 Eth Network Configuration Network, Geth/Nimbus P2P ports, Geth chain-history retention
2 SSH Security Add/remove keys, toggle password auth, require FIDO2 hardware keys
3 LUKS Encrypted Storage Create/unlock encrypted partition for validator keys, change passphrase
4 Initial Sync Trusted-node (checkpoint) sync from a curated server list
5 Service Management Start/stop/enable Geth, Nimbus beacon, Nimbus validator; view logs
6 Monitoring Fullscreen dashboard, HDMI autostart, sync status, peers, resources and disk usage
7 Data Management Wipe Geth / Nimbus / signer / all data (with double-confirmation)
8 System Hostname, timezone, keyboard, EEPROM/OC tools, UPS, LCD, reboot/shutdown
9 Validator Management Import keys (SSH or USB), fee recipient, graffiti, MEV-Boost, start/stop, voluntary exit
U Client Updates Check & apply Geth / Nimbus updates (APT), with safe service restarts
F Internet Failover (LTE) WAN failover to an LTE modem

The default network is hoodi. The menu also contains mainnet and the legacy holesky option; its presence is not a guarantee that a network or its listed endpoints are operational. The MEV-Boost module has relay lists for Hoodi and mainnet, with no Holesky relay list.

See desc.md §8 for the menu reference and the modules for the current implementation.

Submenu gallery

Every Control Panel section is a self-contained whiptail menu. Click any thumbnail for full size.

Eth Network Configuration
Eth Network Configuration
Network · Geth/Nimbus P2P ports
SSH Security
SSH Security
Keys · password auth · FIDO2
LUKS Encrypted Storage
LUKS Encrypted Storage
Encrypted partition for validator keys
Initial Sync
Initial Sync
Trusted-node checkpoint sync
Service Management
Service Management
Geth · Nimbus beacon · validator
Monitoring
Monitoring
Sync · peers · RAM/CPU · disk
Data Management
Data Management
Wipe Geth / Nimbus / signer data
System
System
Hostname · timezone · EEPROM · OC
Validator Management
Validator Management
Import keys · fee recipient · exit

System submenu — power & overclocking tools

System menu — Web3 Pi UPS highlighted
Navigating to Web3 Pi UPS
Web3 Pi UPS
Web3 Pi UPS
Install · service · live data
Pi-Under-Pressure stress test
Pi-Under-Pressure
5-minute thermal stress test
Auto OC Detection
Auto OC Detection
Find max stable clock automatically

Web3 Pi UPS — live telemetry view

Web3 Pi UPS → Live UPS data — real-time power telemetry (source, V/I, battery SoC, thermal, faults) alongside host stats (CPU, memory, disk, network, Ethereum status). Project: Web3-Pi/Web3-Pi-UPS.

Integrated Dashboards and Services

Component Access Installation / boot behavior
w3p-dashboard Monitoring → Live Dashboard, or sudo w3p-dashboard Included in the image; HDMI console autostart is disabled until enabled in Monitoring
w3p-ups System → Web3 Pi UPS Pre-installed and enabled when its release download succeeds; menu provides install/update, config, logs and watch telemetry
w3p-hwm System → LCD Display Pre-installed and enabled when its release download succeeds; menu provides install/update, service control, logs and SPI status
mev-boost Validator Management → MEV Boost Disabled by default; menu configures relays and coordinates the Nimbus builder settings
w3p-failover Internet Failover (LTE) Included but disabled by default; configured separately from the UPS telemetry modem

The terminal dashboard shows Ethereum sync/peers, WAN failover, resources, networking and logs, including a dmesg source. Enabling HDMI autostart replaces the login prompt on tty1; SSH access remains available. This is separate from the physical SPI LCD managed by w3p-hwm.

The UPS agent reports each Ethereum unit's service state to the remote UPS panel. Its default units are geth, nimbus-beacon-node and nimbus-validator; if you change clients, update both monitoring and command-whitelist entries in /etc/w3p-ups/config.toml. Chain-sync progress is available through the node monitoring tools.

Recommended Setup Order

Once you're SSH'd in and have launched the Control Panel:

  1. SSH Security → add your public key, then disable password auth.
  2. Eth Network Configuration → pick a network (start with hoodi).
  3. LUKS Encrypted Storage → create the encrypted partition (set a strong passphrase).
  4. Initial Sync → run trusted-node sync (skips weeks of genesis sync).
  5. Service Management → enable + start Geth and Nimbus beacon.
  6. Monitoring → wait for both EL and CL to fully sync.
  7. Validator Management → import keys, set fee recipient, start the validator.

Importing Validator Keys

After EL + CL are fully synced and LUKS is unlocked:

Option A — Over SSH (recommended)

# From your workstation
scp keystore-*.json ethereum@<PI_IP>:~/validator_keys/

Then in the Pi's Control Panel:

Validator ManagementImport Validator KeysFrom ~/validator_keys

You'll be prompted for the keystore password. After import, keystore files are moved to the encrypted LUKS partition (needed for Voluntary Exit).

Option B — Via USB drive

  1. Copy keystores to a USB stick.
  2. Plug it into the Pi.
  3. Validator ManagementImport Validator KeysFrom USB drive.

Always keep an offline backup of your keystores. They're required for Voluntary Exit.

Daily Operations (After Reboot)

LUKS does not auto-unlock — that's by design. After every reboot:

sudo /opt/web3pi/control-panel.sh
# → LUKS Encrypted Storage → Unlock LUKS
# → Validator Management → Start Validator

Or directly:

sudo /opt/web3pi/unlock-luks.sh
sudo /opt/web3pi/start-validator.sh

Geth and Nimbus beacon node start automatically on boot if you enabled them.

File Locations

Component Path
Control Panel /opt/web3pi/control-panel.sh
Central config /opt/web3pi/config (W3P_* keys)
Helper scripts /opt/web3pi/ (setup-luks.sh, unlock-luks.sh, start-validator.sh, …)
Logs /opt/web3pi/logs/
Geth data /var/lib/el
Nimbus beacon data /var/lib/cl
Validator keys /home/signer/keys (LUKS-encrypted)
Key import staging /home/ethereum/validator_keys
UPS agent config /etc/w3p-ups/config.toml
Terminal dashboard /usr/local/share/w3p-dashboard/ (w3p-dashboard command)
SPI LCD binary /usr/local/bin/w3p-hwm
Failover config /etc/w3p-failover.conf

Full layout: desc.md §2.2.

Useful Commands

# Control Panel — your main entry point
sudo /opt/web3pi/control-panel.sh

# Live terminal dashboard
sudo w3p-dashboard

# Service control
sudo systemctl status geth
sudo systemctl status nimbus-beacon-node
sudo systemctl status nimbus-validator

# Logs
sudo journalctl -u geth -f
sudo journalctl -u nimbus-beacon-node -f

# Sync checks
sudo -u el geth attach --datadir /var/lib/el --exec "eth.syncing"
curl -s http://127.0.0.1:5052/eth/v1/node/syncing | jq

# Firewall + disk
sudo nft list ruleset
df -h

Network Ports

Port Proto Service Exposure
22 TCP SSH Public, rate-limited (5/min)
30303 TCP/UDP Geth P2P Public — forward on router
9000 TCP/UDP Nimbus P2P Public — forward on router
8545 TCP Geth HTTP-RPC Localhost only
8546 TCP Geth WebSocket RPC Localhost only
8551 TCP Engine API (JWT) Localhost only
5052 TCP Nimbus REST API Localhost only
18550 TCP MEV-Boost builder API (when enabled) Localhost only

Forward 30303 and 9000 on your router to maximize peer count and improve sync speed.

Troubleshooting

Services won't start → Control Panel → Service Management → view logs, or:

sudo journalctl -u geth -n 100
sudo journalctl -u nimbus-beacon-node -n 100

Validator won't start → Verify LUKS is unlocked (Control Panel → LUKS Encrypted StorageCheck Status) and that fee recipient is configured.

Sync stuck → Check peers in Monitoring; verify port forwarding for 30303/9000.

Can't find the Pi → Try ping rpi4b-w3p.local (mDNS), or check your router DHCP table.

More cases in getting-started.md.

Optional Hardening

Use SSH Security to manage keys, password authentication and FIDO2 enforcement. The image's firewall is defined in userpatches/overlay/etc/nftables.conf; DNS and routing defaults also involve the failover network configuration. Review those files together before changing network policy. See desc.md for the system security reference.

Project Layout

Web3-Pi-vOS/
├── compile.sh                       # Armbian build entry point
├── compress.sh                      # Image compression and SHA-256 sidecar
├── userpatches/
│   ├── config-w3p.conf              # Build configuration (BOARD, RELEASE, options)
│   ├── customize-image.sh           # Chroot customization (build-time)
│   └── overlay/
│       ├── rc.local                 # First-boot setup (runtime)
│       ├── control-panel.sh         # Installed as /opt/web3pi/control-panel.sh
│       ├── control-panel/           # Shared library and menu modules
│       ├── dashboard/               # Fullscreen terminal dashboard
│       ├── config                   # Installed as /opt/web3pi/config
│       └── etc/                     # Firewall, network and other system files
├── config/boards/rpi4b-w3p.conf     # Custom board definition
├── desc.md                          # ⭐ Full system reference
├── getting-started.md               # Step-by-step staking guide
└── README.md                        # You are here

The two-phase setup (chroot build-time vs. on-device first-boot) is described in desc.md §2.1, with executable steps in customize-image.sh and rc.local.

Related Projects

License

See LICENSE. Inherits the Armbian build framework license; project-specific additions follow the same terms.

For the full system reference — architecture diagrams, user model, every Control Panel submenu, packages, services, and security details — see desc.md.

About

Ethereum solo-staking OS for Raspberry Pi 5 — Armbian-based image with Geth + Nimbus, LUKS-encrypted validator keys, nftables firewall, and a whiptail Control Panel TUI.

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages