Self-host Chatalot

Chatalot is built to be installed once and operated for years. One Docker stack, one PostgreSQL database, one reverse proxy. No federation, no cloud dependency, no phone-home.

This page is the technical guide for the free, open-source self-host path. If you’d rather have Seglamater run the instance for you, see Self-host vs Managed — managed deployments use a different bundle-driven flow with signed updates and support included.

Two paths, both real

Free, open-source self-host

Pull the container images from registry.seglamater.app/seglamater/chatalot (cosign-signed, see the Security page). Run them. Configure your domain. You own the deployment end to end. The canonical source lives at the Seglamater Forgejo repo. Public-mirror access and community channels are part of an open-core rollout still in planning — reach out via contact@seglamater.com for self-hoster questions in the meantime.

Managed by Seglamater

Per-instance signed bundle, automated update pipeline tied to your domain, a real support relationship with response-time commitments. Same software, different operating posture. Pricing on the comparison page.

The rest of this page covers the OSS self-host path.

Prerequisites

Quickstart

1. Clone the repository

git clone https://forgejo.seglamater.app/seglamater/chatalot.git
cd chatalot

2. Generate secrets

./scripts/generate-secrets.sh
./scripts/generate-keys.sh

These create secrets/jwt_private.pem, secrets/jwt_public.pem, a random DB_PASSWORD, and a TOTP_ENCRYPTION_KEY. Everything lives in secrets/. Do not commit it. Back it up separately — without these keys, previously-encrypted TOTP secrets cannot be decrypted.

3. Configure .env

cp .env.example .env
$EDITOR .env

At minimum, set:

4. Start the stack

docker compose up -d

PostgreSQL comes up first, migrations apply automatically, then the Chatalot server. Health-check after a minute:

curl https://chat.example.com/health
# expect: {"status":"ok","version":"...","uptime_secs":N,"db_healthy":true}

5. Register the admin user

Open PUBLIC_URL in a browser and register. The first account whose username matches ADMIN_USERNAME is granted admin privileges. Enable 2FA immediately under Settings → Security → TOTP.

Voice and video (WebRTC)

Chatalot uses peer-to-peer WebRTC with a TURN server for NAT traversal. The bundled coturn profile handles this:

docker compose --profile turn up -d

Set TURN_USER, TURN_PASSWORD, and TURN_EXTERNAL_IP in .env. For larger deployments, a dedicated TURN server with per-session ephemeral credentials is recommended (the manifest supports this; the wiring is on the roadmap).

Backups

The PostgreSQL database holds message ciphertext, accounts, settings, and per-user encrypted keys. Back it up. Uploaded files live in a bind-mounted directory. Back that up too. The secrets/ directory is irreplaceable — archive it offsite, separately from the database backup.

Updating

For the OSS self-host path, the update flow is:

git pull
docker compose pull
docker compose up -d

The managed-update pipeline (with signature verification, staged rollouts, automatic rollback on failure) is reserved for managed-tier customers — that’s a meaningful chunk of the operational value the managed tier provides. Self-host operators who want similar guarantees can wire up cosign verification themselves; the public key is documented on the Security page.

What managed clients get instead

Managed clients don’t run docker compose pull. They run an admin-UI button (or a scheduled policy) that fetches a signed bundle from updates.seglamater.app, verifies the cosign signature against the SHA-pinned public key, swaps containers atomically, and rolls back automatically on health-check failure. The bundle includes the migration set and any per-instance config the deployment needs. There is no shell access required for routine updates. See the comparison page for the full delta.

Troubleshooting

The repository’s admin guide covers the common cases:

For anything not covered there, file an issue on the public mirror once it’s up. Self-host support is community-driven and best-effort. If you need response-time commitments, you want the managed tier.