Run your own Bákn.
One container image, your domain, your database. Nothing reports back to us, and no account with us is required.
Before you start
- A machine with a public IP. 1 vCPU / 2 GB is comfortable.
- A hostname pointing at it, resolving before the first start — Caddy answers the certificate challenge on port 80, and issuance fails for a name pointing somewhere else.
- Docker with the Compose plugin.
-
Ports open:
80and443TCP,3478TCP + UDP, and49152–49999UDP.
That UDP range is the call relay — one port per concurrent call. Block it and messaging still works while calls fail silently, because a call with no reachable relay simply never connects.
Install
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 # your hostname, email, version, and two secrets
chmod 600 .env
docker compose up -d
Generate the secrets on the machine rather than inventing them:
openssl rand -base64 32
Then check it came up:
curl https://your-host.example.com/api/v1/health/ready
BAKN_ADMIN_PASSWORD is required — compose refuses to
start without it. There is deliberately no default: the image is public, so a
password shipped inside it would be one every operator shares and anyone can read.
It bootstraps the first login only, and cannot reset the password later.
Pin a version
BAKN_VERSION in .env selects the image tag. Pin it.
Tracking latest means the next pull upgrades you at a moment you did
not choose — possibly across a major release your licence does not cover.
docker pull ghcr.io/theoistic/bakn-server:1.0.4Your own database
The bundled PostgreSQL container is the simplest option. To use a managed cluster
instead, set the connection string and delete the postgres service:
Bakn__Database: postgresql://user:pass@host:25060/db?sslmode=require
Bakn__DatabaseProvider: postgres
Grant the app role CREATE on schema public
first. PostgreSQL 15+ no longer grants it automatically, so a freshly
created user cannot build the schema and the server crash-loops on
permission denied for schema public. Connected as the admin, to your
application's database:
GRANT USAGE, CREATE ON SCHEMA public TO "your-app-user";
Pointing clients at your server
The published clients pre-fill our hosted server, but the Server URL field on the login screen is editable and remembered per device — your users can point the stock client at you by typing it once.
To hand them a client that defaults to your server, build one with
-p:BaknDefaultServerUrl=https://your-host.example.com/. Note that the
updater points at a compile-time feed, so your builds will not receive our updates,
and ours will not receive yours.
Licence
Bákn is free to run for small deployments, and paid past that. Either threshold triggers the paid tier — a 200-person company running a 10-user instance needs a licence, and so does a 12-person company running a 400-user instance.
- Under 50 users on the instance
- Organisation under 50 people
- Commercial use allowed
- No feature restrictions
- 50+ users, or a 50+ person organisation
- One-time fee, not a subscription
- Covers one major release, perpetually
- Moving to the next major release renews it
Crossing a threshold gives you 60 days to sort out a licence, so growth never puts you in breach overnight. Offering Bákn to third parties as a hosted service is a separate conversation — the same address.