Running Multiple MoveIt Pro Instances on One Computer
A single computer can run several MoveIt Pro deployments at the same time — for example two simulated cells, or one deployment per robot in a test lab. Each deployment is a named instance with its own containers, network namespace, published ports, persistent data directory, and logs, so instances never interfere with each other.
Instances support mock hardware, simulation, and direct-device hardware (for example USB cameras). Network-attached robot hardware that opens connections back into the MoveIt Pro stack requires the default host-network deployment — run at most one of those, without --instance.
Starting an instance
Pass --instance <name> to moveit_pro run:
moveit_pro run --instance robot-a
Instance names use lowercase letters, digits, - and _, and must start with a letter or digit.
Ports are assigned automatically. The first time an instance runs, MoveIt Pro picks a free block of five consecutive host ports (web UI first, then the REST API, WebSocket bridge, video server, and terminal service), starting from 10000. The assignment is recorded in ~/.config/moveit_pro/instance_ports.yaml, so an instance keeps the same ports on every later run, and the CLI prints them at startup:
Running MoveIt Pro as instance 'robot-a'.
Web UI: http://localhost:10000
Backends: REST 10001, rosbridge 10002, video 10003, terminal 10004
Running without --instance is the default deployment and keeps the classic ports (web UI on 80, backend services on 3200–3203). Auto-assigned instance ports never overlap with it, so the default deployment and named instances can run side by side.
To pin an individual port (for example a firewalled web UI port), set the matching environment variable before moveit_pro run; the rest of the block stays auto-assigned. Pinned ports must be 1024 or higher and outside the default deployment's ports:
MOVEIT_UI_PORT=8080 moveit_pro run --instance robot-a
Run each instance from its own terminal. Different instances can use different robot configuration packages:
moveit_pro run --instance robot-a --config-package my_cell_a_config
moveit_pro run --instance robot-b --config-package my_cell_b_config
What each instance gets
| Resource | Location |
|---|---|
| Containers, networks | Docker Compose project moveit_pro_<name> |
| Host ports | Auto-assigned block recorded in ~/.config/moveit_pro/instance_ports.yaml |
| Web interface | http://localhost:<assigned UI port> (printed at startup) |
| Persistent data | ~/.local/share/moveit_pro/instances/<name> (override with MOVEIT_HOST_DATA_DIR) |
| ROS logs | ~/.ros/log_moveit_pro/<name> |
| CLI log | ~/.config/moveit_pro/last_moveit_pro_run.<name>.log |
Instances are isolated at the network level: each one runs in its own network namespace, so their ROS 2 traffic never mixes, even without configuring distinct ROS_DOMAIN_ID values. All instances on a host share the same Docker images, so disk usage does not multiply with the number of instances.
The network isolation relies on the DDS configuration that MoveIt Pro manages (loopback interface, no multicast, local peers). Instances refuse to start when a custom DDS configuration is active — USE_HOST_DDS=true, a CYCLONEDDS_URI or FASTRTPS_DEFAULT_PROFILES_FILE file, a non-default RMW_IMPLEMENTATION, or overridden CYCLONEDDS_* discovery settings — because custom discovery settings can route traffic between instances. Deployments that need a custom DDS configuration must use the default deployment (run without --instance).
Managing instances
List all recorded instances, their running state, and their web UI address — useful when a browser tab was closed and you need to find an instance again:
$ moveit_pro run --list-instances
robot-a RUNNING http://localhost:10000
robot-b STOPPED http://localhost:10010
Target a specific instance with the --instance option on the other CLI verbs:
# Open a shell in an instance's container
moveit_pro shell --instance robot-a
# Shut an instance down completely
moveit_pro down --instance robot-a
moveit_pro down without --instance only shuts down the default (non-instance) deployment; named instances keep running until brought down individually.
Licensing
Each instance counts as one license activation, like a separate machine. The activation is stable: an instance keeps the same hardware fingerprint across restarts and container recreations, so re-running an instance reuses its existing activation instead of consuming a new one. Make sure your license has enough activations for the number of instances you run, plus one for the default deployment if you use it.
moveit_pro run --instance derives this fingerprint automatically and per host, so you do not need to manage it. The only exception is driving the docker-compose-multi.yaml overlay by hand instead of through the CLI: set a host-unique MOVEIT_INSTANCE_MAC on each machine, otherwise the overlay's shared fallback makes those machines present the same fingerprint and consume each other's activations.
Limitations
- Remote access to an instance's backend ports follows the same rules as the default deployment (see Remotely Connecting to the Web Interface), substituting your per-instance ports.
- The opt-in legacy
rosbridge_servercompatibility sidecar (port3204) is not published outside an instance. Legacyroslibpy/roslibjsclients that need it must use the default host-network deployment.