Baremetal install (native systemd, no Docker)
The Quick start runs the clients as containers on the metal. This page covers the bare-process alternative: native beacond + bera-reth binaries as hardened systemd services, with no container runtime at runtime.
Same flags, same ports, same genesis bundle as the container path — pick whichever fits your ops. Artifacts: from-source/deploy/baremetal/.
Which path?
Both are first-class and interchangeable. Use containers (Quick start) for the simplest setup; use native systemd (this page) if you prefer no container runtime, tighter systemd hardening, or distro-native process management.
What it installs
/opt/krypton/bin/{beacond,bera-reth,krypton-*.run} # binaries + launch wrappers
/etc/krypton/krypton.env # config (0640, root:krypton)
/etc/krypton/network/{eth-genesis.json,spec.toml,kzg-trusted-setup.json} # bundle (ro)
/etc/krypton/jwt.hex # Engine-API secret (0600)
/var/lib/krypton/{reth,beacond} # chaindata — MUST be NVMe
/etc/systemd/system/{bera-reth,beacond}.service # hardened units (CL after EL)Everything runs as the unprivileged krypton system user.
Install
Prerequisites are the same as the container path minus Docker — see Prerequisites (NVMe at the data dir, NTP, firewall, a public IP) and the published network bundle. Then, as root:
cd l1/from-source/deploy/baremetal
# A remote bundle MUST be https and is verified against BUNDLE_SHA256 before extraction.
sudo BIN_SOURCE=images BUNDLE_URL=https://…/bundle.tar.gz BUNDLE_SHA256=<sha256> ./install.shinstall.sh creates the user/dirs, obtains the binaries, installs the bundle (asserting chainId == 473374), generates the JWT, and installs the wrappers + units.
Getting the binaries — BIN_SOURCE
| Mode | How | Docker? |
|---|---|---|
images (default) | extract the patched binaries from the from-source images (build once via build.sh) | once, to extract |
source | clone the pinned forks, apply from-source/patches/*, build natively (needs go ≥1.26 + Rust) | none |
prebuilt | copy operator-supplied BEACOND_BIN / BERA_RETH_BIN | none |
TIP
images reuses the exact, verified binaries from the from-source build with the least effort; source/prebuilt are fully Docker-free. All three install the same hardened units.
Configure & start
Edit /etc/krypton/krypton.env (MONIKER, EXT_IP, peers, role). Apply the firewall — only 30303/tcp+udp + 26656/tcp public (Ports & firewall). Then:
sudo systemctl enable --now bera-reth beacond
journalctl -u bera-reth -u beacond -f
cast chain-id --rpc-url http://127.0.0.1:8545 # 473374beacond starts after bera-reth and dials its engine on 127.0.0.1:8551.
Per-role config
| Role | Set in krypton.env |
|---|---|
| Validator | PAYLOAD_BUILDER=true; place priv_validator_key.json in /var/lib/krypton/beacond/config or set PRIV_VALIDATOR_LADDR=tcp://0.0.0.0:1234 for Horcrux threshold signing |
| RPC / explorer indexer | RPC_API=eth,net,web3,debug,trace, EL_SYNC_MODE= (archive), RPC_BIND=<VPN addr> |
| Seed | defaults; tiny host |
Validator key
Never run the same validator key on two nodes — equivocation is slashable. Use Horcrux threshold signing + Vault/KMS for production; the local-key path is for low-stakes/testnet only. See Validator.
Operate
- Upgrade: replace
/opt/krypton/bin/{beacond,bera-reth}(re-runinstall.shwith a new*_REF), thensystemctl restart(stop CL before EL on coordinated upgrades). - Logs/metrics:
journalctl -u …; EL metrics on:9001, CL CometBFT metrics on:26660(on by default) → monitoring. Both stay private — the firewall drops them (Ports & firewall). - Rollback:
beacond rollbackfor a bad block; keep the prior binary. - Troubleshooting: reference/troubleshooting.
Status
Deploy artifact — scripts are bash -n-clean but not yet run on real hardware; the public testnet isn't live yet. Pin the binary versions for production. Mainnet (47337) is the same with CHAIN_ID=47337, post-audit.