Docker lifecycle

kimbap can detect, install, and update Docker on its host — this is what lets it bootstrap a completely fresh server into something that can run projects.

Detection

GET /api/system/status (or get_system_status via MCP) reports:

{
  "docker": {
    "installed": true,
    "serverVersion": "29.7.1",
    "composeVersion": "5.4.0",
    "composeV2": true,
    "updateAvailable": false
  }
}

Detection runs docker version --format json and docker compose version --short; a missing docker binary or a compose plugin below v2 shows up here. updateAvailable is a soft signal (server version below kimbap's minimum-expected baseline) — it doesn't block anything.

Installing / updating

Both actions call the same underlying mechanism: Docker's official convenience script, curl -fsSL https://get.docker.com | sh. The script is idempotent — running it against an existing install upgrades it in place — so "install" and "update" really are the same operation from kimbap's perspective.

This is deliberate: the convenience script already has broad, actively-maintained distro detection (Debian, Ubuntu, Fedora, CentOS, and more). Duplicating that logic in kimbap would only drift out of sync with it. On a genuinely unsupported platform, the script's own error is surfaced verbatim rather than kimbap guessing.

Confirmation-gated, always. POST /api/system/docker/install requires {"confirm": true} in the body; the install_docker/update_docker MCP tools require confirm: true as an argument and are admin-only. kimbap never installs or updates Docker without an explicit, current action — not on boot, not on a schedule.

The install/update run streams its output back live (chunked HTTP on the REST endpoint; the MCP tools return the full combined output once the script finishes) so you can watch exactly what's happening rather than staring at a spinner.

Before Docker exists

kimbap's UI and API are fully usable before Docker is installed — you can log in, manage users, and see system status. Anything that actually needs Docker (/api/projects/* deploy/lifecycle endpoints, Traefik provisioning) returns 503 until detection succeeds. This is exactly what the setup wizard's first screen is for.

What requires a real host

A clean install-from-nothing (a fresh VM that has never had Docker) is the one thing this can't be exercised against an already-Docker'd host — verify it manually against a disposable VM before relying on it in production. The idempotent re-install/update path (the common case — a host that already has some Docker install) works and is safe to run repeatedly.