Installation Guide

Connect any device to your NetFlux network in under 60 seconds. One command handles everything — WireGuard installation, network join, and systemd service setup.

No prior VPN experience needed. NetFlux handles WireGuard key generation, IP assignment, and peer discovery automatically. You just run one command.

Quick start

The fastest path from zero to a connected device is three steps:

1
Create a network
Sign in to your dashboard and click + New network. Give it a name and keep the default IP pool 10.10.0.0/24. You'll get a network ID and join token.
Open dashboard →
2
Run the install command
Copy the install command from the dashboard and run it on each device you want to connect. Replace the placeholders if running manually.
curl -fsSL https://api.net-flux.com/install.sh | sudo bash -s -- \
  --token      YOUR_JOIN_TOKEN   \
  --network    YOUR_NETWORK_ID   \
  --controller https://api.net-flux.com
Get your exact command pre-filled (with your real token and network ID) by clicking Add device on any network in your dashboard.
3
Verify the connection
The agent prints your virtual IP on success. Ping another device on the same network to verify connectivity.
  ✓ NetFlux connected!
    Virtual IP:  10.10.0.2
    Peers:       1 online
    Planet:      Singapore (14ms)

# Test connectivity to another device
ping 10.10.0.1
PING 10.10.0.1: 56 data bytes
64 bytes from 10.10.0.1: icmp_seq=0 ttl=64 time=18.4 ms

How it works

NetFlux creates a WireGuard virtual network interface (rnet0) on each device and assigns it a private virtual IP (e.g. 10.10.0.x). Devices communicate directly peer-to-peer when possible, or through a relay node when NAT traversal fails.

ComponentWhat it does
AgentRuns on your device. Creates the WireGuard interface, polls the controller for peers, manages keys.
ControllerREST API at api.net-flux.com. Manages networks, assigns IPs, authenticates join tokens.
Planet nodeUDP rendezvous server. Helps peers find each other's real IP and port. Falls back to relay when P2P fails.

Requirements

RequirementDetails
OSLinux kernel 5.6+ (WireGuard built-in), Raspberry Pi OS Bullseye+, Ubuntu 20.04+, Debian 11+
Architecturex86_64 (AMD64), ARM64, ARMv7 (Raspberry Pi)
Root accessRequired — the agent creates a kernel network interface
Outbound UDPPort 51820 (WireGuard) and 7447 (planet) — falls back to TCP 443 if blocked
Python3.8+ (installed automatically if missing)
macOSSupported via WireGuard App — see macOS section
WindowsSupported via WSL2 — see Windows section

Linux / Ubuntu

Works on Ubuntu, Debian, and any distribution with apt. The installer detects your OS, installs WireGuard if needed, and configures a systemd service that starts automatically on boot.

# Run as root or with sudo
curl -fsSL https://api.net-flux.com/install.sh | sudo bash -s -- \
  --token      YOUR_JOIN_TOKEN     \
  --network    YOUR_NETWORK_ID     \
  --controller https://api.net-flux.com

# Expected output:
  · Detecting OS: Ubuntu 22.04 (x86_64)
  · Installing WireGuard...
  · Connecting to nearest planet: Frankfurt (8ms)
  · Joining network...
  ✓ Connected! Virtual IP: 10.10.0.2

Manage the service

# Check status
systemctl status netflux

# View live logs
journalctl -u netflux -f

# Restart after config change
sudo systemctl restart netflux

# Uninstall
curl -fsSL https://api.net-flux.com/install.sh | sudo bash -s -- --uninstall

Raspberry Pi

Tested on Raspberry Pi 3, 4, and 5 running Raspberry Pi OS (64-bit and 32-bit). The install command is identical — the installer auto-detects ARM architecture.

# Same command as Linux — works on RPi OS Bullseye and Bookworm
curl -fsSL https://api.net-flux.com/install.sh | sudo bash -s -- \
  --token      YOUR_JOIN_TOKEN     \
  --network    YOUR_NETWORK_ID     \
  --controller https://api.net-flux.com
