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>
This commit is contained in:
parent
063044450f
commit
ac56596aed
4 changed files with 95 additions and 2 deletions
|
|
@ -1,4 +1,4 @@
|
|||
FROM node:20-slim
|
||||
FROM node:22-noble-slim
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
|
|
|
|||
63
docs/decisions/030-pr-71-base-image-noble-slim.md
Normal file
63
docs/decisions/030-pr-71-base-image-noble-slim.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# 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, чтобы плагин работал как заявлено.
|
||||
30
docs/handoff/pr-71-base-image-noble-slim.md
Normal file
30
docs/handoff/pr-71-base-image-noble-slim.md
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
pr: 71
|
||||
title: fix(docker): switch base image to node:22-noble-slim for rag-cli GLIBC compat
|
||||
---
|
||||
|
||||
## Что сделано
|
||||
Сменён Docker base image с `node:20-slim` (Debian 12 Bookworm, glibc 2.36) на `node:22-noble-slim` (Ubuntu 24.04 Noble, glibc 2.39) — однострочное изменение `FROM` в `Dockerfile:1`. Все остальные RUN layers, apt-пакеты, npm install, ENV, ENTRYPOINT — без изменений (проверено по пакетам: docker.io, ffmpeg — ✓; uv, gh, cloudflared — ставятся вне apt; chromium — known limitation, см. ниже).
|
||||
|
||||
- `Dockerfile:1` — `FROM node:20-slim` → `FROM node:22-noble-slim`
|
||||
- `docker-compose.yml` — без правок (service `opencode` использует `build: { context: ., dockerfile: Dockerfile }`, base image берётся из Dockerfile; pinned тегов image или упоминаний Node 20/Debian 12 в compose нет)
|
||||
- `README.md` — без правок (упоминаний «Node 20», «node:20», «Debian 12», «bookworm» в README нет — issue явно просит не плодить лишнее)
|
||||
- `docs/decisions/030-pr-71-base-image-noble-slim.md` — новый ADR-030 (следующий свободный номер после 029) с обоснованием выбора, проверкой пакетов на noble, known limitation по chromium snap, и 5 альтернативами
|
||||
|
||||
## Почему
|
||||
`@mathew-cf/opencode-memory` plugin тянет `@mathew-cf/rag-cli` как dependency для semantic search. RAG CLI — Rust native binary, требует **GLIBC_2.39**, но `node:20-slim` (Debian Bookworm) поставляется с **GLIBC 2.36** → binary падает, 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). Сменить хост нельзя: opencode работает **внутри контейнера**, хост изолирован. Смена base image на `node:22-noble-slim` — минимальное изменение, изолированное от хоста, без сборки rag-cli из исходников.
|
||||
|
||||
## Pending
|
||||
—
|
||||
- Файл `docs/decisions/030-pr-71-base-image-noble-slim.md` и этот handoff содержат placeholder `<71>` — после `create_pr` полученный PR номер надо вписать в frontmatter handoff (`pr:`) и в имя/контент ADR, отдельным коммитом `docs(handoff): set PR number`.
|
||||
|
||||
## Watch out
|
||||
- **chromium snap на Ubuntu 24.04 Noble — KNOWN LIMITATION, НЕ блокер.** На noble `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. Chromium используется опционально (browser MCP tools), НЕ основным entrypoint opencode. Issue #70 явно просит смену base image «точно, без отклонений» — без обходов chromium-snap. Workaround (вне scope): Playwright install или сторонний PPA — отдельный PR при необходимости.
|
||||
- **Тесты `tests/test_dockerfile.py` НЕ проверяют `FROM` строку** — тесты проверяют только `npm install -g` line (3 пакета: opencode-ai, repomix, @mathew-cf/opencode-memory) + regression guards. Смена `FROM` не сломает существующие тесты. Регрессионный тест на `FROM node:22-noble-slim` НЕ добавлен (issue не просит, не плодить лишнее).
|
||||
- **package-lock.json untracked** (`.opencode/package-lock.json`) — не относится к этому PR (зафиксировано в pr-69 handoff), не коммитить.
|
||||
- **Node 20 → 22 LTS** — мажорное обновление Node. Все установленные npm-пакеты (opencode-ai, repomix, @mathew-cf/opencode-memory) совместимы с Node 22 (проверено по их package.json engines). Если обнаружится несовместимость — отдельный fix PR.
|
||||
- **scaffold-handoff.sh** — нумерация ADR по `ls docs/decisions | grep -E '^[0-9]{3}-' | wc -l + 1` = 030 (после ADR-029). ADR создан вручную ДО scaffold с placeholder в имени (`030-pr-71-...`), scaffold нашёл существующий файл по `*-pr-71-base-image-noble-slim.md` паттерну и не создал дубликат.
|
||||
|
|
@ -117,7 +117,7 @@ opencode-config/
|
|||
├── uv.lock # Locked deps for Python project
|
||||
├── .pre-commit-config.yaml # ruff + UV hooks
|
||||
├── docker-compose.yml # 2 services (dind + opencode), opencode_network, 4 bind mounts, port 4096 on 0.0.0.0 — PR#24, PR#51
|
||||
├── Dockerfile # node:20-slim + uv + gh + chromium + docker.io + opencode-ai + repomix + @mathew-cf/opencode-memory + cloudflared — PR#24, PR#34, PR#57
|
||||
├── Dockerfile # node:22-noble-slim (Ubuntu 24.04, glibc 2.39) + uv + gh + chromium + docker.io + opencode-ai + repomix + @mathew-cf/opencode-memory + cloudflared — PR#24, PR#34, PR#57, PR#71
|
||||
├── .env.example # Placeholder-only env template (user copies to .env) — PR#24, PR#34 (TUNNEL_DOMAIN), PR#36 (OPENCODE_MEMORY_REMOTE/DIR)
|
||||
├── app_data/
|
||||
│ ├── opencode-memory/ # Persistent memory (separate git repo, gitignored) — PR#36
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue