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
- A Linux server with Docker and Docker Compose. Any modern distro — Ubuntu 22.04+, Debian 12+, Alpine, etc.
- A public domain pointed at the server.
- TLS — Let’s Encrypt is typical; Caddy handles it automatically, nginx and Traefik work fine too.
- 2 GB RAM minimum (4 GB recommended). 10 GB disk for the application, plus headroom for uploads and message history.
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:
PUBLIC_URL— for example,https://chat.example.comADMIN_USERNAME— the account that gets admin privileges on first loginREGISTRATION_MODE—invite_only(recommended),open, orclosed
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:
/healthreturnsdegraded— the database is unreachable. Check thechatalot-dbcontainer logs.- WebSocket disconnects — the reverse proxy may need
explicit WebSocket upgrade headers. Caddy handles this automatically;
nginx wants explicit
UpgradeandConnectiondirectives. - Voice calls fail to connect — TURN is not reachable. Confirm the firewall allows 3478/udp and the configured ephemeral UDP range (49152-65535/udp by default).
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.