Getting started.
From nothing to a running server your team can sign in to. Roughly ten minutes, most of it waiting for DNS.
What you are running
Bákn is one server plus the clients that connect to it. The server holds accounts, conversations, and message history; it hands out short-lived credentials for the TURN relay so calls work between people who cannot reach each other directly.
- Server — a container image,
ghcr.io/theoistic/bakn-server. - Database — PostgreSQL, or SQLite for a small instance.
- Attachments — a local volume, or S3-compatible object storage.
- TURN — bundled, and required for calls to work across networks.
One server process only. The realtime hub keeps connections in memory with no backplane, so a second replica cannot reach the first's sockets — a message to someone connected elsewhere would be silently dropped. Scale the machine, not the instance count.
1. Run the server
Full instructions, including TLS and the firewall ports calls need, are on the self-hosting page. The short version:
mkdir -p /opt/bakn && cd /opt/bakn
curl -fsSLO https://bakn.fo/selfhost/docker-compose.yml
curl -fsSLO https://bakn.fo/selfhost/Caddyfile
curl -fsSL https://bakn.fo/selfhost/env.example -o .env
nano .env # hostname, email, and the three secrets
docker compose up -d
Check it answered:
curl https://chat.example.com/api/v1/health/ready
# {"status":"ready"}2. Sign in as the first admin
The first start creates the admin account using BAKN_ADMIN_PASSWORD from
your .env. That value applies only while the account has no
password of its own — changing it in .env later does nothing, because by
then the account has one.
Install a client from the downloads section, put your server's address in the Server URL field, and sign in. Change the password once you are in.
The published clients pre-fill our hosted server. Your users type yours once and it is remembered per device — or you build clients that default to yours, see self-hosting.
3. Decide who can get in
A fresh server accepts self-registration: anyone who can reach it can create an account. That is usually wrong for a team server, and it is worth deciding before you hand the address out.
Leave BAKN_ALLOW_REGISTRATION blank. Anyone reaching the server can
sign up. Fine for a private network, rarely right on the public internet.
Set BAKN_ALLOW_REGISTRATION=false. The Register button disappears
from the client and the endpoint refuses. Accounts arrive only from an admin.
Set BAKN_ALLOW_REGISTRATION=false and configure
single sign-on. Your identity provider decides who exists,
and accounts are created on first sign-in. Best for anything with a directory
behind it.
Closing registration does not affect SSO — that is the point of the combination, not a gap in it. It also does not lock out existing accounts; password sign-in keeps working for everyone who already has one.
4. Check calls actually work
Messaging works long before calling does, so it is easy to believe the deployment is finished when it is not. Test a call between two devices on different networks — one on Wi-Fi, one on mobile data. Two devices on the same LAN reach each other directly and prove nothing about the relay.
If messages work and calls do not, it is almost always the TURN relay: UDP
49152–49999 blocked by a cloud firewall, or the machine sitting behind NAT
so the relay advertises an address the far side cannot route to. Both are covered under
self-hosting.
Next
- Configuration — every setting, what it does, and what happens if you leave it alone.
- Single sign-on — OIDC against Entra ID, Keycloak, Google, or Authentik.
- Self-hosting — TLS, databases, backups, upgrades.