Docs

Team & admin

Self-hosting

Running Comity on your own single host with Docker Compose, for Enterprise pilots.

On this page

Important

Self-hosting is available for Enterprise pilots, set up together with us. There is no self-serve installer, license or high-availability setup. Contact hello@comity.so to discuss a self-hosted deployment.

This page describes what the deployment consists of, so you can judge whether it fits your infrastructure.

What runs

Everything runs from one Docker Compose file on one Linux host (sized for 2 GB RAM plus 2 GB swap):

Service Role
postgres PostgreSQL 18. Not published outside the Compose network.
migrate Applies database migrations on every start; api and worker start only after it succeeds.
api The REST API, MCP endpoint and webhooks receiver (port 8080, internal).
worker Background jobs: expiry sweeps, event partitions, notification delivery, GitHub sync, Stripe usage reports.
caddy TLS termination on ports 80/443 with automatic Let's Encrypt certificates; serves the CLI tarball under /cli/.

The web dashboard (sign-in, browser login approval for comity login, Messages, Settings) is not part of this Compose stack; its address is configured with WEB_URL. Plan where it runs with us. Without it, developers sign in with tokens created by the admin command (comity login --token cmt_…).

The domain's DNS must point straight at the host (no proxying CDN in front): Caddy obtains its own certificate, and long-lived MCP and SSE streams must pass through unbuffered.

Configuration

A provisioning script writes /opt/comity/.env once with random database passwords and a master key. The server reads:

Variable Required Default Purpose
DATABASE_URL yes Owner connection (migrations, sign-in, background sweeps)
APP_DATABASE_URL yes Application role comity_app, subject to row-level security
COMITY_MASTER_KEY yes 32 bytes, base64. Wraps every org's data key.
PUBLIC_URL for GitHub App The API's public URL
WEB_URL https://comity.so Dashboard origin (CORS, invite and device-login links)
PORT / HOST 8080 / 0.0.0.0
LOG_LEVEL info
RESEND_API_KEY, EMAIL_FROM for email Email sign-up, password reset and invite emails
GITHUB_OAUTH_CLIENT_ID, GITHUB_OAUTH_CLIENT_SECRET for GitHub login
STRIPE_* no Billing; off unless STRIPE_SECRET_KEY is set
EGRESS_ALLOW_PRIVATE false Allow webhook and Slack URLs on private networks
COMITY_DOMAIN Caddy's site address

Caution

Back up COMITY_MASTER_KEY off the host and never change it in place. Losing it, or replacing it without re-wrapping the org keys, makes all encrypted content unreadable, including in backups.

First org

The server has an admin command instead of an admin UI. Bootstrapping prints the owner's token once:

Terminal
docker compose run --rm migrate node dist/server/admin.js bootstrap --org acme --name "Acme Inc" --email owner@acme.example

Other admin commands: create-member, create-token, and set-plan --org <slug> --plan <free|team|business|enterprise> [--developer-limit n|unlimited] [--repo-limit n|unlimited] (custom limits apply to Enterprise only).

Developers then point the CLI at your server:

Terminal
npm i -g https://comity.example.com/cli/comity-cli.tgz
comity login --server https://comity.example.com

comity update reads the release manifest from your server (/cli/latest.json), so self-hosted machines update from your host.

Backups

A systemd timer runs a pg_dump daily at 03:17 UTC to /opt/comity/backups/ and keeps 14 days. Copy dumps off the host. A backup is only restorable together with the master key that was active when it was taken.