💡
Raspberry Pi OS Lite (headless) — works perfectly. The agent runs as a background service and doesn't need a desktop environment. Ideal for robots and embedded deployments.
Raspberry Pi OS Buster (older): WireGuard may need manual installation. Run sudo apt install wireguard first, then run the NetFlux install command.

Docker

Run the agent in a Docker container. Requires --privileged and --network host so the container can create the WireGuard interface on the host.

docker run -d \
  --name        netflux-agent   \
  --privileged                   \
  --network     host             \
  --restart     unless-stopped   \
  -e NETFLUX_TOKEN=YOUR_JOIN_TOKEN    \
  -e NETFLUX_NETWORK=YOUR_NETWORK_ID  \
  -e NETFLUX_CONTROLLER=https://api.net-flux.com \
  ghcr.io/alicia-bots/netflux-agent:latest

Docker Compose

# docker-compose.yml
services:
  netflux:
    image: ghcr.io/alicia-bots/netflux-agent:latest
    privileged: true
    network_mode: host
    restart: unless-stopped
    environment:
      - NETFLUX_TOKEN=YOUR_JOIN_TOKEN
      - NETFLUX_NETWORK=YOUR_NETWORK_ID
      - NETFLUX_CONTROLLER=https://api.net-flux.com

Windows (WSL2)

Run the Linux agent inside WSL2 (Windows Subsystem for Linux). Requires WSL2 with Ubuntu 22.04.

# In Windows PowerShell (run as Administrator)
wsl --install -d Ubuntu-22.04

# Then open WSL Ubuntu and run the standard install command
curl -fsSL https://api.net-flux.com/install.sh | sudo bash -s -- \
  --token      YOUR_JOIN_TOKEN   \
  --network    YOUR_NETWORK_ID   \
  --controller https://api.net-flux.com

Create a network

You can create networks via the dashboard or the REST API.

Via dashboard

Go to api.net-flux.com → click + New network → enter a name → click Create. The network ID and join token are shown immediately. Save the join token — it's only shown once.

Via API

curl -s -X POST https://api.net-flux.com/api/v1/networks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "My Network", "ip_pool": "10.10.0.0/24"}'

# Response:
{
  "network_id":  "c935163e6bac957e",
  "name":        "My Network",
  "ip_pool":     "10.10.0.0/24",
  "join_token":  "5487c2cb89979873..."
}

Join tokens

A join token is a one-time secret that authorises a device to join a specific network. Any device with a valid token can join — share tokens carefully.

# Create a new join token for a network
curl -s -X POST https://api.net-flux.com/api/v1/networks/NETWORK_ID/tokens \
  -H "Authorization: Bearer YOUR_API_KEY"

{"join_token": "7a26797531929275..."}
Tokens don't expire by default. Create a new token for each deployment and avoid sharing the same token across multiple devices you don't control.

NetFlux CLI — headless Linux servers

The NetFlux CLI lets you connect any Linux server or robot without a web UI. Install it once, then use simple commands to join networks, check status, and manage peers.

Install the CLI

curl -fsSL https://api.net-flux.com/netflux -o /usr/local/bin/netflux && chmod +x /usr/local/bin/netflux

Join a network

Get your network ID and join token from the dashboard, then run:

sudo netflux join YOUR_NETWORK_ID --token YOUR_JOIN_TOKEN

# Optional: set a display name for this device
sudo netflux join YOUR_NETWORK_ID --token YOUR_JOIN_TOKEN --name "Warehouse Robot 3"

# Expected output:
  · WireGuard found
  · Joining network abc123...
  · Starting interface...
  ╔════════════════════════════════════════╗
  ║   NetFlux connected!                   ║
  ╚════════════════════════════════════════╝

  Virtual IP:  10.10.0.3
  Peers:       2 connected
  Network:     YOUR_NETWORK_ID

Commands

CommandDescription
netflux join <id> --token <token>Join a network. Installs WireGuard if needed, sets up auto-reconnect on boot.
netflux statusShow current virtual IP, WireGuard interface status, and connected peers.
netflux peersList all devices currently connected to the same network.
netflux updateFetch the latest peer list from the controller and update WireGuard config.
netflux leaveDisconnect from the network and stop all NetFlux services.
netflux uninstallRemove NetFlux completely — WireGuard config, services, and identity files.
💡
Auto-reconnect on boot: After running netflux join, the WireGuard interface is registered with systemd so it reconnects automatically on every reboot. The dashboard poller also runs as a systemd service to keep the device showing Online.

