🧪 killBottleneck is in public beta — cloud and self-host.🧪 killBottleneck is in beta.Beta on GitHub →
Skip to content

Environment variables

Everything is configured in .env next to docker-compose.yml. Copy the template and edit:

bash
cp .env.example .env

After any change, rebuild — a restart is not enough:

bash
docker compose up -d --build

Old FLOWMAP_* names still work

The variables used to be called FLOWMAP_*. Both layers — Docker Compose and the server — understand the old names, so an .env from an earlier version keeps working. Fresh installs should use KB_*.

Basics

VariableDefaultWhat it does
KB_PORT8090Port the instance listens on: http://SERVER-IP:PORT.
TZUTCInstance time zone. Decides which zone "day" and "hour" mean for recurring templates, daily summaries and deadline notices. Set e.g. Europe/Prague. Applies to the whole instance — a team spread across zones gets the server's zone, not each user's.
KB_AUTO_HOUR5Hour (0–23, in TZ) from which recurring templates create that day's projects. If the server was off during that hour, they are created at the next later hour the same day.
KB_DEADLINE_HOUR7Hour of the morning deadline digest (0–23, local).

AI

VariableDefaultWhat it does
KB_AI_PROVIDERnonenone = no AI at all (everything else works). api = a remote AI service compatible with the killBottleneck API (address + token). ollama = your own local model. custom = your own endpoint honouring the same contract.
KB_AI_URL(empty)Endpoint address. For ollama the Ollama address, e.g. http://192.168.1.10:11434.
KB_AI_TOKEN(empty)Token for api / custom.
KB_AI_MODEL(empty)ollama only — the model to use (ollama pull <model> first).
KB_AI_TRANSCRIBE_URL(empty)Speech-to-text endpoint. Derived from KB_AI_URL when empty.

Daily summary

The one-line encouragement in My day can use a separate, smaller model.

VariableDefaultWhat it does
KB_SUMMARY_HOUR6Hour of morning generation (local).
KB_SUMMARY_ACTIVE_DAYS14Generate in the morning only for accounts that signed in within N days. 0 = everyone. Inactive users get theirs when they open the app.
KB_SUMMARY_PROVIDER(empty)Overrides KB_AI_PROVIDER just for summaries.
KB_SUMMARY_URL(empty)Overrides KB_AI_URL just for summaries.
KB_SUMMARY_MODEL(empty)Overrides KB_AI_MODEL just for summaries.
KB_SUMMARY_TOKEN(empty)Overrides KB_AI_TOKEN just for summaries.

Access and sign-in

VariableDefaultWhat it does
KB_SETUP_CODE(empty)Instance registration key. When set, every registration requires it. Empty = anyone who knows the address can register. The first account registered is always the administrator.
KB_GOOGLE_CLIENT_ID(empty)Google OAuth client ID. Empty = the "Sign in with Google" button is not shown.
KB_GOOGLE_CLIENT_SECRET(empty)Google OAuth client secret.
KB_GOOGLE_PICKER_API_KEY(empty)Enables picking attachments straight from Google Drive. Needs the OAuth client above plus the "Google Picker API" enabled in the same Google Cloud project. Files picked this way are stored as links — they never leave Drive.

Set a registration key before you expose the instance

On a machine reachable from the internet, an empty KB_SETUP_CODE means anyone who finds the address can create an account.

E-mail (SMTP) is not configured here — it lives in the PocketBase admin UI, see Configuration → E-mail.

Automations

Only needed if you actually use automations on goals.

VariableDefaultWhat it does
KB_PUBLIC_URL(empty)Public address of this instance, sent to the agent as callback_url so it can report back. Any address the agent can reach works — on a self-host a LAN address is fine. When unset, the "Application URL" from the PocketBase admin UI is used, which after installation is http://localhost:8090 — an agent on another machine would then call itself. The agent registry in the app shows the effective address and warns about localhost.
KB_AGENT_TIMEOUT_MIN90How many minutes an automation may run before the watchdog marks it failed.
KB_ALLOW_PRIVATE_WEBHOOKS(empty)1 allows agent webhooks to target private networks (10.x, 192.168.x, localhost). Disabled by default.

Why private webhooks are off by default

Without that guard, the server can be pointed at your internal network and used to scan it. Turn it on only when the automation target (n8n, for instance) genuinely runs on the same LAN.

Limits and instance mode

VariableDefaultWhat it does
KB_FILES_MB(empty)Cap in MB for uploaded attachments across the whole instance. Empty = no limit (the self-hosting default — it is your disk). 0 = uploading disabled, attachments can only be added as links.
KB_HOSTED(empty)1 marks an instance that runs at a provider alongside other customers. The instance administrator then may not point the AI service into a private network. On your own server leave this empty — a local Ollama on the LAN is the normal setup there.
KB_NOTIFY_EMAIL_DEFAULT(empty)Notification e-mails are off by default and driven by per-user preferences. Set to 1 to keep the old "e-mail on until the user turns it off" behaviour after an upgrade.

Notifications

The defaults are sane. Change them if notices are too noisy, or if an automation of yours legitimately produces more than the cap.

There is no "unlimited"

0 is not a magic value here — it means the cap is reached immediately. Raise the number instead of zeroing it.

VariableDefaultWhat it does
KB_NOTIFY_DIGEST_HOUR8Hour of the daily e-mail digest (0–23, local TZ).
KB_NOTIFY_DAILY_CAP50Maximum in-app notices per recipient per day. Above the cap the individual rows are replaced by one growing summary ("+N more") — nothing is silently lost.
KB_NOTIFY_EMAIL_DAILY_CAP10Maximum notification e-mails per recipient per day. Above the cap e-mails are dropped (the in-app notice still appears).
KB_NOTIFY_COALESCE_MIN10Notices for the same recipient arriving within this many minutes are merged into one message.
KB_UVODNI_MAPA1Create the sample map for every new user. 0 = new accounts start empty.

Updates and versioning

VariableDefaultWhat it does
KB_UPDATE_CHECK1The signed-in user's browser asks the GitHub API whether a newer release exists; the About dialog then offers a link. The instance itself sends nothing anywhere. 0 turns the check off.
KB_UPDATE_REPO(empty)Where releases are read from. Empty = the official repository. Set it only for your own fork.
KB_VERSIONdevBuild argument, not an .env variable — pass it on the command line: KB_VERSION=$(git describe --tags --dirty) docker compose up -d --build. Left at dev, the update check is not offered.

No telemetry

The update check runs in the user's browser against GitHub. The instance never phones home, so nothing about your installation reaches us.

fair-code — self-hosting and internal use are free, reselling as a hosted service is not.