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

Installation

This page is the "properly, on a server" version of the Quick start.

What you need

  • Docker with the Compose plugin. Nothing else — no Node.js, no database server, no web server. The image builds the frontend and bundles PocketBase, which serves the API, the database, authentication and the static files from a single container.
  • A few hundred megabytes of disk for the image, plus whatever your attachments take.
  • Ideally a machine that stays on. Recurring templates, daily summaries and deadline notices are driven by cron jobs inside the container. Nothing is silently skipped — if the server was off during the target hour, the jobs catch up later the same day — but a machine that is on in the morning delivers them at the hours you configured.

No Docker yet? Pick your system

The rest of this page is the same for everyone — this part only gets your particular machine to the point where docker compose works.

Windows 10 / 11 — step by step
  1. Download Docker Desktop from docker.com and install it. The installer adds WSL 2 for you and asks for a restart once — let it restart.
  2. Start Docker Desktop and wait until it says Engine running in the bottom left. While it is still amber, the commands below will report that Docker is not running.
  3. Get the code: on the project page use the green Code → Download ZIP button and unpack it into, say, C:\killbottleneck. (If you have Git, git clone works too.)
  4. Open that folder in Explorer, click into the address bar, type powershell and press Enter. A command line opens right in the correct folder.
  5. Copy the configuration and start:
    powershell
    Copy-Item .env.example .env
    docker compose up -d --build
  6. Open http://localhost:8090 in your browser and create the admin account.

Things to watch out for on Windows:

  • When the computer sleeps or shuts down, so does the instance. Daily summaries and deadline notices then catch up later the same day. For a team, a machine that stays on is the better host.
  • Want to reach it from a phone or a colleague's computer? Use the machine's IP address (ipconfig) instead of localhost, and when prompted, allow Docker through the Windows firewall for the private network.
  • If port 8090 is taken, change KB_PORT in the .env file.
Linux (Ubuntu, Debian) — step by step
  1. Install Docker with the official script and add yourself to the docker group so you do not need sudo for every command:
    bash
    curl -fsSL https://get.docker.com | sudo sh
    sudo usermod -aG docker $USER
    After the second command log out and back in (or reboot) — otherwise the new group is not in effect yet and Docker reports permission denied.
  2. Check that it works:
    bash
    docker run --rm hello-world
  3. Then continue with Get the code below. There is nothing else to install — the image builds Node.js and the database into itself.
macOS

Download Docker Desktop for Mac (mind the right variant — Apple silicon vs Intel), start it, then continue with Get the code below. The same caveat as on Windows applies: a sleeping Mac means a sleeping instance.

Get the code

bash
git clone https://github.com/tengolabs/killbottleneck.git
cd killbottleneck

Configure

bash
cp .env.example .env

The defaults work as they are. The variables worth a look before the first start:

VariableWhy now
KB_PORTIf something already uses 8090.
TZSet your zone (e.g. Europe/Prague), otherwise cron jobs run in UTC.
KB_SETUP_CODESet it if the machine is reachable from the internet — otherwise anyone who knows the address can register.
KB_PUBLIC_URLOnly needed for automations, so an agent knows where to report back.

The full list is in Environment variables.

Start

bash
docker compose up -d --build

The first build takes a few minutes (it compiles the frontend). Afterwards:

bash
docker compose ps
docker compose logs -f killbottleneck

Open http://SERVER-IP:8090 — a fresh instance greets you straight with creating the administrator account (the first account becomes one automatically).

Stamp the version

Without it the instance reports itself as dev and does not offer update checks. For a real deployment:

bash
KB_VERSION=$(git describe --tags --dirty) docker compose up -d --build

Always rebuild, never just restart

The application and all its server-side logic are baked into the image. After any change — new code, or an .env variable such as TZ — use:

bash
docker compose up -d --build

docker compose restart will silently keep running the old build. This catches people out often enough to be worth repeating.

Where things live

PathWhat it is
./pb_dataSQLite database and uploaded files. This is the only thing you must back up.
./docker-compose.ymlService definition. Overwritten by updates — do not edit it.
./docker-compose.override.ymlYour local additions (a reverse proxy, extra ports). Not overwritten by updates.
./.envYour configuration. Not overwritten by updates.

If you rename the compose service

docker-compose.override.yml refers to the service by name. Rename the service in docker-compose.yml without touching the override and docker compose config fails, so the stack will not come up at all.

The PocketBase admin UI

The instance also exposes the PocketBase superuser interface at http://SERVER-IP:8090/_/. The superuser account is created on first start — the link is in docker compose logs. You need it for exactly two things: configuring SMTP and low-level database inspection. Day-to-day administration happens in the application itself.

Next

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