Check it's working

# Show virtual IP and WireGuard tunnel
netflux status
NetFlux status:
interface: rnet0
  public key: abc123...
  listening port: 51820
Virtual IP: 10.10.0.3

# List peers on your network
netflux peers
  2 peer(s):
  · 10.10.0.1    warehouse-robot-1    Online
  · 10.10.0.2    dev-laptop           14s ago

# Ping another device
ping 10.10.0.1
64 bytes from 10.10.0.1: icmp_seq=0 ttl=64 time=12.3 ms

# SSH into another device on the network
ssh user@10.10.0.1

CLI reference

All flags can also be set via environment variables.

FlagEnv varDescription
--tokenNETFLUX_TOKENJoin token from the dashboard (required)
--networkNETFLUX_NETWORKNetwork ID (required)
--controllerNETFLUX_CONTROLLERController URL (default: https://api.net-flux.com)
--planetNETFLUX_PLANETOverride planet server address (host:port)
--ifaceWireGuard interface name (default: rnet0)
--identityIdentity file path (default: /etc/netflux/identity.json)
--uninstallRemove NetFlux and clean up all files

ROS2 setup

After connecting your devices, configure ROS2 to use the NetFlux virtual network for discovery. Without this, ROS2 uses multicast which doesn't work over VPN.

# Set on every ROS2 machine in the network
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export ROS_DOMAIN_ID=42
export ROS_IP=10.10.0.X   # your NetFlux virtual IP

# Tell CycloneDDS to discover peers by IP, not multicast
export CYCLONEDDS_URI='<CycloneDDS><Domain><Discovery><Peers>
  <Peer address="10.10.0.1"/>
  <Peer address="10.10.0.2"/>
</Peers></Discovery></Domain></CycloneDDS>'

# Test it
ros2 topic list
/cmd_vel
/odom
/scan
/tf
Dashboard auto-generation. Click Get install command on any network in your dashboard to get the exact CycloneDDS config pre-filled with all your device IPs.

Safety watchdog

The safety watchdog monitors the VPN link and publishes a zero Twist message to /cmd_vel if the connection drops for more than 500ms. This stops your robot from continuing the last command indefinitely.

# Run the watchdog node alongside your robot control stack
ros2 run netflux watchdog \
  --ros-args \
  -p timeout_ms:=500          \
  -p monitored_peer:=10.10.0.1 \
  -p cmd_vel_topic:=/cmd_vel

# Output when link drops:
[netflux_watchdog]: Link to 10.10.0.1 lost (523ms) — publishing STOP

REST API reference

All endpoints require a Bearer token in the Authorization header.

EndpointDescription
POST /api/v1/auth/signupCreate a new account
POST /api/v1/auth/loginSign in, returns JWT token
GET /api/v1/networksList all networks
POST /api/v1/networksCreate a new network
GET /api/v1/networks/:idGet network + device list
POST /api/v1/networks/:id/joinDevice joins network (agent calls this)
GET /api/v1/networks/:id/peersGet current peer list (agent polls this)
POST /api/v1/networks/:id/tokensCreate a new join token
DELETE /api/v1/networks/:id/members/:node_idRemove a device
GET /api/v1/billing/usageGet device usage and plan info
GET /healthHealth check

Troubleshooting

Device shows offline in dashboard

The dashboard marks devices as offline if not seen in the last 2 minutes. Check the agent is running:

systemctl status netflux
journalctl -u netflux -n 50

Can't ping another device

# Check the WireGuard interface is up
ip addr show rnet0

# Check peers are configured
sudo wg show rnet0

# Check there's a route
ip route show | grep rnet0

Behind a strict corporate firewall

If UDP port 51820 and 7447 are blocked, NetFlux falls back to TCP/443 automatically. If the connection still fails, check that outbound TCP 443 is allowed.

Invalid join token error

Join tokens are single-use per device. If a token was already used by a different device or the command was run twice, create a new token from your dashboard.