Scale from one device to a fleet (without rewrites)
Most teams start with a single device — a Raspberry Pi on a desk, a Jetson in a test rig. Access is simple: SSH in, run commands, iterate. The problems start when you add a second device, then a third, then ten across different sites.
With m87 (make87's command line + device runtime), each device is addressed by name. Your workflow stays the same whether you have 1 device or 100.
The problem
Scaling from one device to many forces you to solve problems that didn't exist before. SSH keys multiply — you're managing authorized_keys files across machines, rotating credentials, tracking who has access to what. Network topologies diverge as devices end up behind different NATs, on different VPNs, or requiring site-specific bastion hosts. Deployment scripts that worked fine with a hardcoded IP now need inventory files, connection logic, and error handling for each environment.
The result: what worked for one device requires a rewrite for ten.
The pattern: same commands, different device names
m87 sidesteps this complexity by making every device reachable the same way — by name:
m87 <device> shell
m87 <device> forward 8080
m87 <device> docker compose up -d
Adding a new device doesn't change your workflow. You just use its name.
Quick start
1) Set up the device
Install the m87 runtime on your device and register it:
m87 runtime login
m87 runtime enable --now
2) Access from your laptop
m87 login
m87 devices list
m87 rpi shell
Adding more devices
1) Repeat the device setup
On each new device:
m87 runtime login
m87 runtime enable --now
2) Approve the device
m87 devices approve jetson-01
3) Use the same commands
m87 jetson-01 shell
m87 jetson-01 forward 8080
m87 jetson-01 docker ps
No new VPN configs. No new SSH keys. No firewall changes.
Fleet operations
List all devices
m87 devices list
Deploy to multiple devices
Script the same commands across device names:
for device in rpi-01 rpi-02 rpi-03; do
m87 $device docker compose up -d
done
Check status across devices
for device in rpi-01 rpi-02 rpi-03; do
echo "=== $device ==="
m87 $device docker ps
done
Currently, scripting with a for-loop is the recommended approach for fleet-wide operations. We're adding fleet groupings in the future, allowing commands to target a group name instead of individual device names (e.g., m87 @warehouse docker compose up -d).
What doesn't change as you scale
| Concern | One device | Fleet |
|---|---|---|
| Authentication | m87 login | m87 login |
| Device access | m87 <device> shell | m87 <device> shell |
| Port forwarding | m87 <device> forward 8080 | m87 <device> forward 8080 |
| Deployment | m87 <device> docker compose up | m87 <device> docker compose up |
| File sync | m87 sync ./src <device>:app | m87 sync ./src <device>:app |
The commands are identical. Only the device name changes.
What to think about as you scale
Naming conventions
Use meaningful, consistent names:
rpi-warehouse-01,rpi-warehouse-02jetson-camera-north,jetson-camera-southedge-nyc-001,edge-sfo-001
Deployment automation
For larger fleets, wrap m87 commands in scripts or use your existing automation tools (Ansible, shell scripts, CI/CD).
Monitoring
Use m87 <device> stats for quick checks. For persistent monitoring, deploy observability agents (Prometheus node exporter, Telegraf) via Docker Compose.
Automated provisioning
m87 can be integrated into image flashing or OS installation processes. Pre-install and configure the m87 runtime in your base image, and new devices register automatically on first boot — no manual setup per device. This is especially useful for manufacturing or large-scale deployments where devices should be ready to connect out of the box.
Alternatives (and tradeoffs)
Ansible / SSH-based automation
Pros:
- Agentless: runs over SSH, no daemon required on target devices
- Idempotent task execution with rollback capabilities
- Large module library for common operations (apt, systemd, docker)
Cons:
- Requires inbound SSH (port 22) — problematic behind NAT/CGNAT without bastion hosts or VPN
- Static inventory files need updates when IPs change; dynamic inventory requires additional infrastructure (Consul, cloud APIs)
- Playbooks embed connection details; network migrations require inventory rewrites
Kubernetes / k3s
Pros:
- Declarative desired-state model with automatic reconciliation
- Built-in service discovery, load balancing, and rolling updates
- Helm charts available for common workloads
Cons:
- k3s requires ~512MB RAM minimum per node; full k8s requires 2GB+
- Nodes need persistent connectivity to API server (port 6443); network partitions cause pod evictions after 5 minutes (default)
- Control plane (etcd, API server, scheduler) adds operational complexity for single-device or small deployments
Custom fleet management
Pros:
- Full control over protocol choice (MQTT, gRPC, WebSocket, custom)
- Can optimize for specific constraints (bandwidth, latency, intermittent connectivity)
Cons:
- Must implement: device authentication, certificate management, secure tunneling, NAT traversal
- Ongoing maintenance: protocol upgrades, security patches, scaling infrastructure
- Testing burden: edge cases for network interruptions, partial failures, clock drift
FAQ
Do I need different credentials per device?
No. You authenticate once with m87 login. Access to devices is managed through the make87 platform.
Can I group devices?
Yes. Use naming conventions and scripting. make87 also supports organization-level grouping.
What about devices in different networks?
Each device connects outbound to the make87 platform. Network topology doesn't matter — devices behind different NATs, CGNATs, or corporate networks are all reachable the same way.
How many devices can I manage?
m87 scales to hundreds of devices. The limiting factor is typically your operational processes, not the tool.
Can I revoke access to a device?
Yes. Remove the device from your organization in the make87 platform, or stop the runtime on the device itself.