diff --git a/.gitignore b/.gitignore index 25e5a08..cab97ec 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ ollama_backends.json .python/ cpython-*.tar.gz +docker-compose-linux-* diff --git a/deploy/README.md b/deploy/README.md index e4ec795..7a3c63b 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -16,14 +16,17 @@ What `install.sh` does (idempotent — safe to re-run, e.g. after `git pull`): -1. Checks prerequisites: Docker + compose plugin, and a Python ≥ 3.11. +1. Checks prerequisites: Docker, and a Python ≥ 3.11. If the system has none (Ubuntu 18.04 ships 3.6, 22.04 ships 3.10 — and the system python must never be replaced), the script fetches a standalone CPython build into `.python/` inside the repo — self-contained, needs only glibc ≥ 2.17, so it runs on any distro, old or new. The downloaded tarball is kept next to the repo root and reused on re-runs; for an offline server, drop the tarball next to `install.sh` beforehand - and it will be picked up instead of downloading. + and it will be picked up instead of downloading. Same for the docker + compose plugin: if the host doesn't have `docker compose` (18.04's docker + packages predate it), the script installs the compose v2 binary itself + into `/usr/local/lib/docker/cli-plugins/`. 2. Provisions `.env` — on the `deploy` branch it already ships with the deployment defaults (web UI off, auth off, Ollama Cloud, profile `navi_code`); the script generates the DB password in place of the diff --git a/deploy/install.sh b/deploy/install.sh index 4363ade..3d9c0b7 100755 --- a/deploy/install.sh +++ b/deploy/install.sh @@ -90,8 +90,42 @@ if ! command -v docker >/dev/null; then err "docker not found — install Docker (https://docs.docker.com/engine/install/) first"; exit 1 fi + +# compose v2: use the existing plugin, or auto-install it (single static +# binary; works on any distro with docker CLI >= 18.09). System-wide path — +# so `sudo docker compose` sees it too. Pre-downloaded binary next to +# install.sh wins on offline servers. if ! $SUDO docker compose version >/dev/null 2>&1; then - err "docker compose (v2 plugin) not available"; exit 1 + say "docker compose v2 not found — installing the plugin" + case "$(uname -m)" in + x86_64) COMPOSE_ASSET="docker-compose-linux-x86_64" ;; + aarch64|arm64) COMPOSE_ASSET="docker-compose-linux-aarch64" ;; + *) err "unsupported architecture for compose: $(uname -m)"; exit 1 ;; + esac + $SUDO mkdir -p /usr/local/lib/docker/cli-plugins + DEST="/usr/local/lib/docker/cli-plugins/docker-compose" + if [ -f "$REPO_DIR/$COMPOSE_ASSET" ]; then + $SUDO cp "$REPO_DIR/$COMPOSE_ASSET" "$DEST" + else + URL="https://github.com/docker/compose/releases/latest/download/$COMPOSE_ASSET" + if command -v curl >/dev/null; then + $SUDO curl -fsSL --retry 3 -o "$DEST" "$URL" || { err "compose download failed: $URL"; exit 1; } + elif command -v wget >/dev/null; then + $SUDO wget -q -O "$DEST" "$URL" || { err "compose download failed: $URL"; exit 1; } + else + err "no curl/wget on the host. Download on another machine:" + err " $URL" + err "put the file next to install.sh and re-run." + exit 1 + fi + fi + $SUDO chmod +x "$DEST" + if ! $SUDO docker compose version >/dev/null 2>&1; then + err "compose plugin installed but docker doesn't pick it up —" + err "the docker CLI is probably older than 18.09 (no plugin support)." + err "Report the output of: docker --version" + exit 1 + fi fi echo "OK: python ($($PYBIN --version 2>&1)), docker + compose"