Self-Hosting
By default, RootCX manages the infrastructure for you -- create a project on rootcx.com and a dedicated Core instance is provisioned automatically. This guide is for teams that need to run the Core on their own servers.
Quick start
The Core is published as a multi-arch Docker image (linux/amd64 + linux/arm64):
docker run -d \
--name rootcx-core \
-p 9100:9100 \
-v rootcx-data:/data \
-e ROOTCX_BIND=1 \
ghcr.io/rootcx/core:latest
Verify it is running:
curl http://localhost:9100/health
# {"status":"ok"}
That's it. The Core initializes its bundled PostgreSQL database on first boot. No additional setup required.
Docker Compose
For production deployments, use a docker-compose.yml:
services:
core:
image: ghcr.io/rootcx/core:latest
restart: unless-stopped
ports:
- "9100:9100"
volumes:
- rootcx-data:/data
environment:
ROOTCX_BIND: 1
ROOTCX_JWT_SECRET: "your-secret-min-32-characters-here"
ROOTCX_MASTER_KEY: "hex-encoded-32-byte-key"
RUST_LOG: info
volumes:
rootcx-data:
docker compose up -d
Environment variables
All variables are optional for local development. For production, set explicit secrets.
| Variable | Default | Description |
|---|---|---|
ROOTCX_BIND |
not set | Set to any value to listen on 0.0.0.0 instead of 127.0.0.1. Required for remote access. |
ROOTCX_JWT_SECRET |
Auto-generated | String (min 32 characters) for JWT signing. Auto-generated in config/jwt.key if not set. |
ROOTCX_MASTER_KEY |
Auto-generated | Hex-encoded 32-byte key for AES-256-GCM encryption. Auto-generated in config/master.key if not set. |
DATABASE_URL |
not set | PostgreSQL connection URL for an external database (e.g. postgres://user:pass@host:5432/db). Bypasses the bundled PostgreSQL. |
RUST_LOG |
info |
Log filter. Values: trace, debug, info, warn, error. |
ROOTCX_JWT_SECRET and ROOTCX_MASTER_KEY. Relying on auto-generated secrets means losing them if the container is recreated without persistent storage.External database
By default, the Core manages a bundled PostgreSQL instance inside the container. For teams that require a managed database (RDS, Cloud SQL, etc.), set the DATABASE_URL environment variable:
docker run -d \
--name rootcx-core \
-p 9100:9100 \
-e ROOTCX_BIND=1 \
-e DATABASE_URL=postgres://user:pass@your-rds-host:5432/rootcx \
-e ROOTCX_JWT_SECRET="your-secret-min-32-characters-here" \
-e ROOTCX_MASTER_KEY="hex-encoded-32-byte-key" \
ghcr.io/rootcx/core:latest
When DATABASE_URL is set, the bundled PostgreSQL is not started.
Health checks
Use these endpoints for load balancer or orchestrator health checks:
# Liveness
curl http://localhost:9100/health
# {"status":"ok"}
# Detailed status
curl http://localhost:9100/api/v1/status
Connecting Studio
Once your self-hosted Core is running and reachable, open RootCX Studio, select Connect to a server, and paste your Core URL.