The ados-deploy tool
ados-deploy is a Rust terminal tool in the Mission Control repo at
tools/deploy/. It brings up the self-hosted stack (Convex backend and
dashboard, the Mission Control web GCS, Mosquitto, the MQTT bridge and the video
relay) through a guided flow, then keeps the lifecycle commands in one place.
It is not a second stack. It drives the same Compose project documented on
All-in-one stack:
tools/selfhost/docker-compose.yml. What it adds is the ordering, the generated
config, the secret handling and the verification, so you do not run the ten
steps by hand.
When to use which path
ados-deploy operates on a repo checkout, because it builds the Mission
Control image from the repo and pushes Convex functions from it. There is no
checkout-free mode.
Invoke it
From a checkout, through the npm script:-- goes to ados-deploy. The script is
cargo run --release --quiet --manifest-path tools/deploy/Cargo.toml --.
Directly with cargo:
tools/selfhost/docker-compose.yml, otherwise it clones to
$HOME/ADOSMissionControl. Override with ADOS_DIR and ADOS_REPO_URL. It
then launches in preference order: a cached or committed ./ados-deploy binary,
a best-effort fetch of the matching release asset, then a cargo build. Extra
arguments pass through.
Running with no action opens the interactive menu. On a non-terminal (CI, or a
piped invocation) the menu is unavailable and the tool tells you to pass an
action instead.
Actions
An unrecognised action falls through to the menu.
Dry-run first
--plan (alias --dry-run) prints the exact files the deploy would write and
the exact commands it would run, in order, then exits without touching
anything. Secrets are always redacted in the plan output.
This is the right way to review a deploy before you let it run, and it is the
same ordering the real state machine executes.
Flags
Rendering and interactivity
Deploy answers
Supply these to run the whole flow without prompts.
An unknown flag is ignored rather than rejected, so a newer wrapper script stays
forward-compatible with an older binary.
What a deploy runs
The state machine is ordered and idempotent:- Preflight checks (Docker, Node, toolchain).
- Write the generated config files.
- Bring up the Convex backend.
- Wait for it to answer.
- Generate the admin key.
- Push the Convex functions.
- Write the auth keys.
- Write the MQTT password file.
- Bring up the rest of the stack.
- Verify, then print the reach links.
upgrade reuses the same graph: it reconstructs the
config from the deployed .env and runs the whole thing again.
Files it writes
All paths are relative to the repo root; commands run with the root as their working directory.Services and default ports
These mirrortools/selfhost/docker-compose.yml. The tool detects a port
conflict before it starts anything.
Check and tear down
teardown runs docker compose down. Purging the volumes is a separate opt-in,
so a teardown does not silently destroy your Convex data.
To roll back a bad upgrade, check out the previous commit of the repo and run
upgrade again: the image is rebuilt from the checkout and the functions are
re-pushed from it, so the checkout is the version you are running.