RootCX
Docs
Pricing
RootCX/RootCXSource Available
Introduction
What is RootCX?Getting StartedHow it Works
Build
ApplicationAI AgentIntegrationDeploying
Platform
CoreAuthenticationRBACData APISecret VaultJob QueueScheduled Jobs (Crons)Audit LogReal-time LogsChannels
Developers
React SDKBackend & RPCManifest ReferenceREST APICLIClaude CodeSelf-Hosting
DocsDevelopersSelf-Hosting

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 requires an external PostgreSQL database. The easiest way to get started is with Docker Compose:

# docker-compose.yml
services:
  postgres:
    image: ghcr.io/rootcx/postgresql:16-pgmq
    user: root
    entrypoint: ["/pg-entrypoint.sh"]
    environment:
      POSTGRES_USER: rootcx
      POSTGRES_PASSWORD: rootcx
      POSTGRES_DB: rootcx
      PGDATA: /data/pgdata
    volumes:
      - pgdata:/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U rootcx -d rootcx"]
      interval: 2s
      timeout: 5s
      retries: 10

  core:
    image: ghcr.io/rootcx/core:latest
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      DATABASE_URL: postgres://rootcx:rootcx@postgres:5432/rootcx
    ports:
      - "9100:9100"
    volumes:
      - data:/data

volumes:
  pgdata:
  data:
docker compose up -d

Verify it is running:

curl http://localhost:9100/health
# {"status":"ok"}
The ghcr.io/rootcx/postgresql:16-pgmq image is PostgreSQL 16 with the pgmq extension pre-installed, which the Core uses for its job queue. You can use any PostgreSQL 16+ instance as long as the pgmq extension is available.

Environment variables

DATABASE_URL is required. All other variables are optional for local development. For production, set explicit secrets.

Variable Default Description
DATABASE_URL — (required) PostgreSQL connection URL (e.g. postgres://user:pass@host:5432/db).
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.
ROOTCX_PUBLIC_URL not set Public URL for OIDC callbacks (e.g. https://core.example.com). Falls back to ROOTCX_URL.
ROOTCX_URL not set Core instance URL (used as fallback for ROOTCX_PUBLIC_URL).
RUST_LOG info Log filter. Values: trace, debug, info, warn, error.
ROOTCX_OIDC_ISSUER not set URL of your OIDC identity provider (e.g., Okta, Azure AD, Google). Seeds a provider on first boot.
ROOTCX_OIDC_CLIENT_ID not set Client ID for your OIDC provider. Required if ROOTCX_OIDC_ISSUER is set.
ROOTCX_OIDC_CLIENT_SECRET not set Client Secret for your OIDC provider. Required if ROOTCX_OIDC_ISSUER is set. Encrypted in the vault.
ROOTCX_DISABLE_PASSWORD_LOGIN not set Set to true or 1 to disable email/password login. A first-user bypass allows initial registration even when set.
For production, always provide explicit values for ROOTCX_JWT_SECRET and ROOTCX_MASTER_KEY. Relying on auto-generated secrets means losing them if the container is recreated without persistent storage.

Development database

For local development, you can expose the PostgreSQL port to connect directly:

# docker-compose.dev.yml
services:
  postgres:
    image: ghcr.io/rootcx/postgresql:16-pgmq
    user: root
    entrypoint: ["/pg-entrypoint.sh"]
    environment:
      POSTGRES_USER: rootcx
      POSTGRES_PASSWORD: rootcx
      POSTGRES_DB: rootcx
      PGDATA: /data/pgdata
    volumes:
      - pgdata-dev:/data
    ports:
      - "5480:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U rootcx -d rootcx"]
      interval: 2s
      timeout: 5s
      retries: 10

volumes:
  pgdata-dev:
psql -h 127.0.0.1 -p 5480 -U rootcx -d rootcx

Managed database

For teams using a managed database (RDS, Cloud SQL, etc.), point DATABASE_URL at your instance. Ensure the pgmq extension is available — on AWS RDS, enable it via the shared_preload_libraries parameter group.

docker run -d \
  --name rootcx-core \
  -p 9100:9100 \
  -e DATABASE_URL=postgres://user:pass@your-rds-host:5432/rootcx \
  -e ROOTCX_BIND=1 \
  -e ROOTCX_JWT_SECRET="your-secret-min-32-characters-here" \
  -e ROOTCX_MASTER_KEY="hex-encoded-32-byte-key" \
  ghcr.io/rootcx/core:latest

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

The Docker image includes a built-in health check (curl -fs http://localhost:9100/health) with a 10-second interval.


Connecting Studio

Once your self-hosted Core is running and reachable, open RootCX Studio, select Connect to a server, and paste your Core URL.

PreviousClaude Code

On this page

Quick start
Environment variables
Development database
Managed database
Health checks
Connecting Studio