Skip to content

Self hosting

Keanan is built to be owned. Your license buys the complete stack, twelve months of updates, and a deployment that runs on a single low cost machine. This guide walks the exact path from purchase to production.

After checkout you receive an email titled “Your Keanan self hosted license key” containing a key like KEANAN-XXXXX-XXXXX-XXXXX-XXXXX.

Go to keanan.app/activate and enter the key, your company name, and your GitHub username. Two things happen immediately:

  1. Your license is registered to your company.
  2. Your GitHub account is invited to the private source repository — accept the invitation from your GitHub notifications.

Keep the key: your deployment needs it in the next step. If anything goes sideways, sales@keanan.app reaches a human.

Terminal window
git clone git@github.com:Keanan-app/dejgo.git keanan
cd keanan
Service Role
web Django API served by Daphne, WebSockets included
celery and beat Reminders, monthly invoices, slide previews
db PostgreSQL 16
redis Cache, channels and task broker
unleash Self hosted feature flags
caddy Automatic TLS, serves the dashboard and media
Terminal window
cd infra/aws
REPO_URL=git@github.com:Keanan-app/dejgo.git \
KEANAN_DOMAIN=hr.your-company.com \
KEANAN_LICENSE_KEY=KEANAN-XXXXX-XXXXX-XXXXX-XXXXX \
./deploy.sh

The script finds the latest Ubuntu image, creates a key pair and a security group, launches the instance and installs everything through cloud init. When it finishes, point an A record for your domain at the printed IP address. Caddy obtains a TLS certificate the moment DNS resolves.

A t4g.small instance carries a team of ten to fifty comfortably. Move to t4g.medium when you pass that.

Any Linux machine with Docker works the same way:

Terminal window
cd infra
cp .env.production.example .env
# fill in KEANAN_DOMAIN, SECRET_KEY, DB_PASSWORD, UNLEASH_ADMIN_TOKEN
# and KEANAN_LICENSE_KEY from your purchase email
docker compose -f docker-compose.prod.yml up -d --build

On every start the instance validates KEANAN_LICENSE_KEY against the Keanan license server, then caches the result locally:

  • First start needs one successful check, then the instance is activated for good.
  • Later starts keep working even when the license server is unreachable — the cached activation carries you through outages and air-gapped restarts.
  • A refunded or revoked license stops validating; the instance refuses to boot with a clear message rather than failing mysteriously.

Nothing about your data ever leaves your machine: the check sends only the license key and your configured domain.

The containers are stateless apart from Postgres and media. When a client outgrows a single instance, move the database to RDS by changing the DB_ variables, move media to S3 by setting the AWS_ variables, and run the web and worker containers on any platform you like. No code changes are involved.

A nightly run of export_tenant plus a copy of the archive off the machine is a complete backup. Restoring is described in the migration guide.