Getting started
From zero to a two-node mesh: install, configure a standalone node, add a route, then join a peer.
1. Install the daemon
Run the installer on every VPS you want in the fleet:
curl -fsSL https://bridgemesh.space/install.sh | sh
The installer places the binary in /usr/local/bin, creates a
bridge system user and /etc/bridge, writes a minimal
config if none exists, and enables a systemd service. See
Install for details and manual installation.
2. Minimal standalone config
A single node runs fine on its own: omit the [node] section entirely
and BRIDGE operates in standalone mode. Edit /etc/bridge/bridge.toml:
enable_telemetry = false
[proxy]
mode = "Direct" # Direct | SniPassthrough | Managed
listeners = ["http"]
http_addr = "0.0.0.0:80"
[dashboard]
enabled = true
listen_addr = "127.0.0.1:9090"
[ipc]
enabled = true
socket_path = "/tmp/bridge.sock"
[logger]
level = "INFO"
format = "text"
Configuration is auto-discovered from ./bridge.toml, then
$BRIDGE_CONFIG, then /etc/bridge/bridge.toml. TOML and
YAML are both accepted.
3. Add your first route
Point a hostname at an upstream on this node by appending a
[[services]] entry:
[[services]]
url = "https://app.example.com"
node_id = "node-01"
upstream = "127.0.0.1:3000"
In Direct mode the daemon reverse-proxies HTTP for that hostname to
the upstream. Routes can also come from Docker auto-discovery: labeled containers
become routes automatically when [discovery] is enabled.
4. Run it
If you used the installer, the service is already running:
systemctl status bridge
bridge status
Without systemd, run the daemon in the foreground:
bridge --config /etc/bridge/bridge.toml
5. Check the dashboard
Open http://127.0.0.1:9090 on the node. The embedded operations
dashboard shows the node, its routes, and live events over a WebSocket stream.
It binds to loopback by default.
6. Add a second node
To turn standalone nodes into a fleet, give each node a cluster identity and tell them about each other. On node-01:
# This node's cluster identity
[node]
id = "node-01"
mesh_ip = "10.8.0.1"
endpoint = "203.0.113.10:51820"
listen_port = 51820
priority = 100
[[nodes]]
node_id = "node-01"
endpoint = "203.0.113.10:51820"
On node-02, use its own identity and list node-01 as a seed so gossip has a starting point:
[node]
id = "node-02"
mesh_ip = "10.8.0.2"
endpoint = "203.0.113.11:51820"
listen_port = 51820
priority = 50
[[seeds]]
endpoint = "203.0.113.10:51820"
[[nodes]]
node_id = "node-01"
endpoint = "203.0.113.10:51820"
The WireGuard mesh comes up on the 10.8.0.x overlay; keys are
auto-generated if not configured. The priority field feeds the bully
election: the highest-priority alive node becomes leader and holds the ingress
entrypoint. Restart both daemons after editing the config.
7. Watch the fleet converge
Within seconds, gossip membership converges. Confirm from either node:
bridge cluster
Both nodes appear in the dashboard's nodes and mesh views, one marked as leader. From here, pick an ingress handoff tier, tune configuration, and learn the day-two operations.