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.
The Control Panel — single TUI entry point for every operation
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
userpatchesconfiguration and scripts.
- What This Image Provides
- Hardware Requirements
- Building the Image
- Flashing & First Boot
- The Control Panel
- Integrated Dashboards and Services
- Recommended Setup Order
- Importing Validator Keys
- Daily Operations (After Reboot)
- File Locations
- Useful Commands
- Network Ports
- Troubleshooting
- Optional Hardening
- Project Layout
- Related Projects
- License
A headless Ubuntu 26.04 LTS (RELEASE=resolute) image targeting the Raspberry Pi 5,
pre-configured to run a solo-staking validator:
- Execution Layer — Geth (Ethereum PPA)
- Consensus Layer — Nimbus 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 thew3p-hwmSPI LCD dashboard - UPS integration —
w3p-upshost 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.
- 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
The image is produced by the Armbian Build Framework, configured via userpatches/config-w3p.conf.
git clone https://github.com/Web3-Pi/Web3-Pi-vOS.git
cd Web3-Pi-vOS
./compile.sh w3pThe 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- Loads userpatches/config-w3p.conf →
BOARD=rpi4b-w3p,BRANCH=current,RELEASE=resolute,BUILD_MINIMAL=yes. - Builds the kernel, bootloader, and rootfs in a chroot.
- 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.
- 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. - Packages an
.img.
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-w3ptargets the Raspberry Pi 5 despite the name. This is a quirk of the Armbianbcm2711board family, which covers both Pi 4 and Pi 5.
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.
- Insert the NVMe into the Pi 5's PCIe slot.
- Connect Ethernet.
- Power on and allow first-boot setup to finish. Its
rc.localsetup checks internet access, synchronizes time and finalizes the user account.
# 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.
Left: forced password change on first login. Right: MOTD banner with system stats — launch the Control Panel from here.
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.
sudo control-panelThe full path also works, and first boot creates a control-panel.sh symlink in /home/ethereum:
sudo /opt/web3pi/control-panel.shThe 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.
| # | 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.
Every Control Panel section is a self-contained whiptail menu. Click any thumbnail for full size.
![]() Navigating to Web3 Pi UPS |
![]() Web3 Pi UPS Install · service · live data |
![]() Pi-Under-Pressure 5-minute thermal stress test |
![]() Auto OC Detection Find max stable clock automatically |
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.
| 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.
Once you're SSH'd in and have launched the Control Panel:
- SSH Security → add your public key, then disable password auth.
- Eth Network Configuration → pick a network (start with
hoodi). - LUKS Encrypted Storage → create the encrypted partition (set a strong passphrase).
- Initial Sync → run trusted-node sync (skips weeks of genesis sync).
- Service Management → enable + start Geth and Nimbus beacon.
- Monitoring → wait for both EL and CL to fully sync.
- Validator Management → import keys, set fee recipient, start the validator.
After EL + CL are fully synced and LUKS is unlocked:
# From your workstation
scp keystore-*.json ethereum@<PI_IP>:~/validator_keys/Then in the Pi's Control Panel:
Validator Management → Import Validator Keys → From ~/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).
- Copy keystores to a USB stick.
- Plug it into the Pi.
- Validator Management → Import Validator Keys → From USB drive.
Always keep an offline backup of your keystores. They're required for Voluntary Exit.
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 ValidatorOr directly:
sudo /opt/web3pi/unlock-luks.sh
sudo /opt/web3pi/start-validator.shGeth and Nimbus beacon node start automatically on boot if you enabled them.
| 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.
# 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| 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.
Services won't start → Control Panel → Service Management → view logs, or:
sudo journalctl -u geth -n 100
sudo journalctl -u nimbus-beacon-node -n 100Validator won't start → Verify LUKS is unlocked (Control Panel → LUKS Encrypted Storage → Check 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.
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.
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.
- Web3-Pi-UPS — UPS hardware and firmware
- Web3-Pi-UPS-Service — Linux UPS agent and local diagnostics
- Web3-Pi-UPS-Panel — remote UPS and host monitoring
- Web3 Pi LCD — SPI LCD dashboard (
w3p-hwm)
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.














