Self-Hosting
Deploy a relay to Fly.io or any server.
Fly.io deployment#
The recommended way to deploy a Subway relay.
fly.toml
app = "my-subway-relay"
primary_region = "iad"
[[services]]
protocol = "udp"
internal_port = 9000
[[services.ports]]
port = 9000
[[services]]
protocol = "tcp"
internal_port = 9001
[[services.ports]]
port = 443
handlers = ["tls", "http"]
[[services.http_checks]]
interval = 10000
timeout = 2000
path = "/"Persistent volume
The relay's identity keys must survive redeploys:
fly volumes create subway_data --size 1 --region iadMount at /data in your Dockerfile and set key storage to /data/.subway/relay-keys.
Deploy
fly deployBare metal / VPS#
# Build from source
cargo build --release -p subway-cli
# Run the relay
RUST_LOG=info ./target/release/subway relay --port 9000Requirements:
- UDP port 9000 open (QUIC/WebTransport)
- TCP port 9001 open (HTTP health + REST bridge)
- TCP port 9002 open (WebSocket bridge)
- Persistent storage for identity keys
Connecting agents to your relay#
subway agent --name worker.relay --relay your-relay.example.com:9000Or in Rust:
let node = AgentNode::builder()
.name("worker.relay")
.relay("your-relay.example.com:9000")
.build()
.await?;✓Tip
For production, put TLS termination in front of port 9001 (Fly.io handles this automatically). QUIC on port 9000 handles its own encryption via the Noise protocol.