Getting started
This page takes you from bare hardware to a running HALO network with one gateway and one node. A HALO network has exactly one gateway — the control-plane and mesh exit point — and one or more nodes peered to it over HaLow.
Prerequisites
- A Raspberry Pi 4B (or compatible ARM board) for the gateway, with upstream connectivity on
eth0. - One or more Pi-class boards for nodes, each with a Morse Micro HaLow radio.
- A HALO
.img.gzimage. Build it on a Pi with thepi-genbuilder indeploy/image/— do not build the image on Windows, where path handling corrupts the build. - A workstation to flash the image and reach the gateway over LAN.
Flash and first boot
Write the image to each board's SD card and boot it.
zcat halo-<version>.img.gz | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync
The image carries all five binaries (gateway-api, halo-agent, halo-mesh, halo-field, haloctl), the custom wpa_supplicant, mesh scripts, the frontend, nginx, dnsmasq, wireguard-tools, and gpsd. A first-boot provisioner reads halo.toml from the FAT32 boot partition and enables services according to the node role.
Role-based service enablement decides what comes up:
- Gateway nodes start
nginxandgateway-api. - Remote nodes start
halo-fieldon port80.
halo-meshis the root dependency. Ifsystemctl is-enabled halo-meshreturnsdisabled, no HALO services start on boot. Always verify it is enabled after any hardware change.
Bring up the gateway
On the gateway, run the interactive setup wizard. It prompts for node name and ID, role, mesh SSID/PSK/country/channel, and admin credentials, then writes /etc/halo/config.yaml.
haloctl setup
Confirm the gateway is healthy. Every check should report PASS.
haloctl gateway-health
A healthy gateway shows halo-mesh, gateway-api, and halo-agent active, wlan0 in mesh point mode, a bat0 address on 10.41.0.0/24, a wg0 address on 10.42.0.0/24, and a recent WireGuard handshake.
Reach HALO Portal
HALO Portal is served by nginx on port 80 of the gateway. Open it in a browser and log in.
http://<gateway-lan-ip>/
Default credentials are admin / ethrx. On first login the gateway forces an admin password change. The API itself listens on port 8080; nginx proxies it and the WebSocket stream behind port 80.
Join the first node
Node onboarding is automatic. A node boots, joins the 802.11s mesh, peers with the gateway, and acquires a bat0 address via DHCP. It then registers a WireGuard key and starts reporting:
- The node peers with the gateway over HaLow and gets an underlay IP on
10.41.0.0/24. - It calls
POST /v1/mesh/wg-register, exchanges WireGuard keys, and receives an overlay IP on10.42.0.0/24. - The agent authenticates and runs a heartbeat loop, posting telemetry every 5 seconds.
- The node appears in the topology and on the dashboard.
From the gateway you can list known nodes and confirm reachability.
haloctl gateway-peers
If a node needs admin approval before it is trusted, approve it from the gateway.
haloctl admin list
haloctl admin approve <registration-id>
Verify the mesh
Check the full node status dashboard on any device.
haloctl status
From a remote node, confirm it can reach the gateway through the mesh.
haloctl remote-diag
SSH over the WireGuard overlay (
10.42.0.x) is unreliable during banner exchange. Prefer LAN IPs when available, or usecurl http://10.42.0.2:80/api/diagfrom the gateway as a diagnostic fallback —halo-fieldalways responds even when SSH does not.
Where to go next
- Learn the platform model in architecture.
- Understand the radio and tunnel layers in networking.
- Build your first automation in HALO Flows.
