opencode-config/docs/decisions/030-pr-71-base-image-trixie-slim.md
Sergey 92d21a142c
fix(docker): use node:22-trixie-slim instead of non-existent node:22-noble-slim (#73)
* fix(docker): use node:22-trixie-slim instead of non-existent noble-slim

* docs(adr): update ADR-030 for trixie-slim base image

* docs(handoff): update handoff for trixie-slim and add watch out note

* docs(handoff): set PR number

* docs(handoff): add handoff for PR#73

* fix(ci): drop dangling ADR-031 ref in pr-73 handoff

* docs(adr): add ADR-031 for PR#73 trixie-slim base image

---------

Co-authored-by: opencode-agent <agent@opencode.local>
2026-07-26 04:43:03 +03:00

7.9 KiB
Raw Permalink Blame History

ADR-030 (PR #71): Switch Docker base image to node:22-trixie-slim for rag-cli GLIBC compat

Статус

Accepted (2026-07-26)

Контекст

@mathew-cf/opencode-memory plugin тянет @mathew-cf/rag-cli как dependency для semantic search. RAG CLI — Rust native binary, требует GLIBC 2.39. Базовый image node:20-slim (Debian 12 Bookworm) поставляется с GLIBC 2.36 → binary падает с ошибкой совместимости glibc, semantic search молча неработоспособен, memory_search деградирует к keyword-only (grep).

ADR-024 (PR #57) зафиксировал это как «известная проблема, НЕ блокер» и явно отметил: «Полный fix semantic search (смена base image) — вне scope этого PR». PR #71 = тот самый follow-up.

Все 5 опубликованных версий @mathew-cf/rag-cli-linux-x64 (0.4.0, 0.5.0, 0.6.0, 0.7.0, 1.0.0) требуют GLIBC_2.39. CI плагина собирается на ubuntu-latest (= 24.04 Noble, glibc 2.39) — prebuilt binary слинкован с этой версией glibc. Сменить хост (Ubuntu 22.04 с glibc 2.35 — недостаточно) нельзя: opencode работает внутри Docker-контейнера, хост изолирован.

opencode в Docker — base image меняет только контейнер, не хост. Это минимальное изолированное изменение, не требующее обновления ОС сервера.

Тег node:22-noble-slim не существует в Docker Hub (проверено через API: count=0). Официальные образы node базируются только на Debian, не Ubuntu. PR#71 использовал несуществующий тег — PR#73 (этот) исправляет.

Проверка пакетов на Debian 13 trixie

  • docker.io — ✓ v29.1.3-0ubuntu3 (amd64, security/universe), доступен.
  • ffmpeg — ✓ v7:6.1.1-3ubuntu5 (universe), доступен.
  • chromium — ✓ доступен как обычный apt-пакет. Debian 13 trixie НЕ использует snap (в отличие от Ubuntu noble), chromium ставится через apt-get install -y chromium напрямую — реальный browser, не transitional wrapper. Puppeteer-интеграция (PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium) работает as-is.
  • uvНЕ в apt, ставится через curl -LsSf https://astral.sh/uv/install.sh (прямой install script), не зависит от дистрибутива ✓.
  • ghНЕ в apt по умолчанию, ставится через сторонний apt-репозиторий (https://cli.github.com/packages), ключ/репозиторий не зависят от дистрибутива ✓.
  • cloudflared — прямой download бинарника с GitHub releases, не зависит от apt ✓.
  • npm install -g opencode-ai repomix @mathew-cf/opencode-memory --unsafe-perm — Node 22 совместим с этими пакетами ✓.

Решение

Сменить FROM в Dockerfile:

FROM node:22-trixie-slim

Однострочное изменение. node:22-trixie-slim (Debian 13 trixie, glibc 2.41 ≥ 2.39, Node 22 LTS). Все остальные RUN layers, apt-пакеты, npm install, ENV, ENTRYPOINT — без изменений (проверено по пакетам выше).

Смена node:20-slimnode:22-trixie-slim:

  • GLIBC 2.36 → 2.41 — fixes rag-cli semantic search (требуется ≥ 2.39).
  • Node 20 → Node 22 LTS — совместим со всеми установленными пакетами.
  • Debian Bookworm → Debian Trixie — имена apt-пакетов совпадают для всех используемых.

docker-compose.yml правок не требует — opencode service использует build: { context: ., dockerfile: Dockerfile }, base image берётся из Dockerfile. Pinned тегов image или упоминаний Node 20/Debian 12 в compose нет.

README.md правок не требует — упоминаний «Node 20», «node:20», «Debian 12», «bookworm» в README нет.

chromium snap problem отпадает — Debian не использует snap

На Ubuntu 24.04 chromium — virtual package, предоставляемый chromium-browser (transitional → chromium snap). В Debian 13 trixie snap не используется вообще — chromium ставится через apt как обычный пакет, реальный browser, не transitional wrapper. Puppeteer-интеграция (PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium, PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true) работает as-is. Known limitation из PR#71 (chromium snap) отпадает.

Issue #70 просит смену base image «точно, без отклонений» — на Debian 13 trixie chromium snap problem отсутствует, обходов не требуется.

Альтернативы

  • cargo install rag-cli (сборка из исходников) — отклонено: требует ~500MB Rust toolchain (rustc, cargo, crates.io deps), +время сборки на каждом docker build, +image size. Смена base image — 0 дополнительных MB toolchain, готовый prebuilt binary работает as-is.

  • debian:trixie-slim + Node вручную (через NodeSource или nvm) — отклонено: Trixie = Debian 13, glibc 2.41 — подходит, но требует ручной установки Node 22 поверх slim image (apt node = старая версия, нужен NodeSource apt-репозиторий или download tarball). node:22-trixie-slim уже включает Node 22 LTS — нулевая настройка.

  • node:lts-trixie-slim (Node 24 LTS) — отклонено: мажорное обновление Node 22→24. Все установленные npm-пакеты (opencode-ai, repomix, @mathew-cf/opencode-memory) тестировались на Node 22 LTS; Node 24 не валидирован, риск несовместимости. Оставаться на Node 22 LTS минимизирует риск.

  • node:trixie-slim (latest Node 26) — отклонено: не LTS (latest = Node 26). Для production-образа требуется LTS-канал с long-term support. Latest-тег дополнительно не pinned — drifting risk при docker build.

  • Обновление хост-ОС сервера (linux-1) до Ubuntu 24.04 — отклонено и ненужно: opencode работает внутри контейнера, хост изолирован. Смена base image меняет только контейнер, не хост. Обновление хост-ОС — отдельная задача с рисками (другие сервисы на linux-1), без выгоды для этой проблемы.

  • node:20-bookworm (full image, GLIBC 2.36) — отклонено в ADR-024: bookworm (Debian 12) = GLIBC 2.36, той же версии что slim — не решает проблему. Full image ~1GB vs ~200MB slim, лишние пакеты, и НЕ исправляет rag-cli.

  • Оставить node:20-slim + keyword-only search (без RAG) — отклонено: semantic search — заявленная фича @mathew-cf/opencode-memory (hybrid search: ripgrep + local RAG). Деградация к keyword-only теряет semantic recall для концептуальных запросов. Смена base image — минимальный fix, чтобы плагин работал как заявлено.