Self-Hosting (Docker Hub)
Run your own AgentX from the published Docker image — no source checkout, no build step, nothing on the host but Docker. The deployment package includes a web dashboard that watches the stack for you, so setup is four short steps (most of the wait is a one-time model download).
1 · Get the deployment package
Download agentx-deploy.tar.gz from the
latest release (it’s also
linked from the Docker Hub repo)
and unpack it where the instance should live:
tar xzf agentx-deploy.tar.gz && cd agentx-deploy
2 · Configure and start
cp .env.example .env # defaults are fine — secrets are generated on first Start
docker compose up -d
Nothing to edit: the Django secret key and database passwords are generated
into .env on the dashboard’s first Start, and LLM provider API keys are
added later in the app (Settings → Providers — saved server-side), not in
.env. That starts only the deployment manager — nothing else yet. On
Windows, double-click the bundle’s start-manager.bat instead — it
creates .env if missing, runs the same command through Docker Desktop’s
WSL 2 integration, then opens the dashboard and the access token for you.
3 · Open the dashboard and bring up the stack
- Open http://127.0.0.1:12320 in a browser on the host.
- Paste the access token — it’s in
./.manager-token(also shown bydocker compose logs manager). - The dashboard shows Stopped (expected — at this point only the manager
itself is running). Click Start AgentX. A fresh install shows
Starting up… for a few minutes while it downloads the embedding model
(~2.3 GB, cached under
./data/hf-cache— the dashboard shows the live download rate) and self-initializes its database schemas — nothing to migrate by hand — then it flips to Running. If anything looks stuck, the Activity Log shows exactly where it is.
The same dashboard handles day-2 life from here: stop/restart, per-service logs, and live CPU/memory usage. Full reference: Deployment Manager.
4 · Connect the desktop client
Download an installer from the
latest release — Windows
(.exe / .msi) or Linux (.deb / .AppImage / .rpm); macOS is not yet in
the release matrix. Point it at your server’s URL on first run and set the root
password from its setup screen (auth is on by default; the terminal
alternative is docker compose exec api agentx setup-auth).
You’re up.
Operating your instance
Day-to-day, the dashboard covers most of it. The rest:
Updating
# pin AGENTX_IMAGE to the new version in .env (recommended), or pull :latest
docker compose pull
docker compose exec manager agentx-manager up
agentx-manager up (not a bare docker compose up -d, and not restart —
that only restarts existing containers, it won’t swap in a freshly pulled
image) recreates whichever services actually changed. Dashboard Up/
Restart does the same. Schema migrations re-apply automatically on boot
(idempotent — a warm boot just verifies version stamps and reaches the API in
seconds); config and data persist under ./data.
Backups
agentx export/import (below) cover the memory graph only. For a full
database backup, dump the volumes directly:
docker compose exec postgres pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" > backup.sql
docker compose exec neo4j neo4j-admin database dump neo4j --to-path=/backups
The agentx CLI
Terminal-side day-2 operations run through the in-image CLI (versioned with the image, so nothing external to keep in sync):
docker compose exec api agentx help # list commands
docker compose exec api agentx status # health + memory status
docker compose exec api agentx version # running API version
docker compose exec api agentx migrate # apply all migrations (fast; --full re-inits)
docker compose exec api agentx setup-auth --force # reset the root password
docker compose exec api agentx warmup # pre-load the embedding model
docker compose exec api agentx export --output /app/data/memory-export.json
docker compose exec api agentx import --input /app/data/memory-export.json
GPU acceleration
With the NVIDIA Container Toolkit
on the host, add the overlay to COMPOSE_FILE in .env (keep
docker-compose.manager.yml in the list), then bring the stack up through the
manager:
# .env: COMPOSE_FILE=docker-compose.yml:docker-compose.manager.yml:docker-compose.gpu.yml
docker compose exec manager agentx-manager up
curl -s localhost:12319/api/health | jq .compute # {"device":"cuda",...}
Going public
The recommended public setup layers two things in front of Django:
- The Nginx token gateway (
docker-compose.gateway.yml, shipped in the bundle) — every request must carry a shared-secretAgentX-Gateway-Tokenheader and is rate-limited (~10 req/s per client IP) before it reaches the API. The desktop client sends the header automatically from its per-server Gateway token setting. - A Cloudflare Tunnel running as a container — no
cloudflaredon the host, no inbound ports opened, TLS terminated at Cloudflare’s edge.
1. Gateway config + shared secret
mkdir -p gateway
cp gateway/nginx.conf.example gateway/nginx.conf
openssl rand -hex 32 # → AGENTX_GATEWAY_TOKEN below
The gateway overlay fails closed: compose refuses to start it while
AGENTX_GATEWAY_TOKEN is unset or empty.
2. Create the tunnel (Cloudflare dashboard)
In Zero Trust → Networks → Tunnels, create a tunnel and copy its token. Add a Public Hostname for it:
- Subdomain/Domain: the hostname you’ll use (e.g.
agentx.example.com) - Service:
http://nginx:80— the gateway, reachable by name because the tunnel runs on the same Docker network. (Pointing it athttp://api:12319directly bypasses the gateway — see the bare-tunnel note below.)
3. Configure .env
TUNNEL_TOKEN=<your-tunnel-token> # from the dashboard; keep it secret
AGENTX_PUBLIC_HOST=agentx.example.com
AGENTX_GATEWAY_TOKEN=<64-char hex> # from step 1; keep it secret
AGENTX_TRUST_PROXY=true # the gateway overwrites X-Forwarded-For
# Make the overlays sticky so a bare `docker compose up -d` always layers them:
COMPOSE_FILE=docker-compose.yml:docker-compose.manager.yml:docker-compose.gateway.yml:docker-compose.tunnel.yml
AGENTX_PUBLIC_HOST extends ALLOWED_HOSTS, CORS_ALLOWED_ORIGINS, and
CSRF_TRUSTED_ORIGINS in one shot, so Django accepts requests arriving with that
host from the tunnel. AGENTX_TRUST_PROXY lets the API attribute requests to the
real client IP (nginx sets X-Forwarded-For from Cloudflare’s
CF-Connecting-IP); leave it unset when nothing overwrites that header.
4. Bring it up and verify
docker compose up -d # (re)starts the manager, now with these files loaded
docker compose exec manager agentx-manager up # brings up the stack — api, dbs, gateway, tunnel
# The connector registered with Cloudflare's edge:
docker compose logs cloudflared | grep -i "Registered tunnel connection"
# Gateway enforces the token (health is otherwise unauthenticated):
curl -sI https://agentx.example.com/api/health # → 401
curl -sI -H "AgentX-Gateway-Token: <token>" \
https://agentx.example.com/api/health # → 200
Then point the desktop client at https://agentx.example.com, paste the gateway
token into the server’s Gateway token field, and log in (root + the
password you set). Authenticated endpoints return 401 until you log in —
that’s app auth, not the gateway.
Variants
- Named tunnel (credentials file, no dashboard-managed routing): also
cp gateway/cloudflared/config.yml.example gateway/cloudflared/config.yml, follow the setup steps embedded in that file, and swapdocker-compose.tunnel.ymlfordocker-compose.tunnel.named.ymlinCOMPOSE_FILE. - Your own reverse proxy / TLS (no Cloudflare): swap the tunnel overlay for
docker-compose.gateway.expose.yml— the gateway listens on${AGENTX_GATEWAY_BIND:-127.0.0.1}:${AGENTX_GATEWAY_PORT:-8080}for your proxy to front. Rate limiting keys on the TCP peer address in this mode.
Reference
What’s in the package
docker-compose.yml # API (pulled image) + Neo4j + PostgreSQL + Redis — profile `production`
docker-compose.manager.yml # web deployment manager (dashboard) — on by default, starts the stack for you
docker-compose.gateway.yml # Nginx token gateway (going public)
docker-compose.gateway.expose.yml # … gateway on a host port (BYO reverse proxy)
docker-compose.tunnel.yml # … Cloudflare token tunnel
docker-compose.tunnel.named.yml # … Cloudflare named tunnel
docker-compose.gpu.yml # optional NVIDIA GPU overlay
gateway/ # gateway config templates
.env.example # configuration template
README.md
Overlays are opt-in layers over the base compose; set them once via
COMPOSE_FILE= in .env (as the sections above do) and they’re loaded on
every docker compose command from then on. Loaded isn’t the same as
started, though — the API/databases (and any overlay services) sit behind the
production profile and only come up through the manager (dashboard Up,
or agentx-manager up), not a bare docker compose up -d.
Headless / scripted checks
Everything the dashboard shows is also reachable without a browser:
curl "http://localhost:12319/api/health?include_memory=true" # API + databases
docker compose exec api agentx status # via the ops CLI
Local vs isolated deployments
What this page stands up is an isolated deployment (published image, owned by its own directory, self-initializing). The repo also supports local clusters — source-built instances for developing AgentX itself, managed by the same deployment manager — see Clusters & Gateway. Both are the same compose stack underneath; they differ only in where the image comes from.