Deploy workers / AX
Use an existing AX deployment
Experimental. This guide assumes AX and Agent Substrate are already running. Horde connects to that deployment and creates workers in gVisor. Your Horde controller can stay on your local machine.
Before you start
- Use AX revision
d8ed0fe38bceb7842d3c47817d53d16ccdfcb601with its pinned Substrate dependency. For AX installation, follow upstream AX documentation. - Make the AX gRPC API and Substrate HTTP router available to your controller through private, loopback-bound tunnels. Workers must be able to connect back to the controller.
- Use matching controller and runner builds from a Horde revision with AX support; older releases may not include it. Configure Horde’s controller identity and enrollment signer, and a project with a registered repository and model accounts.
- Use persistent AX and Substrate storage if workers must survive host restarts. See the storage prerequisites.
1. Prepare a Horde runner image
The AX runner is currently built from source; Horde does not yet publish a prebuilt AX image. From a Horde checkout, place an Ubuntu 24.04-compatible Linux AMD64 Horde executable at dist/amd64/horde (see the binary build instructions), then build and push:
docker build --platform linux/amd64 -f containers/ax/Dockerfile \
-t REGISTRY/horde-ax:experimental .
docker push REGISTRY/horde-ax:experimental
docker inspect --format '{{index .RepoDigests 0}}' REGISTRY/horde-ax:experimentalReplace REGISTRY with a registry your AX workers can pull from. Keep the returned image@sha256:... reference for the next step. The image contains Horde, Git, and the model CLIs. If tasks need Docker or Compose, apply the optional Docker setup before building and creating the worker.
2. Add an AX profile
Add this to the controller’s ~/.config/horde/runtimes.toml. Keep the enrollment settings at the top of the file, before any profile tables; reuse your configured controller CA and address.
issuer_key = "/absolute/path/to/controller/ca.key"
controller_address = "CONTROLLER_ADDRESS:7443"
controller_tls_name = "controller.example.net"
[profiles.ax-worker]
provider = "ax"
project = "PROJECT_UUID"
endpoint = "http://127.0.0.1:9090"
ax_router_endpoint = "http://127.0.0.1:8001"
ax_revision = "d8ed0fe38bceb7842d3c47817d53d16ccdfcb601"
image = "REGISTRY/horde-ax@sha256:IMAGE_SHA256"
ax_egress = ["*:443"]
cpus = 2
memory_mb = 4096
concurrency = 2
executor_roles = ["planner", "worker", "reviewer"]Replace the placeholders and tunnel ports. Get the project UUID with horde project inspect PROJECT. The listed executor roles must exist in that project’s configuration. Configure credentials through Horde’s managed accounts; ambient CLI logins are not copied into workers. Use a separate profile for each project.
The pinned AX gateway ignores the port in ax_egress, so *:443 permits all outbound traffic. Use explicit hostnames or CIDRs to restrict destinations. CPU and memory settings are sent to AX; per-worker enforcement has not been established by this integration.
3. Create and verify a worker
horde --project PROJECT runtime create ax-1 --profile ax-worker --request-id create-ax-1
horde --project PROJECT runtime inspect ax-1
horde --project PROJECT call runtime_capabilities '{}'Replace PROJECT with your project slug or UUID. Wait for Horde’s authenticated worker connection to be ready before submitting work. AX reporting its Task ready is only the first part of startup. Capabilities should show gvisor isolation.
4. Run a task
horde --project PROJECT submit --on ax-1 --repo /path/to/repo "Run the tests"Use a registered repository with a clean checkout and committed changes. Horde transfers the repository and runs the workflow on ax-1. Work selected for that worker waits while it is unavailable; it does not fall back to your local machine.
Stop and resume
horde --project PROJECT runtime stop ax-1 --request-id stop-ax-1
horde --project PROJECT runtime start ax-1 --request-id start-ax-1Stop drains active work and retains the workspace and worker identity. Reuse a request ID only to retry the same operation; use a new ID for the next stop/start cycle. For image upgrades, create a new runtime with the new image digest. See recovery and upgrades for uncertain operations and cleanup.
Optional Docker and Compose
Docker and Compose work inside AX workers when the deployment supplies the required guest capabilities and gVisor settings. Follow the AX Docker configuration, which includes the pinned AX patch and sandbox setup, then build the Horde runner with --build-arg ENABLE_DOCKER=true.
Create a new worker using that image and verify that runtime_capabilities reports Docker and Compose available. Each worker has its own Docker daemon and persistent image and volume storage; it does not use the host Docker socket. Builds and Compose service networking have passed live tests. Published ports (-p) remain untested.
If Docker fails, Horde stays connected for inspection and draining. Explicitly stop and start the worker to recover Docker. See the full AX reference for configuration details and tested limitations.