Dockerfile at the repo root builds the GCS; the convex/
directory holds the functions and schema you push to the backend.
You do not need Convex at all to fly on the LAN. Served over plain HTTP,
Mission Control connects straight to the agent and pairs over the local
network with no backend. Convex is for cloud relay (cross-network access) and
for auth. See the
self-hosting overview for the local-first
path.
The two Convex origins
Before any wiring, the one detail that trips people up: a self-hosted Convex backend exposes two origins that are not interchangeable.| Origin | Role | Who talks to it |
|---|---|---|
:3210 | client API | the GCS browser bundle (NEXT_PUBLIC_CONVEX_URL) and convex deploy |
:3211 | site / HTTP actions | the drone agent heartbeat and the MQTT bridge (CONVEX_URL resolves to ${CONVEX_URL}/agent/status); the agent’s server.self_hosted.url and pairing.convex_url |
:3210 for browser and deploy,
:3211 for the agent and bridge.
Build and run the GCS image
The repoDockerfile is a multi-stage build that produces a Next.js
standalone server. The container listens on port 4000.
The build needs the Convex client-API origin baked in as a build argument,
because NEXT_PUBLIC_* values are inlined at build time, not read at runtime.
Point it at the :3210 origin of the Convex backend the browser will reach.
Build the image
Dockerfile accepts:| Build arg | Purpose |
|---|---|
NEXT_PUBLIC_CONVEX_URL | Convex client API origin (:3210), required for cloud mode |
NEXT_PUBLIC_CESIUM_ION_TOKEN | 3D terrain tiles (optional) |
NEXT_PUBLIC_DEMO_MODE | true ships the build with the demo fleet |
NEXT_PUBLIC_PLUGIN_REGISTRY_URL | plugin registry origin (optional) |
ADOS_MANIFEST_URL | agent install manifest origin (optional) |
Stand up a self-hosted Convex backend
You have two routes for Convex:- Convex Cloud is the easiest if you are fine with a hosted backend. Run
npx convex initandnpx @convex-dev/authin theADOSMissionControldirectory, thennpx convex dev. - Self-hosted runs the open-source backend in Docker. The rest of this page covers that route.
ghcr.io/get-convex/convex-backend.
The all-in-one stack at
tools/selfhost/ bundles it with a convex-dashboard service, the GCS, and
the relay layers in one compose file. To run just the backend:
Start the backend
Start the
convex-backend service (from the all-in-one compose, or your
own compose pointing at the same image). On first boot it prints an admin
key:Push functions and schema
Deploy the GCS functions to the backend. Point the CLI at your own
:3210 origin and admin key, run from a machine with the repo checked
out:Generate the auth keys
A fresh self-hosted backend has no signing keys. Convex Auth signs
session JWTs with RS256, so you generate a key pair and set it on the
backend. The helper script exports
JWT_PRIVATE_KEY and JWKS into your
shell:Point the agent at the backend
To put a drone on your self-hosted backend instead of the LAN-only local mode, set itsserver.mode to self_hosted and point the self-hosted URL at the
Convex site origin (:3211). The agent heartbeat and pairing both target
that origin.
server and pairing blocks, and the
agent self-hosting page for the install
command.
Telemetry and video relay
Convex carries auth, fleet state, and the cloud command queue (a 5 second poll baseline). For live telemetry at 2 Hz and up, and for browser video, add the MQTT bridge and the video relay. The GCS reads their URLs from a Convex environment variable at runtime, so a self-hosted deployment must set them or the GCS falls back to a broker and relay it cannot reach:MQTT bridge
Mosquitto plus the bridge that forwards live telemetry to Convex.
Video relay
RTSP-to-WebSocket video so a browser can play the drone’s stream.
Verify
Open the GCS in a browser. Over HTTPS it enters cloud mode; pair a drone and the node detail should show a Cloud badge and start receiving telemetry. A few quick checks:curl https://your-convex.example.com:3210/returns a response, so the backend is reachable on the client-API origin.- Sign-in works in the GCS, which confirms the auth keys are set on the right deployment.
- A paired drone appears in the fleet, which confirms its heartbeat reached the
:3211site origin.
:3210 versus :3211 wiring above. The
troubleshooting and ports
page carries the full port table and the common failure modes.
Where to go next
All-in-one stack
One Docker Compose brings up Convex, the GCS, and the relay layers on a
single host.
Drone agent
Install the agent and point it at your backend.