Skip to content

Self-hosted deployment

  • A Linux host with Docker and Docker Compose v2, supporting docker compose -f a.yml -f b.yml.
  • A public DNS name pointing to the host and open ports 80/443 if the bundled Caddy terminates TLS.
  • Outbound internet access for images and Let’s Encrypt certificates.
  • For AI workers: /var/run/docker.sock on the same host, used by the supervisor, and an LLM endpoint with an OpenAI-compatible API (LiteLLM in the default configuration).

The control plane neither updates itself nor initiates connections to machines. Agents connect to it through WebSocket, so managed machines need no inbound ports.

The reference stack is in deploy/docker/docker-compose.yml:

Service Purpose
control-plane HTTP/WS API, authentication, chat, memory, and audit; serves the SPA from /app/dist. Listens on 18181.
postgres Postgres 15, used when NYTHRONIX_STORAGE=postgres is enabled. By default, state is stored as JSON in nythronix_state.
redis Included in the stack; connected through NYTHRONIX_REDIS_URL for temporary download tokens.
minio + minio-init S3-compatible release bundle storage; creates the nythronix-bundles bucket automatically.
supervisor Worker reconciler, the only service with docker.sock access, with no inbound ports. Starts and stops workers according to desired state from the control plane.

First start:

Terminal window
cd deploy/docker
cp .env.example .env
$EDITOR .env # secrets, public URL, LLM
echo '{}' > llm-profiles.json
docker compose up --build -d

Each container start runs preflight (NYTHRONIX_REQUIRE_PREFLIGHT=true). A weak pepper, missing public URL, or http:// without NYTHRONIX_ALLOW_HTTP_FOR_STAGING=true keeps the container restarting until .env is fixed.

Check health:

Terminal window
curl -fsS http://127.0.0.1:18181/api/healthz # {"status":"ok"}: process is alive
curl -fsS http://127.0.0.1:18181/api/readyz # {"status":"ready"}: storage available, bootstrap complete
Variable Meaning
NYTHRONIX_MODE self-hosted (default) or saas. Self-hosted enables NX endpoints and administrator bootstrap from environment variables.
NYTHRONIX_PUBLIC_URL Public control plane URL (https://cp.example.com, no trailing /). Must match the browser address exactly: used for WebSocket Origin checks, the canonical /agent/ws, and supervisor URLs.
NYTHRONIX_EXTRA_ORIGINS Additional comma-separated origins, such as https://app.cp.example.com when the dashboard uses a separate host.
NYTHRONIX_PASSWORD_PEPPER Argon2 secret, at least 32 characters. Losing it makes all passwords unverifiable.
NYTHRONIX_BOOTSTRAP_EMAIL, NYTHRONIX_BOOTSTRAP_PASSWORD First administrator, used only with empty storage.
NYTHRONIX_RUNTIME_TOKEN Shared secret between the control plane and supervisor. If unset, runtime API is disabled and workers do not start.
LITELLM_BASE_URL, LITELLM_API_KEY, LITELLM_MODEL Default worker LLM, read by the supervisor, not the control plane.
NYX_LLM_PROFILES_FILE, NYX_POOL, NYX_WORKER_NETWORK, NYX_HUNG_GRACE_SECS Supervisor settings: per-organization LLM profiles, pool name, isolated worker network, and hung-worker threshold.
NYTHRONIX_SMTP_URL, NYTHRONIX_SMTP_FROM, NYTHRONIX_BETA_NOTIFY_TO Outbound beta-request notifications: smtps://user%40example.com:pass@smtp.example.com:465 (implicit TLS) or smtp://…:587 (STARTTLS). Encode @ in usernames as %40.
NYTHRONIX_STORAGE, NYTHRONIX_DATABASE_URL json (default), or postgres with a DSN.
NYTHRONIX_HOST_PORT Host port for the control plane, default 18181.

See deploy/docker/.env.example for the full list. nythronix-server config-show prints the effective configuration; nythronix-server preflight --strict checks it before startup.

The shortest path on a fresh VPS is Caddy in the same stack, with automatic certificates:

Terminal window
# in .env: NYTHRONIX_DOMAIN=cp.example.com, NYTHRONIX_PUBLIC_URL=https://cp.example.com
docker compose -f docker-compose.yml -f docker-compose.caddy.yml up --build -d

The overlay removes host publication of port 18181, making Caddy the only entry point. Block direct port access in the firewall.

For an existing reverse proxy, use deploy/caddy/Caddyfile or deploy/nginx/nythronix.conf. Forward /api/* and /proxy/* over HTTP and allow WebSocket upgrades for /agent/ws, /nx/ws, /ws/remote, /ws/nx, /ws/relay, and /ws/control. Pass X-Forwarded-Proto. Caddy handles upgrades transparently; nginx requires proxy_set_header Upgrade / Connection. Agent connections last for hours, so increase read/write timeouts (1–2 hours in the examples).

With empty storage, the server creates the default organization and an owner from NYTHRONIX_BOOTSTRAP_EMAIL / NYTHRONIX_BOOTSTRAP_PASSWORD. Remove these variables after the first successful startup; they are ignored for nonempty storage. SaaS mode does not perform bootstrap.

See Administration for further operator management.

The server serves everything in the SPA directory as static files. To host the Windows installer at https://<cp>/downloads/<file>, mount a directory into control-plane:

services:
control-plane:
volumes:
- nythronix_state:/var/lib/nythronix
- ./downloads:/app/dist/downloads:ro

Download the Windows agent on the sign-in page and Agents section points to /downloads/nythronix-agent-setup.exe. Place the file under that name. Build it with scripts/build-agent-windows-installer.sh.

There are two independent paths.

Control plane does not update itself. Rebuild the image and restart the stack:

Terminal window
docker compose -f docker-compose.yml -f docker-compose.caddy.yml up --build -d

Startup order matters: the control plane with runtime API must start before the supervisor and workers. The supervisor retries, so a brief startup race only produces a log warning.

Agents, NX endpoints, and the nx CLI update over the connection. Build and sign releases on a separate build machine, not the control plane, and publish with scripts/release.sh. Agents with auto policy receive an offer on their next connection, verify SHA-256 and Ed25519, and restart into the new binary. See Administration and Security model.