opencode-config/docs/decisions/030-pr-71-base-image-noble-slim.md
Sergey ac56596aed
fix(docker): switch base image to node:22-noble-slim for rag-cli GLIBC compat (#71)
* fix(docker): switch base image to node:22-noble-slim

* docs(adr): add ADR-030 for base image switch

* docs(handoff): add handoff for base image switch

* docs(handoff): set PR number

* docs(handoff): replace PR-NUMBER placeholder with 71

* docs(project-map): update Dockerfile description after base image switch

---------

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

63 lines
No EOL
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ADR-030 (PR #71): Switch Docker base image to node:22-noble-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 меняет только контейнер, не хост. Это минимальное изолированное изменение, не требующее обновления ОС сервера.
### Проверка пакетов на Ubuntu 24.04 Noble
- `docker.io` — ✓ v29.1.3-0ubuntu3 (amd64, security/universe), доступен.
- `ffmpeg` — ✓ v7:6.1.1-3ubuntu5 (universe), доступен.
- `chromium` — ⚠ virtual package, предоставляется `chromium-browser` (transitional → **chromium snap**). Snap в Docker-контейнере без systemd НЕ запускается. `chromium-browser` ставится (48.9kB transitional), тянет `snapd`, но реальный браузер через snap не запустится. Puppeteer-интеграция (`PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium`) деградирует — known limitation, НЕ блокер (chromium используется опционально, не основным entrypoint).
- `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`:
```dockerfile
FROM node:22-noble-slim
```
Однострочное изменение. `node:22-noble-slim` = Ubuntu 24.04 Noble (glibc 2.39) + Node 22 LTS. Все остальные RUN layers, apt-пакеты, npm install, ENV, ENTRYPOINT — без изменений (проверено по пакетам выше).
Смена `node:20-slim``node:22-noble-slim`:
- GLIBC 2.36 → 2.39 — fixes rag-cli semantic search.
- Node 20 → Node 22 LTS — совместим со всеми установленными пакетами.
- Debian Bookworm → Ubuntu Noble — имена apt-пакетов совпадают для всех используемых (кроме chromium, см. limitation).
`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 нет.
### Known limitation: chromium snap
На Ubuntu 24.04 `chromium` — virtual package, предоставляемый `chromium-browser` (transitional → chromium snap). Snap в Docker-контейнере без systemd не работает. `chromium-browser` (48.9kB transitional) ставится через apt, но тянет `snapd` — реальный snap-бинарник chromium не запустится без snap-демона.
Puppeteer-интеграция (`PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium`, `PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true`) деградирует: бинарник `/usr/bin/chromium` будет transitional wrapper, не реальный browser. Это **known limitation, НЕ блокер** — chromium используется опционально (browser MCP tools), не основным entrypoint opencode. Workaround (вне scope этого PR): установка chromium через Playwright (`npx playwright install chromium`) или через сторонний PPA/deb — отдельный PR при необходимости.
Issue #70 явно просит смену base image «точно, без отклонений» — без обходов chromium-snap. Limitation зафиксирована в ADR и handoff.
## Альтернативы
- **`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 testing, glibc 2.40 — подходит, но требует ручной установки Node 22 поверх slim image (apt node = старая версия, нужен NodeSource apt-репозиторий или download tarball). `node:22-noble-slim` уже включает Node 22 LTS — нулевая настройка.
- **Обновление хост-ОС сервера (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, чтобы плагин работал как заявлено.