Quickstart
Two containers, and everything else in the browser.
Budget 15–20 minutes, plus DNS propagation. Getting the app running is one command; the four DNS records your support address needs are the rest of it. Nobody sets this up in five minutes and we would rather say so here than have you find out at record three.
Before you start
- A domain you control. The support address lives on a subdomain of it —
help.example.com, never the root. Kiku does not check this at boot; it just cannot work without it. - A mailbox on that subdomain, with IMAP and SMTP credentials. Any provider.
- Docker with the Compose plugin.
- A reverse proxy terminating TLS. Not optional in practice — see Reverse proxy.
The Compose file
Grab compose.yaml from the repo.
It is the whole deployment: the app, Postgres and instance mail configuration.
Set APP_URL to the public HTTPS URL you will reach the app on. It has no default and the app
refuses to boot without it, because a guessed base URL breaks deep links and the session cookie
silently instead of loudly.
Generate SECRET_KEY with:
openssl rand -hex 32 # put this in SECRET_KEYThe app also needs instance mail at boot. The simplest correct answer is to reuse the support
mailbox’s own SMTP credentials: set INSTANCE_MAIL_HOST, INSTANCE_MAIL_USER and
INSTANCE_MAIL_PASSWORD, and choose INSTANCE_MAIL_FROM — for example,
Kiku <instance@example.com>. Port and TLS use the defaults shown in the
configuration reference.
The db service publishes no port, so the throwaway kiku:kiku password never leaves the
Compose network. Leave it or change it; it makes no difference from outside.
:1 is the major tag. docker compose pull takes every patch and minor of 1.x and can never
drag you across a breaking change unattended.
Start it
docker compose up -dMigrations run automatically at boot. If one fails the app logs the pending migrations and the
Postgres error and exits non-zero rather than serving a half-migrated schema — with
restart: unless-stopped that is a visible restart loop, which is the point.
Claim the instance
Open /setup. With zero users, any visitor can create the first admin account — no token in
the logs, no password parked in a Compose file forever.
Complete setup before you expose the instance publicly. Between
up -dand claiming the account, anyone who can reach the app can take it — and this instance’s admin reads every internal note in the inbox.
/setup returns 404 the moment any user exists, and until then the app logs a loud
“setup is unclaimed” warning on every boot.
The wizard then walks: admin account → Settings → Email → connection test → plus-addressing probe → done. Every step past the first is skippable and resumable, because waiting on DNS to propagate is not something you do in one sitting.
Connect the mailbox
That is Email setup: four DNS records on the subdomain, the IMAP and SMTP credentials, and the probe that tells you whether reply threading’s strongest layer will work on your mailbox.
Where to next
- Email setup — DNS, IMAP, the webhook path
- Configuration reference — environment variables and app settings
- Reverse proxy — Caddy, Traefik, nginx
- Upgrade and backup
- Embedding a Contact form, the snippet for your website
- Limits — what Kiku deliberately does not do