Self-hosting Hub
Set a persistent credential encryption key before starting Hub:
export CLISBOT_HUB_CREDENTIAL_MASTER_KEY="$(openssl rand -base64 32)"
npx @clisbot/hub
Hub listens on http://localhost:6870 for backend APIs. It creates its embedded
database and authentication secret. Manage it through the Hub settings integrated
in the Clisbot app. Port 6870 does not serve a separate dashboard.
For the daemon, web UI and Hub together, use the shared Docker image with
CLISBOT_RUN_MODE=all and open http://localhost:6868; see
Docker service modes.
Save that key in your deployment secrets and reuse it across restarts. You can
instead mount a secret and set CLISBOT_HUB_CREDENTIAL_MASTER_KEY_FILE to its
absolute path. Set exactly one key source.
Follow the quickstart to connect Slack over Socket Mode and run the first workflow without a public server.
Local data
Without DATABASE_URL, Hub stores an embedded PGlite database and its generated authentication secret under $XDG_DATA_HOME/clisbot-hub. If XDG_DATA_HOME is not set to an absolute path, Hub uses ~/.local/share/clisbot-hub. Both survive restarts.
Set a different location explicitly with:
CLISBOT_HUB_DATA_DIR=/path/to/clisbot-hub-data npx @clisbot/hub
Embedded mode supports one Hub process per data directory. It is intended for a personal or single-process Hub. Back up the whole data directory before upgrading or moving it.
Public addresses
Hub's backend defaults to http://localhost:6870. Daemons and outbound provider
connections can use it directly. Browser access uses the Clisbot web UI and Hub
APIs on the same public origin. In Docker all mode, that origin defaults to
http://localhost:6868.
Standalone Hub also defaults browser links to http://localhost:6868.
Starting Hub alone does not start the web UI. Local CLI onboarding prepares
the shared UI and proxy when launching a fresh daemon, and uses its selected
port for browser login links. If that daemon is already running without the
proxy configured, onboarding explains which settings need a deliberate restart.
GitHub event triggers use webhooks and need a public HTTPS address. Repository access can still work without the webhook. Slack's optional Webhooks transport also needs public HTTPS; Socket Mode does not.
When Hub is available at a stable public origin, set it before starting:
CLISBOT_HUB_APP_URL=https://hub.example.com npx @clisbot/hub
CLISBOT_HUB_APP_URL must be the public app origin, with Hub APIs routed to the
backend. For a separately hosted daemon web UI, configure its
CLISBOT_HUB_PROXY_URL=http://your-hub:6870. Use HTTPS outside localhost.
The daemon can instead persist features.webUi.enabled=true and
features.webUi.hubProxyUrl in config.json; the environment URL takes precedence.
On Hub, set CLISBOT_HUB_TRUSTED_CLIENT_IP_HEADER=x-clisbot-proxy-client-ip and
CLISBOT_HUB_TRUSTED_PROXY_ADDRESSES to the daemon proxy's IP address as seen by
Hub (comma-separated IP literals). Docker all sets both for its local proxy.
This preserves per-client quotas while rejecting IP headers from other peers.
Changing the public origin requires updating callback and webhook settings in
the provider apps. The app's Hub settings generate URLs for that public origin.
PostgreSQL
Set DATABASE_URL to use PostgreSQL instead of the embedded database:
DATABASE_URL=postgres://clisbot:password@localhost:5432/clisbot_hub \
npx @clisbot/hub
Use PostgreSQL for a durable server deployment, more than one Hub process, or an existing database backup and operations setup. Migrations run automatically at startup. Hub does not start listening when a migration fails.
Hub holds up to 30 connections to PostgreSQL. Set CLISBOT_HUB_DATABASE_POOL_SIZE to change that; keep every Hub process's pool, added together, under the server's max_connections.
The database also stores Hub's generated authentication secret. Set CLISBOT_HUB_AUTH_SECRET only when the deployment must supply that secret from a platform secret store. While the override is set, Hub uses it without replacing the stored secret. Changing the effective secret signs everyone out of the dashboard; execution credentials already issued remain valid until their execution ends.
App configuration
The operator configures GitHub, Slack, and Discord under Apps. Hub verifies the credentials before saving them in its database and starts the same provider runtime used by environment-configured deployments.
Environment variables remain available for deployments that manage secrets outside Hub. A complete environment configuration takes precedence over a saved application and appears as Managed by environment in the dashboard.
# GitHub
GITHUB_APP_SLUG=
GITHUB_APP_ID=
GITHUB_APP_CLIENT_ID=
GITHUB_APP_CLIENT_SECRET=
GITHUB_APP_PRIVATE_KEY= # or GITHUB_APP_PRIVATE_KEY_PATH
GITHUB_WEBHOOK_SECRET=
# Slack Socket Mode
SLACK_TRANSPORT=socket
SLACK_APP_ID=
SLACK_APP_TOKEN=
# Slack Webhooks instead of Socket Mode
SLACK_TRANSPORT=webhook
SLACK_APP_ID=
SLACK_CLIENT_ID=
SLACK_CLIENT_SECRET=
SLACK_SIGNING_SECRET=
# Discord
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
DISCORD_BOT_TOKEN=
See GitHub, Slack, and Discord for provider behavior and connection steps.
Bootstrap from environment
Browser setup is the default for a fresh database. An unattended deployment can create the first operator from environment variables instead:
CLISBOT_BOOTSTRAP_ORGANIZATION=My organization
CLISBOT_BOOTSTRAP_OWNER_EMAIL=me@example.com
CLISBOT_BOOTSTRAP_OWNER_PASSWORD=replace-with-a-temporary-password
The password must be at least 12 characters. Sign in once, replace it in the dashboard, then remove CLISBOT_BOOTSTRAP_OWNER_PASSWORD. Hub keeps the account and organization.
Docker Compose
The repository contains Hub and PostgreSQL as one Compose stack:
git clone https://github.com/longbkit/clisbot.git
cd clisbot/packages/hub
cp .env.example .env
Set CLISBOT_HUB_CREDENTIAL_MASTER_KEY in .env, along with the public URL and
bootstrap account settings, then run docker compose up -d.
This starts the backend on 6870. Serve the Clisbot web UI separately and route
its Hub APIs here, or use Docker all mode to run everything together.
Complete account setup in the Clisbot app. Set CLISBOT_HUB_APP_URL to the app's
public origin before starting the stack.
The stack publishes Hub on port 6870 and stores PostgreSQL data in a named volume.
It uses the shared ghcr.io/longbkit/clisbot:latest image with CLISBOT_RUN_MODE=hub.
The same image supports daemon (port 6868) or all (both services).
HTTPS with Caddy
For all mode, expose the shared UI through Caddy on the same host:
hub.example.com {
reverse_proxy 127.0.0.1:6868
}
Point hub.example.com at the host and open ports 80 and 443. Caddy obtains and renews the certificate.
Set these environment values on the Clisbot container:
CLISBOT_HUB_APP_URL=https://hub.example.com
CLISBOT_HOSTNAMES=hub.example.com
Only port 6868 needs to be published in all mode. For the Hub-only Compose
stack, publish 6870 only to the network used by the UI proxy (for a proxy on
the same host, use "127.0.0.1:6870:6870").
Fly
Clone the repository and create an app and database under names you control:
git clone https://github.com/longbkit/clisbot.git
cd clisbot/packages/hub
fly apps create your-hub
fly postgres create --name your-hub-db
fly postgres attach your-hub-db -a your-hub
Copy fly.example.toml to fly.toml and set your app name. It selects the shared
image in Hub mode. Set the persistent credential key as a Fly secret, then deploy:
fly secrets set CLISBOT_HUB_CREDENTIAL_MASTER_KEY="$CLISBOT_HUB_CREDENTIAL_MASTER_KEY" -a your-hub
fly deploy -a your-hub \
-e CLISBOT_HUB_APP_URL=https://clisbot.example.com
The Fly address serves the backend. Serve the Clisbot app at
https://clisbot.example.com and configure its Hub proxy to reach that backend.
Complete account setup in the app, or set the
bootstrap environment before deploying.
Keep one machine running. Hub holds Slack Socket Mode and Discord gateway connections and dispatches events to daemons, so a stopped machine misses events.
Upgrades
Pull the new image or source and deploy it. Migrations are forward-only. Back up the embedded data directory or PostgreSQL database first; it contains accounts, app credentials, configuration revisions, connections, and execution history.