When we introduced Pantavisor Mocker it simulated one device at a time. The last two releases (v0.1.0 and v0.2.0) turn it into a proper fleet-simulation tool: describe a whole fleet in one JSON file and run it as a swarm — in local tmux sessions, as Docker containers, or as Kubernetes pods.
One file per device, one file per fleet
Everything is now driven by single-file JSON configs. A device.json describes one device — Pantahub endpoint, auto-join token, device metadata, automation behavior, sync intervals:
{
"pantahub": { "host": "api.pantahub.com", "port": "443", "autojoin_token": "YOUR_AUTO_TOKEN" },
"device-meta": { "pantavisor.dtmodel": "My Test Device" },
"automation": { "enabled": true }
}
pantavisor-mocker start -s my-device -c device.json
Re-applying the config is always safe: the registration credentials the device obtains on first run are never touched, so the device keeps its identity across restarts.
A swarm.json does the same for a whole fleet — endpoint, token, metadata templates, model/channel definitions, generation counts and automation weights:
pantavisor-mocker swarm init -d my-fleet # writes a swarm.json template
vim my-fleet/swarm.json # set pantahub.host + autojoin_token
pantavisor-mocker swarm run -d my-fleet # generate the fleet + simulate it
swarm generate-devices, swarm status, swarm simulate --auto and swarm clean are there for step-by-step control, replacing the old pvmocks bash script with native subcommands.
Container-native swarms: one device per container
The v0.2.0 headline is the new swarm device entrypoint: each container provisions one device from a shared swarm.json on first start (picking a model, and a random channel with --channel random) and then runs it in the foreground. One device = one container = one log stream — and the fleet size is just the replica count.
With the ready-made compose file in examples/docker/:
services:
device:
image: ghcr.io/pantavisor/pantavisor-mocker:latest
command: ["swarm", "device", "-c", "/swarm.json", "--channel", "random"]
volumes:
- ./swarm.json:/swarm.json:ro
restart: unless-stopped
deploy:
replicas: 5
docker compose up -d --scale device=10
docker compose logs -f # all devices
docker logs -f docker-device-3 # one device
docker compose down # add -v to also discard the device identities
Each container keeps its device state in a per-container volume, so identities survive restarts and are dropped with the container.
On Kubernetes
examples/kubernetes/ ships two ready-to-apply manifests, both driven by the same swarm.json as a ConfigMap:
-
swarm-devices.yaml(recommended) — a StatefulSet where every pod runsswarm deviceand keeps its identity on its own PersistentVolumeClaim, so reschedules resume the same registered devices. Per-devicekubectl logs, and scaling the fleet is one command:kubectl apply -f examples/kubernetes/swarm-devices.yaml kubectl scale statefulset pantavisor-mocker-device --replicas=20 kubectl logs -f pantavisor-mocker-device-3 -
swarm.yaml— the whole fleet in a single pod viaswarm run --headless, for the smallest footprint (hundreds of devices in one container, per-device output in tmux sessions inside it).
Also new along the way
- Automation mode — devices answer update invitations and acceptance tests on their own (weights configurable in
swarm.json), which is what makes TTY-less container swarms possible in the first place. - HTTPS auto-off for private endpoints — pointing mocks at
localhostor a private address automatically drops TLS, so a swarm against a local self-hosted Hub just works. - pvcontrol server — a Unix-socket implementation of the Pantavisor Control API with local-revisions support, so container-side tooling can talk to the mock like a real Pantavisor.
Get it
Docker image: ghcr.io/pantavisor/pantavisor-mocker:latest (also tagged per release). Source, examples and the full README: github.com/pantavisor/pantavisor-mocker. It pairs nicely with running your own dev Hub — spin up the cluster from the self-hosting guide, mint an auto-join token, and point a 20-device swarm at it.
Questions and feedback welcome below!