From 9f3e5c575e15ec085e111f5bc960bc691a21d106 Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Sat, 3 Oct 2026 10:20:20 +0900 Subject: [PATCH 1/5] =?UTF-8?q?docs:=20base=20=E3=81=AE=E5=89=8A=E6=B8=9B?= =?UTF-8?q?=E3=81=AE=E6=AE=B5=E9=9A=8E=201=20=E3=81=AE=E8=A6=81=E6=B1=82?= =?UTF-8?q?=E3=81=A8=E5=8F=97=E3=81=91=E5=85=A5=E3=82=8C=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=E3=82=92=E6=9B=B8=E3=81=8F=EF=BC=88#400=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 課題の本文の写しを issues/ に置き、要求で使う語(DinD・展開後の大きさ・文書の除外)を用語集へ足す。 Co-Authored-By: Claude Opus 5.5 --- docs/glossary.md | 3 + docs/glossary/glossary.json | 21 ++++ issues/issue-400-requirements.md | 163 +++++++++++++++++++++++++++++++ 3 files changed, 187 insertions(+) create mode 100644 issues/issue-400-requirements.md diff --git a/docs/glossary.md b/docs/glossary.md index 4bebc4e2..9cf01ce7 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -181,6 +181,9 @@ base の設定が派生イメージと lfm へ届く道筋(containers/*/Docker | 取り込み | — | lfm の Dockerfile が COPY --from=devbase-base:latest で base のイメージからファイルやディレクトリを同じパスへ持ち込むこと | — | — | `docs/specifications/lfm-base-settings.md` | | 到達の検査 | — | base の Dockerfile から base の設定を集め、それぞれが lfm へ届くかを Docker を起動せずに判定するテスト(tests/containers/test_lfm_base_settings.py) | — | — | `docs/specifications/lfm-base-settings.md` | | 除外表 | — | 到達の検査が、lfm へ届かなくてよいとする base の項目と、その理由の一覧 | — | — | `docs/specifications/lfm-base-settings.md` | +| DinD | — | コンテナの中で dockerd を起こし、そのコンテナの中だけの docker を使う形。ENABLE_DIND で有効にする。ホストの docker.sock を mount して使う形と区別する | — | — | — | +| 展開後の大きさ | — | 建てたイメージから作ったコンテナで du -sbx / を測ったバイト数。docker images の圧縮後の大きさとは違う | — | — | — | +| 文書の除外 | — | dpkg の path-exclude の設定で、apt が入れるパッケージから文書などの置き場を展開しないこと。base を FROM で継ぐ派生イメージにも効く | — | — | — | ## コンテナの起動(`container-start`) diff --git a/docs/glossary/glossary.json b/docs/glossary/glossary.json index 8a762e93..bcc4791a 100644 --- a/docs/glossary/glossary.json +++ b/docs/glossary/glossary.json @@ -858,6 +858,27 @@ "context": "browser", "meaning": "playwright install の --with-deps が apt で入れるパッケージ。共有ライブラリ(libnss3 など)とフォント(fonts-liberation・fonts-ipafont-gothic・fonts-wqy-zenhei など)を含む", "source": "docs/specifications/base-image-rendering.md" + }, + { + "term": "DinD", + "context": "image-lineage", + "meaning": "コンテナの中で dockerd を起こし、そのコンテナの中だけの docker を使う形。ENABLE_DIND で有効にする。ホストの docker.sock を mount して使う形と区別する", + "source": "", + "pending_source": "issues/issue-400-requirements.md" + }, + { + "term": "展開後の大きさ", + "context": "image-lineage", + "meaning": "建てたイメージから作ったコンテナで du -sbx / を測ったバイト数。docker images の圧縮後の大きさとは違う", + "source": "", + "pending_source": "issues/issue-400-requirements.md" + }, + { + "term": "文書の除外", + "context": "image-lineage", + "meaning": "dpkg の path-exclude の設定で、apt が入れるパッケージから文書などの置き場を展開しないこと。base を FROM で継ぐ派生イメージにも効く", + "source": "", + "pending_source": "issues/issue-400-requirements.md" } ] } diff --git a/issues/issue-400-requirements.md b/issues/issue-400-requirements.md new file mode 100644 index 00000000..499ab6ec --- /dev/null +++ b/issues/issue-400-requirements.md @@ -0,0 +1,163 @@ +# #400: base から使う者が見当たらない中身を外す(dockerd・aws-cdk-lib・root の uv・apt の片付けの漏れ) + +正は課題の本文(#400)で、この文書はその写しである。`spec-copy.py write` で作り直す。手で直さない。 + +## 依頼(原文) + +> base イメージから、使う者が見当たらない中身と片付けの漏れを外す。base の削減の段階 1(段階 2・3 は別の課題)。利用者は 2026-10-03 にこの削減を承認した(MVV の P1)。 +> +> | 中身 | 場所 | 大きさ | 外す根拠 | +> | --- | --- | --- | --- | +> | `docker-ce` と `containerd.io`(dockerd と containerd) | `containers/base/Dockerfile:71` | 106+81MB | DinD でだけ使う。`ENABLE_DIND` を設定している箇所はリポジトリとプラグインに見当たらない(`grep -rn ENABLE_DIND`)。プロジェクトはどれもホストの docker.sock を mount する。CLI・buildx・compose は残す | +> | グローバルの `aws-cdk-lib` | `Dockerfile:159` | 181MB | Node はグローバルのモジュールを `require` で探さず、CDK のアプリは自分の package.json に持つ。CLI の `aws-cdk` は残す | +> | root の uv | `Dockerfile:156` | 40MB | ubuntu の uv(`Dockerfile:211`)と重複し、root で uv を使う処理が見当たらない | +> | `/var/lib/apt/lists` | `Dockerfile:235-245` | 42MB | `playwright install --with-deps` の `apt-get update` が残し、片付けが消していない | +> | `/usr/share/doc`・`man`・`/usr/include/node` など | apt の層 | 約 75MB | 実行時に読まない。dpkg の path-exclude で入れない | +> +> 決めること: +> - DinD の扱い: `containers/base/dind` と entrypoint の `ENABLE_DIND` の分岐を消すか、dockerd を入れたうえで使う派生へ移すか +> - path-exclude で外す置き場の範囲(copyright は残す) +> +> 受け入れ条件(起票時): +> 1. 建てた base(arm64・amd64)に上の中身が無い。docker CLI・`docker buildx`・`docker compose`・`aws-cdk`・ubuntu の uv は動く +> 2. 展開後の大きさが arm64 で 450MB 以上減る(`du -sbx /` の前後で測り、PR に記録する) +> 3. lfm が建ち、`tests/containers/` が通る(lfm は自分で docker-ce を入れるため影響しない見込み) +> 4. DinD を廃止するなら、利用者向けの文書と CHANGELOG に書く +> +> 由来: スプリント m7b の振り返りの後、利用者が「base が機能盛りすぎで肥大化している」として削減のプランを求めた(2026-10-03)。 + +## 目的 + +- base を建てる時間・取得する量・ディスクの消費を、誰も使っていない中身の分だけ減らす(MVV の Value 1「base を重くしすぎず、重い道具は派生イメージに置く」) +- 利用者がコンテナの中で使う道具(docker CLI・buildx・compose・`cdk`・uv)は、削減の前と同じに使える + +## 調べて分かったこと(2026-10-03) + +| 事実 | 出所 | +| --- | --- | +| lfm は base を `FROM` で継がず、`/entrypoint.sh` と `/usr/local/bin/dind` を base のイメージから `COPY --from` で取り込む。lfm は自分で `docker-ce`・`containerd.io` を入れ、`/etc/docker/daemon.json` に NVIDIA の runtime を書く(DinD を前提にした作り) | `containers/lfm/Dockerfile:55-60`・`:169-173`・`:175-200` | +| entrypoint の DinD の分岐は `ENABLE_DIND` が `true` / `1` のときだけ動き、最初に `/var/run/docker.sock` を消してから `dind dockerd` を起こし、`docker info` を最大 30 秒待つ | `containers/base/entrypoint.sh:862-` | +| `ENABLE_DIND` を設定している compose・env は、このリポジトリと手元のプラグイン(`repos/` の下)に見当たらない。利用者向けの文書(`docs/`・`README`・`CHANGELOG.md`)にも DinD の案内は無い | `grep -rn "ENABLE_DIND\|DinD" docs README* CHANGELOG.md lib` と `grep -rln "ENABLE_DIND\|dockerd" repos/ projects/`(当たりはプラグインの 1 つ(proj-a)の compose の注記だけで、ホストの dockerd を指す) | +| base を `FROM` で継ぐ派生イメージは bi-tools・general・go・latex・php・php85・trygroup。dpkg の設定(`/etc/dpkg/dpkg.cfg.d/`)は継がれ、latex・php・php85 は自分で `apt-get install` する | `containers/*/Dockerfile` | +| 派生イメージに root で uv を使う手順は無い(bi-tools の `uv tool install` は `USER ubuntu` の下) | `containers/bi-tools/Dockerfile:29-47` | +| `PATH` の `/root/.local/bin` は、lfm の設定の取り込みの試験が「lfm へ届けない要素」として名前で除外している | `tests/containers/test_lfm_base_settings.py:40`・`docs/specifications/lfm-base-settings.md:225` | +| CI はイメージを建てない。イメージの確かめは手元で行う | `.github/workflows/ci.yml` | + +## 前提 + +- 前提 1(DinD の扱い): DinD は廃止しない。base から dockerd と containerd を外し、DinD を使える派生は lfm だけにする。lfm が取り込む `dind` と entrypoint の `ENABLE_DIND` の分岐は lfm で今と同じに動かす(置き場を base に残すか lfm へ移すかは設計で決める)。根拠: lfm は自分で dockerd を入れ NVIDIA の runtime を DinD 向けに設定しており、分岐を消すと lfm の機能が落ちる。起票時の選択肢「消す」「使う派生へ移す」のうち、退行の無い後者を採る +- 前提 2: base とその派生で `ENABLE_DIND=true` を設定している利用者はいない(上の調べ)。設定していた利用者は、base の建て直しの後に DinD が起きなくなる。この利用者へは CHANGELOG と entrypoint の知らせで伝え、lfm を使うよう案内する +- 前提 3: root で uv を使う利用者・処理は無い。base の root の uv を外した後、`sudo uv` は「コマンドが無い」で失敗してよい +- 前提 4: グローバルの `aws-cdk-lib` を `require` する利用者は無い。CDK のアプリは自分の `package.json` に `aws-cdk-lib` を持ち、`cdk synth` はそれを使う +- 前提 5: dpkg の除外設定は base を `FROM` で継ぐ派生イメージにも効き、派生が後から apt で入れるパッケージの文書も入らなくてよい(copyright は残る)。lfm は `/etc/dpkg` を取り込まないため対象外 +- 前提 6: `/usr/include/node` を外すと、npm のネイティブアドオンのビルドでは node-gyp がヘッダを取得する(ネットワークが要る)。これを許す +- 前提 7: amd64 の確かめは、amd64 の Docker が動く端末(WSL2 の端末など)か、`docker buildx build --platform linux/amd64` で行う。どちらで行ったかを PR に書く +- 前提 8: 大きさは、建てた base から作ったコンテナで `du -sbx /` を測った値で比べる。前は main の Dockerfile で建てた base、後はこの変更の Dockerfile で建てた base とし、同じ端末・同じ日に建てる(apt と npm の取得する版の差を小さくする) + +## 対象範囲 + +含む: +- base の Dockerfile から `docker-ce`・`containerd.io`・グローバルの `aws-cdk-lib`・root の uv を外す +- base の最後の利用者の層で残る `/var/lib/apt/lists` を消す +- dpkg の除外設定で、`/usr/share/doc`(copyright を除く)・`/usr/share/man` などの文書と `/usr/include/node` を入れない +- base に dockerd が無いときの entrypoint の `ENABLE_DIND` の扱い +- lfm の DinD を今と同じに動かすための、`dind` と分岐の置き場の調整 +- 外した中身に触れる試験(`tests/containers/`)と仕様(`docs/specifications/`)の追従 +- `CHANGELOG.md` の `[Unreleased]` への記入 + +含まない: +- 段階 2・3 の削減(重い道具を派生イメージへ移す・版の固定の見直し)。別の課題 +- lfm の中身の削減(lfm が自分で入れる `docker-ce` などは触らない) +- base の他の道具の追加・版の変更 +- イメージを建てる CI の追加 +- 利用者の環境で `devbase up` を実行して確かめること(P3。リリース後テストで利用者が行う) + +## ドメインイベント + +| # | イベント | 引き金 | 失敗したとき | 順序の前提 | +| --- | --- | --- | --- | --- | +| E1 | 変更前の base を建て、展開後の大きさを測った | 実装の着手 | 建たなければ main の不具合として別に起票し、測りを止める | — | +| E2 | 変更後の base を arm64 で建てた | Dockerfile の変更 | 建たなければ変更を直す | E1 | +| E3 | 変更後の base を amd64 で建てた | E2 の成功 | 建たなければ変更を直す(アーキの差は `case` の分岐で起きやすい) | E2 | +| E4 | 建てた base の中身を確かめた(外した物が無く、残す道具が動く) | E2・E3 の成功 | 残す道具が動かなければ変更を直す | E2・E3 | +| E5 | 展開後の大きさを測り、減った量を PR に記録した | E4 の成功 | 450MB に届かなければ、届かない理由と内訳を PR に書いて人へ戻す | E1・E4 | +| E6 | 変更後の base から lfm と、`FROM` で継ぐ派生イメージを建てた | E2 の成功 | `COPY --from` の取り込み元が消えて建たなければ、取り込みの置き場を直す | E2 | +| E7 | lfm で `ENABLE_DIND=true` のコンテナを起こし、DinD の dockerd が応答した | E6 の成功 | 応答しなければ `dind` か分岐の置き場の調整を直す | E6 | +| E8 | base(またはその派生)で `ENABLE_DIND=true` のコンテナを起こし、entrypoint が dockerd の無いことを知らせて起動を続けた | E2 の成功 | 起動が止まる・30 秒待つ・ホストの docker.sock が消えるなら分岐を直す | E2 | +| E9 | 利用者が base を建て直した | main へのマージ(配布) | 建たなければ利用者は前のイメージで動き続ける。リリース後テストで見つける | E2〜E8・マージ | + +## 用語 + +| 用語 | 意味 | +| --- | --- | +| DinD | コンテナの中で dockerd を起こし、そのコンテナの中だけの docker を使う形。`ENABLE_DIND` で有効にする。ホストの docker.sock を mount して使う形と区別する | +| 展開後の大きさ | 建てたイメージから作ったコンテナで `du -sbx /` を測ったバイト数。`docker images` の圧縮後の大きさとは違う | +| 文書の除外 | dpkg の `path-exclude` の設定で、apt が入れるパッケージから文書などの置き場を展開しないこと | + +## 受け入れ条件 + +- [ ] 1. 変更後の base(arm64・amd64)で、`dockerd`・`containerd` がコマンドとして見つからない(`command -v` が失敗する) +- [ ] 2. 変更後の base(arm64・amd64)で、ubuntu の利用者として `docker --version`・`docker buildx version`・`docker compose version`・`cdk --version`・`uv --version` がどれも終了コード 0 で版を出す +- [ ] 3. 変更後の base で、`npm ls -g aws-cdk-lib` に `aws-cdk-lib` が無く、`/root/.local/bin/uv` が無い +- [ ] 4. 変更後の base で、`/var/lib/apt/lists` の下に `lock` と `partial` のほかのファイルが無い +- [ ] 5. 変更後の base で、`/usr/share/man` の下と `/usr/include/node` にファイルが無く、`/usr/share/doc` の下には `copyright` のほかのファイルが無い。`/usr/share/doc/<パッケージ>/copyright` は apt で入れたパッケージについて残る +- [ ] 6. arm64 で、変更前の base と変更後の base の展開後の大きさの差が 450MB(450,000,000 バイト)以上ある。前後の値と差を PR に記録する +- [ ] 7. 変更後の base から lfm が建ち、lfm に `dockerd` と `/usr/local/bin/dind` があり、`ENABLE_DIND=true` で起こした lfm のコンテナの中で `docker info` が DinD の dockerd から応答する +- [ ] 8. 変更後の base から、`FROM devbase-base:latest` で継ぐ派生イメージ(bi-tools・general・go・latex・php・php85・trygroup)が建つ +- [ ] 9. dockerd の無いイメージで `ENABLE_DIND=true` を設定して起こすと、entrypoint は dockerd が無いことを 1 行で出して DinD の手順を飛ばし、起動を続ける。`/var/run/docker.sock` を消さず、`docker info` を待たない +- [ ] 10. `ENABLE_DIND` を設定しない base のコンテナの起動は、変更の前と同じ順で同じ用意を行う(entrypoint の既存の試験が通る) +- [ ] 11. base の Dockerfile が 1〜5 を満たす形であることを、Docker を起こさない試験(`tests/containers/` の Dockerfile を読む試験)が固定する。外した物を Dockerfile へ戻すと、その試験が名前を挙げて落ちる +- [ ] 12. `env -u DEVBASE_ROOT uv run --locked pytest tests/ -q` が通る +- [ ] 13. `CHANGELOG.md` の `[Unreleased]` に、base から dockerd・containerd・グローバルの `aws-cdk-lib`・root の uv・文書を外したことと、DinD は lfm で使えることを書く +- [ ] 14. base の Dockerfile の差分は「対象範囲」の含むに挙げた物を外す変更だけで、ほかの道具の追加・削除・版の変更を含まない + +## 非機能の条件 + +| 大項目 | 条件 | +| --- | --- | +| 性能・拡張性 | arm64 で展開後の大きさが 450MB 以上減る(受け入れ条件 6) | +| 移行性 | 利用者は base を建て直すだけで移る。ボリューム・設定・機密は触らない。戻すときは前の Dockerfile で建て直す | +| システム環境 | arm64 と amd64 の両方で建ち、受け入れ条件 1〜5 を満たす | + +## 影響 + +| 対象 | 影響 | +| --- | --- | +| 公開インタフェース | devbase の CLI は変わらない。base のイメージから `dockerd`・`containerd`・グローバルの `aws-cdk-lib`・root の uv・文書が消える。base とその派生での `ENABLE_DIND=true` は DinD を起こさなくなる(lfm は変わらない) | +| データ | 変わらない | +| 既存の振る舞い | base の entrypoint の `ENABLE_DIND` の分岐(dockerd が無いときの扱い)。派生イメージで apt が入れるパッケージの文書が入らなくなる | + +## 検証手段 + +| 項目 | 手段 | +| --- | --- | +| 起動 | `devbase build` で base と lfm・派生を建てる(建て方は設計で決める) | +| テスト | `env -u DEVBASE_ROOT uv run --locked pytest tests/ -q` | +| 静的解析・型検査 | `uvx ruff check --select=E9,F63,F7,F82 lib`・`python3 .github/scripts/proper_term_check.py`・base のシェルスクリプトの ShellCheck(開発参加ガイドの「CI が実行するもの」) | +| 手動確認(マージ前) | arm64 で建てた base と lfm で受け入れ条件 1〜7・9 を確かめ、出力と大きさを PR に記録する。amd64 で建てた base で受け入れ条件 1〜5 を確かめ、どの端末・どの方法で建てたかを PR に記録する | +| 手動確認 | 利用者が自分の環境で base を建て直し、普段のプロジェクトで docker・`cdk`・uv が使えることを確かめる(リリース後テスト。P3 のため利用者が行う) | + +## 前提とする取り決め + +| 項目 | 参照先 / 決めたこと | +| --- | --- | +| プロジェクト構造 | `AGENTS.md` の「このリポジトリ」。イメージの定義は `containers/`、試験は `tests/containers/`、確定仕様は `docs/specifications/` | +| コーディング規約 | `AGENTS.md` の「書き方」と開発参加ガイド。シェルは ShellCheck を通す | +| テスト戦略 | Dockerfile の中身は Docker を起こさない試験で固定し(既存の `test_base_dockerfile_*.py` と同じ形)、entrypoint の分岐は既存の entrypoint の試験の形で確かめる。イメージを建てて確かめる条件は手動確認(マージ前)で PR に記録する | + +## 境界 + +| 区分 | 内容 | +| --- | --- | +| 常に行う | 全体のテスト・lint・固有の語の検査を push の前に打つ。base を建てる前に `docker system df` で空きを見て、作業用のタグは記録の後に消す(`AGENTS.md` の落とし穴) | +| 確認してから行う | 対象範囲の外の道具を base から外す・足す・版を変える(P1) | +| 行わない | 利用者の環境で `devbase up` を実行する(P3)。タグ・Release を作る(P2)。lfm の中身を削る。プラグインのリポジトリの compose を直す | + +## 未決 + +| 項目 | 誰が決めるか | 期限 | +| --- | --- | --- | +| `dind` と entrypoint の `ENABLE_DIND` の分岐の置き場(base に残して lfm が取り込み続けるか、lfm へ移すか) | 設計(`design`) | 設計 PR | +| dpkg の除外設定で外す置き場の一覧(`/usr/share/doc`・`man`・`info`・`locale`・`/usr/include/node` のどこまでか)と、除外設定を置く位置(最初の `apt-get install` より前) | 設計(`design`) | 設計 PR | +| 外した後の `PATH` の `/root/.local/bin` を残すか消すか(lfm の設定の取り込みの試験の除外表に影響する) | 設計(`design`) | 設計 PR | +| amd64 を建てる端末と方法(前提 7) | 実装の担当 | 手動確認(マージ前) | From 7cebd55cf5f1c72c789ea83ba3fca7c468b71652 Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Sat, 3 Oct 2026 10:32:03 +0900 Subject: [PATCH 2/5] =?UTF-8?q?docs:=20base=20=E3=81=AE=E5=89=8A=E6=B8=9B?= =?UTF-8?q?=E3=81=AE=E6=AE=B5=E9=9A=8E=201=20=E3=81=AE=E8=A8=AD=E8=A8=88?= =?UTF-8?q?=E3=82=92=E6=9B=B8=E3=81=8D=E3=80=81DinD=20=E3=82=92=E5=BB=83?= =?UTF-8?q?=E6=AD=A2=E3=81=99=E3=82=8B=E5=89=8D=E6=8F=90=E3=81=B8=E6=94=B9?= =?UTF-8?q?=E3=82=81=E3=82=8B=EF=BC=88#400=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ENABLE_DIND を設定する者が 0 件で、DinD を前提にした lfm も #403 で廃止が決まったため、要求の前提 1 を 「lfm に残す」から「廃止する」へ改め、課題の本文と写しを揃えた。設計は文書の除外を Ubuntu の excludes の後に 読まれる別のファイルで置く形と、#401・#402・#403 との実装の順と Dockerfile の行の持ち主を決める。 用語集の DinD と文書の除外の意味を直した。 Co-Authored-By: Claude Opus 5.5 --- docs/glossary.md | 4 +- docs/glossary/glossary.json | 4 +- issues/issue-400-design.md | 399 +++++++++++++++++++++++++++++++ issues/issue-400-requirements.md | 41 ++-- 4 files changed, 427 insertions(+), 21 deletions(-) create mode 100644 issues/issue-400-design.md diff --git a/docs/glossary.md b/docs/glossary.md index 9cf01ce7..ac35ac0b 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -181,9 +181,9 @@ base の設定が派生イメージと lfm へ届く道筋(containers/*/Docker | 取り込み | — | lfm の Dockerfile が COPY --from=devbase-base:latest で base のイメージからファイルやディレクトリを同じパスへ持ち込むこと | — | — | `docs/specifications/lfm-base-settings.md` | | 到達の検査 | — | base の Dockerfile から base の設定を集め、それぞれが lfm へ届くかを Docker を起動せずに判定するテスト(tests/containers/test_lfm_base_settings.py) | — | — | `docs/specifications/lfm-base-settings.md` | | 除外表 | — | 到達の検査が、lfm へ届かなくてよいとする base の項目と、その理由の一覧 | — | — | `docs/specifications/lfm-base-settings.md` | -| DinD | — | コンテナの中で dockerd を起こし、そのコンテナの中だけの docker を使う形。ENABLE_DIND で有効にする。ホストの docker.sock を mount して使う形と区別する | — | — | — | +| DinD | — | コンテナの中で dockerd を起こし、そのコンテナの中だけの docker を使う形。#400 で廃止し、ENABLE_DIND は知らせを 1 行出すだけになった。ホストの docker.sock を mount して使う形と区別する | — | — | — | | 展開後の大きさ | — | 建てたイメージから作ったコンテナで du -sbx / を測ったバイト数。docker images の圧縮後の大きさとは違う | — | — | — | -| 文書の除外 | — | dpkg の path-exclude の設定で、apt が入れるパッケージから文書などの置き場を展開しないこと。base を FROM で継ぐ派生イメージにも効く | — | — | — | +| 文書の除外 | — | dpkg の path-exclude の設定で、apt が入れるパッケージから文書などの置き場を展開しないこと。base は Ubuntu の excludes に加え、changelog・info・/usr/include/node を外す(copyright は残す)。base を FROM で継ぐ派生イメージにも効く | — | — | — | ## コンテナの起動(`container-start`) diff --git a/docs/glossary/glossary.json b/docs/glossary/glossary.json index bcc4791a..dd9595d0 100644 --- a/docs/glossary/glossary.json +++ b/docs/glossary/glossary.json @@ -862,7 +862,7 @@ { "term": "DinD", "context": "image-lineage", - "meaning": "コンテナの中で dockerd を起こし、そのコンテナの中だけの docker を使う形。ENABLE_DIND で有効にする。ホストの docker.sock を mount して使う形と区別する", + "meaning": "コンテナの中で dockerd を起こし、そのコンテナの中だけの docker を使う形。#400 で廃止し、ENABLE_DIND は知らせを 1 行出すだけになった。ホストの docker.sock を mount して使う形と区別する", "source": "", "pending_source": "issues/issue-400-requirements.md" }, @@ -876,7 +876,7 @@ { "term": "文書の除外", "context": "image-lineage", - "meaning": "dpkg の path-exclude の設定で、apt が入れるパッケージから文書などの置き場を展開しないこと。base を FROM で継ぐ派生イメージにも効く", + "meaning": "dpkg の path-exclude の設定で、apt が入れるパッケージから文書などの置き場を展開しないこと。base は Ubuntu の excludes に加え、changelog・info・/usr/include/node を外す(copyright は残す)。base を FROM で継ぐ派生イメージにも効く", "source": "", "pending_source": "issues/issue-400-requirements.md" } diff --git a/issues/issue-400-design.md b/issues/issue-400-design.md new file mode 100644 index 00000000..cb397ceb --- /dev/null +++ b/issues/issue-400-design.md @@ -0,0 +1,399 @@ +# base イメージ: 誰も使わない dockerd・aws-cdk-lib・root の uv・node のヘッダと片付けの漏れで展開後の大きさが約 0.5GB 余分にある → 外して arm64 で 450MB 以上小さくし、使う者のいない DinD を廃止する(#400) + +## 目的 + +- **何が壊れているか**: base に、使う者が見当たらない dockerd・containerd・グローバルの `aws-cdk-lib`・root の uv・node のヘッダと、片付けの漏れた apt の一覧が入っている。合わせて約 525MB ある +- **誰が困るか**: base とその派生を建てる・取得する・置くすべての利用者。建てる時間とディスクを、誰も使わない中身の分だけ払っている +- **直すと何が成り立つか**: base の展開後の大きさが arm64 で 450MB 以上減る。docker CLI・buildx・compose・`cdk`・uv は今と同じに使える。`ENABLE_DIND` は廃止を 1 行で知らせて起動を続ける + +## 適用範囲 + +- **働く範囲**: このリポジトリの `containers/base`(とそれを `FROM` で継ぐ派生 7 つ)と、base から取り込む `containers/lfm`。利用者が base を建て直した時点で届く +- **プロジェクトごとに違うもの**: 無し(イメージの中身だけを変え、プロジェクトの設定・引数を読まない) +- **当たるモード**: `standard` + +## あるべき姿の根拠 + +| 根拠 | 種類 | 何を示すか | +| --- | --- | --- | +| `docker run --rm --entrypoint bash devbase-base:latest` で測った値(2026-10-03・arm64): `/usr/include/node` 67MB・`/usr/share/doc` 8.0MB・`/usr/share/info` 940KB・`/var/lib/apt/lists` 42MB・グローバルの `aws-cdk-lib` 181MB | 実測 | 外す中身の大きさ。docker-ce 106MB・containerd 81MB・root の uv 40MB は課題の本文の実測 | +| 同じコンテナの `/etc/dpkg/dpkg.cfg.d/excludes` が既に `man`・翻訳の `.mo`・`doc`(copyright と changelog を除く)を外している。`/usr/share/doc` に残るのは `changelog*` の 257 ファイルだけで、`/usr/share/man` の下のファイルは 0 | 実測 | 文書の除外で足すのは changelog・info・`/usr/include/node` の 3 つで足りる | +| `grep -rIl ENABLE_DIND` を `repos/*/`・`projects/*/` の compose.yml・env・.env にかけて 0 件。当たった compose の注記 1 件はホストの dockerd を指す | 実測 | `ENABLE_DIND` を設定する者がいない | +| #403 の本文: lfm を使うプロジェクトは無く、利用者が 2026-10-03 に lfm の廃止を決めた | 利用者の指示 | DinD を前提に作られた唯一の派生が無くなる | +| 設計の起動の指示「DinD を廃止するかは …… grep して使う者の有無で決める」 | 利用者の指示の原文 | DinD の扱いを使う者の有無で決める | + +要求と受け入れ条件は #400 の本文にある(コピーは `issues/issue-400-requirements.md`)。この文書は「どう作るか」だけを扱う。 +設計の中で要求の前提 1 を「DinD を lfm に残す」から「DinD を廃止する」へ改め、本文の「変更の記録」に残した(決定 1)。 + +## ドメインモデル + +### コンテキスト + +| コンテキスト | 何の語が 1 つの意味に決まるか | +| --- | --- | +| イメージの継承(`image-lineage`) | base の中身・文書の除外・展開後の大きさ・DinD。base が入れる物と、派生と lfm へ届く道筋 | +| コンテナの起動(`container-start`) | entrypoint が起動のたびに行う用意。`ENABLE_DIND` の読み方 | + +イメージの継承が供給者、コンテナの起動が顧客の関係(顧客 / 供給者)。entrypoint は base が入れた物だけを前提に動く。 +base が dockerd を入れなくなるため、entrypoint は dockerd を起こす手順を持たない。 + +### 集約 + +| 集約 | 持ち主(書き換えてよいもの) | 根 | エンティティ | 値オブジェクト | +| --- | --- | --- | --- | --- | +| base の中身 | `containers/base/Dockerfile` | base イメージ | apt のパッケージ・npm のグローバルのモジュール・root と ubuntu の道具 | 文書の除外の設定・片付けの対象のパス・`PATH` | +| 起動の用意 | `containers/base/entrypoint.sh` | 起動の手順 | DinD の知らせ | `ENABLE_DIND` の値 | +| lfm の取り込み | `containers/lfm/Dockerfile` | lfm イメージ | base から取り込む行 | — | + +この変更は lfm の取り込みから `dind` の 1 つを外すだけで、lfm の他の中身を書き換えない(lfm の廃止は #403)。 + +### 不変条件 + +| # | 集約 | 条件 | 破れたときの扱い | +| --- | --- | --- | --- | +| I1 | base の中身 | apt で `docker-ce`・`containerd.io` を入れず、`docker-ce-cli`・`docker-buildx-plugin`・`docker-compose-plugin` を入れる | 実装の誤り。試験がパッケージの名前を挙げて落ちる | +| I2 | base の中身 | npm のグローバルに `aws-cdk-lib` を入れず、`aws-cdk` を入れる | 同上 | +| I3 | base の中身 | uv のインストーラを呼ぶのは `USER ubuntu` の後の `RUN` だけで、`ENV PATH` に `/root/.local/bin` が無い | 同上 | +| I4 | base の中身 | apt の一覧を取得する `RUN`(`apt-get update` か `--with-deps` を含み、`/var/lib/apt` を cache mount しないもの)は、同じ `RUN` で `/var/lib/apt/lists` を消す | 同上。どの `RUN` かを挙げて落ちる | +| I5 | base の中身 | 文書の除外の設定が、最初の `RUN` より前に Ubuntu の `excludes` より後に読まれる名前で置かれ、copyright を残して changelog・info・man・`/usr/include/node` を外す | 同上 | +| I6 | base の中身 | `containers/base/dind` が無く、Dockerfile は `/usr/local/bin/dind` を置かない | 同上 | +| I7 | 起動の用意 | `ENABLE_DIND` が `true` か `1` のとき、DinD の廃止を 1 行出して起動を続ける。dockerd を起こさず、`/var/run/docker.sock` を消さず、`docker info` を待たない | 実装の誤り。entrypoint の試験で落とす | +| I8 | 起動の用意 | `ENABLE_DIND` が無い・`true` と `1` 以外のとき、何も出さず、起動の手順と順序は変わらない | 同上 | +| I9 | lfm の取り込み | lfm は base から `/usr/local/bin/dind` を取り込まない | 実装の誤り。lfm の取り込みの試験で落とす | + +### ドメインイベント + +| # | イベント | 発生元 | 受け手 | +| --- | --- | --- | --- | +| E1 | 変更前の base を建て、展開後の大きさを測った | 実装の担当(main の Dockerfile) | E5 の比べる元 | +| E2 | 変更後の base を arm64 で建てた | 実装の担当(この変更の Dockerfile) | E3・E4・E6・E8 | +| E3 | 変更後の base を amd64 で建てた | 実装の担当 | E4 | +| E4 | 建てた base の中身を確かめた | 実装の担当 | PR の記録 | +| E5 | 展開後の大きさを測り、減った量を PR に記録した | 実装の担当 | PR の記録・承認する人 | +| E6 | 変更後の base から lfm と派生イメージを建てた | 実装の担当 | E7・PR の記録 | +| E7 | lfm に `/usr/local/bin/dind` が無いことを確かめた | 実装の担当 | PR の記録 | +| E8 | base で `ENABLE_DIND=true` のコンテナを起こし、廃止の知らせが出て起動が続いた | entrypoint | PR の記録 | +| E9 | 利用者が base を建て直した | 利用者(main へのマージの後) | リリース後テスト | + +### 用語 + +| 用語 | 意味 | 用語集への反映 | +| --- | --- | --- | +| DinD | コンテナの中で dockerd を起こし、そのコンテナの中だけの docker を使う形。#400 で廃止し、`ENABLE_DIND` は知らせを 1 行出すだけになった。ホストの docker.sock を mount して使う形と区別する | 意味の変更(`image-lineage`) | +| 文書の除外 | dpkg の `path-exclude` の設定で、apt が入れるパッケージから文書などの置き場を展開しないこと。base は Ubuntu の `excludes` に加え、changelog・info・`/usr/include/node` を外す(copyright は残す)。base を `FROM` で継ぐ派生イメージにも効く | 意味の変更(`image-lineage`) | +| 展開後の大きさ | 建てたイメージから作ったコンテナで `du -sbx /` を測ったバイト数 | 既存(意味は変えない) | + +## 機能一覧 + +| # | 機能 | 誰が使うか | +| --- | --- | --- | +| F1 | base を建てると、dockerd・containerd・グローバルの `aws-cdk-lib`・root の uv が入らない | base と派生を建てる利用者 | +| F2 | base と派生で、apt が入れるパッケージの changelog・info・man・node のヘッダが展開されない | 同上 | +| F3 | base の最後の利用者の層に apt の一覧が残らない | 同上 | +| F4 | docker CLI・buildx・compose・`cdk`・ubuntu の uv が今と同じに使える | コンテナの中で作業する利用者 | +| F5 | `ENABLE_DIND` を設定したままの利用者に、DinD の廃止を 1 行で知らせ、起動は止めない | `ENABLE_DIND` を設定していた利用者 | +| F6 | lfm が base から `dind` を取り込まずに建つ | lfm を建てる利用者(#403 まで) | + +## 構成要素 + +型(クラス)は持たない。Dockerfile の命令と、entrypoint のシェル関数だけで構成する。 + +| 要素 | 責務 | 変更 | +| --- | --- | --- | +| 文書の除外の設定(`containers/base/dpkg-excludes`、新規) | `/etc/dpkg/dpkg.cfg.d/excludes-devbase` として置かれ、Ubuntu の `excludes` の後に読まれて changelog・info・man・`/usr/include/node` を外し、copyright を残す(決定 4) | 作る | +| base の Dockerfile の apt の層(最初の `RUN`) | 文書の除外の設定を `COPY` で先に置き、`docker-ce`・`containerd.io` を一覧から外す。`FROM` の層に既にある changelog・info を同じ `RUN` で消す | 変える | +| base の Dockerfile の root の道具の層(2 つ目の大きな `RUN`) | root の uv のインストーラの呼び出しと、npm の `aws-cdk-lib` を外す | 変える | +| base の Dockerfile の `ENV PATH` | `/root/.local/bin` を外す(決定 6) | 変える | +| base の Dockerfile の利用者の層 | 片付けに `/var/lib/apt/lists/*` を足す(決定 7) | 変える | +| base の Dockerfile の最後の `COPY` | `dind` の `COPY` を外し、`entrypoint.sh` だけを置く | 変える | +| `containers/base/dind` | — | 消す | +| entrypoint の DinD の知らせ(`devbase_notice_dind_removed`、新規) | `ENABLE_DIND` が `true` か `1` なら廃止を 1 行出して 0 で返る。それ以外は何も出さずに 0 で返る。`DEVBASE_ENTRYPOINT_LIB_ONLY` で source した試験から呼べる(決定 2) | 作る | +| entrypoint の本体の手順 5 | dockerd を起こす分岐を消し、DinD の知らせを呼ぶ 1 行にする。手順 4 と AI の設定の間という位置は変えない | 変える | +| lfm の Dockerfile の取り込み | `/usr/local/bin/dind` の `COPY --from` を外し、`chmod` を `entrypoint.sh` だけにする(決定 3) | 変える | +| base の形の試験(`tests/containers/test_base_dockerfile_slim.py`、新規) | I1〜I6 を Docker を起こさずに固定する | 作る | +| DinD の知らせの試験(`tests/containers/test_entrypoint_dind_removed.py`、新規) | I7・I8 を固定する | 作る | +| lfm の取り込みの試験(`tests/containers/test_lfm_base_settings.py`) | 除外表から `PATH /root/.local/bin` の行を消し、I9 の試験を足す | 変える | +| base のシェルスクリプトの数え上げ(`tests/containers/test_base_shellcheck_ci.py`・`.github/workflows/ci.yml`・`docs/developer/contributing.md`) | ShellCheck の対象の並びから `dind` を外す | 変える | +| 確定仕様(`docs/specifications/lfm-base-settings.md`・`base-image-shellcheck.md`・`ci-checks.md`) | `dind` の取り込み・`/root/.local/bin` の除外・2 回目の apt の一覧・`dind` の ShellCheck・`SC2009` の抑止の記述を今の形へ直す | 変える | +| 用語集(`docs/glossary/glossary.json`) | DinD・文書の除外の意味を直し、`glossary.py render` で `docs/glossary.md` を作り直す | 変える | +| `CHANGELOG.md` の `[Unreleased]` | 外した中身と、DinD の廃止(破壊的変更・ホストの docker.sock を使う)を書く | 変える | + +```mermaid +graph TD + subgraph base["containers/base"] + X[文書の除外の設定] --> A[apt の層] + A --> R[root の道具の層] + R --> P[ENV PATH] + P --> U[利用者の層] + U --> E[entrypoint の COPY] + N[DinD の知らせ] -.属する.-> E + end + subgraph 派生["FROM で継ぐ派生 7 つ"] + D[自分の apt-get install] + end + subgraph lfm["containers/lfm"] + L[base からの取り込み] + end + subgraph 試験["tests/containers"] + T1[base の形の試験] + T2[DinD の知らせの試験] + T3[lfm の取り込みの試験] + end + X -->|dpkg の設定を継ぐ| D + E -->|entrypoint.sh だけ| L + T1 -.読む.-> base + T2 -.source.-> N + T3 -.読む.-> L +``` + +### 置き場所 + +```text +containers/ +├── base/ +│ ├── Dockerfile 変える +│ ├── dpkg-excludes 新規 +│ ├── dind 消す +│ └── entrypoint.sh 変える +└── lfm/ + └── Dockerfile 変える(dind の取り込みの 2 行) +tests/containers/ +├── test_base_dockerfile_slim.py 新規 +├── test_entrypoint_dind_removed.py 新規 +├── test_lfm_base_settings.py 変える +└── test_base_shellcheck_ci.py 変える +``` + +### 同じスプリントの課題との境目 + +#401・#402・#403 は base の Dockerfile の同じ層を触る。行ごとに持ち主を 1 つに決め、他の課題の行には触れない(決定 8)。 +行番号は main の `9f3e5c5` の `containers/base/Dockerfile` で数えた。 + +| 場所(行) | 中身 | 持ち主 | +| --- | --- | --- | +| 最初の `RUN` の前(新しい `COPY`) | 文書の除外の設定 | #400 | +| 22 | `fonts-noto-cjk-extra` | #402 | +| 23〜25 の後(最初の apt の一覧) | `fonts-liberation` などの明示 | #402 | +| 37〜43 | Docker の apt の取得元 | 変えない(CLI・buildx・compose に要る) | +| 44〜48 | HashiCorp の apt の取得元 | #402 | +| 56〜67 | amd64 の Chrome の取得元と `BROWSER_PKG` | #401 | +| 71 | `docker-ce`・`containerd.io` | #400(`docker-ce-cli` は残す) | +| 73 | `terraform` | #402 | +| 73 | `$BROWSER_PKG` | #401 | +| 75〜76 の後 | `FROM` の層の changelog・info の削除 | #400 | +| 84〜89・111〜113・247〜251・259 | lfm を前提にした注記と `NPM_GID` | #403 | +| 155〜156 | root の uv | #400 | +| 159 | `aws-cdk-lib` | #400 | +| 177 | `/root/.local/bin` | #400 | +| 234〜235 | Playwright の Chromium と `--with-deps` | #402 | +| 236〜245 | 片付け(`/var/lib/apt/lists/*` を足す) | #400。注記の `--with-deps` の語は #402 | +| 304〜308 | `fc-cache` の注記 | #402 | +| 310〜312 | `dind` の `COPY` | #400 | + +Dockerfile の外で重なるもの: + +| 場所 | 重なり | 扱い | +| --- | --- | --- | +| `docs/specifications/base-image-shellcheck.md` の 2 回目の apt の一覧の行 | #400(`docker-ce` → `docker-ce-cli`)・#401(Chrome)・#402(`terraform`) | 後から入る側が main を取り込み、前の課題の直しを残して自分の語を直す | +| `tests/containers/test_base_dockerfile_playwright.py` | #401・#402 | #400 は触らない。#400 の試験は新しいファイルに置く | +| `tests/containers/test_lfm_base_settings.py`・`containers/lfm/` | #400(除外表の 1 行・I9・取り込みの 2 行)・#403(ファイルごと消す) | #403 が先にマージされたら、#400 は lfm の変更をすべて落とし、受け入れ条件 7 は対象が無いと PR に書く | +| 新しい base の形の試験が使う Dockerfile の読み方の部品(今は `test_lfm_base_settings.py` の `Instruction` / `parse`) | #400(import する)・#403(部品を共通の置き場へ移す) | #403 が部品を移すとき、`test_base_dockerfile_playwright.py` と同じく #400 の試験の import も直す | +| `CHANGELOG.md`・`docs/glossary/glossary.json` | 4 つすべて | 両側の記入を残して解く。`docs/glossary.md` は `glossary.py render` で作り直す | + +## 処理の流れ + +### 実装の順 + +```mermaid +graph LR + A["#400 段階 1
使う者のいない中身"] --> B["#401 段階 2
amd64 の Chrome"] + B --> C["#402 段階 3
ブラウザ・フォント・terraform"] + D["#403 lfm の廃止"] -.どの位置でもよい.-> A +``` + +- **#400 → #401 → #402 の順に 1 本ずつマージする。** 後の課題は、前の課題がマージされた main を取り込んでから建てて測る。 + 大きさの比べる元は、その時点の main で建てた base である +- **#400 の 450MB は arm64 で測る。** #401 は amd64 だけを変えるため、#400 の測りに #401 は入らない +- **#403 は順に縛らない。** #400 が先なら #400 が lfm の 2 行を消し、#403 が後で lfm ごと消す。#403 が先なら #400 は lfm の変更を落とす + +### base を建てる順(変更後) + +```mermaid +graph TD + F[FROM ubuntu:26.04] --> C1["COPY dpkg-excludes
/etc/dpkg/dpkg.cfg.d/excludes-devbase"] + C1 --> R1["RUN apt の層
docker-ce-cli・buildx・compose を入れる
FROM の層の changelog・info を消す"] + R1 --> R2[RUN 利用者とグループ] + R2 --> R3["RUN root の道具
aws・gcloud・npm(aws-cdk-lib なし)
root の uv なし"] + R3 --> P["ENV PATH
/opt/google-cloud-sdk/bin を足す"] + P --> R4[RUN bao・確認] + R4 --> R5["USER ubuntu の RUN
uv・claude・agy・kiro・playwright
片付けで apt の一覧も消す"] + R5 --> R6[設定の COPY と fc-cache] + R6 --> C2[COPY entrypoint.sh] + C2 -.建てた base から.-> LF["lfm の取り込み
entrypoint.sh だけ(dind なし)"] +``` + +建てる流れと起動の流れに乗らない要素(試験・ShellCheck の対象の並び・確定仕様・用語集・`CHANGELOG.md`)は図に含めない。 + +`playwright install --with-deps` の `apt-get` も文書の除外の設定に従うため、その層でも文書は展開されない。 + +### コンテナの起動(`ENABLE_DIND` の扱い) + +```mermaid +graph TD + S[手順 4 AWS の設定] --> Q{ENABLE_DIND は true か 1 か} + Q -->|はい| M["廃止の知らせを 1 行出す
(docker.sock・dockerd・docker info に触れない)"] + Q -->|いいえ| Z[何も出さない] + M --> AI[AI の設定の symlink] + Z --> AI + AI --> RP[リポジトリの用意] --> RD[完了の印] --> X[exec] +``` + +知らせの文は 1 行で、`ENABLE_DIND` が廃止されたことと、ホストの docker.sock を使うこと(`docker` はそのまま使える)を含める。 +文言は実装で決める。 + +## 非機能の実現方式 + +| 大項目 | 要求の条件 | 実現方式 | 確かめ方 | +| --- | --- | --- | --- | +| 性能・拡張性 | arm64 で展開後の大きさが 450MB 以上減る | 下の内訳の 7 つを外す。見込みは合わせて約 525MB で、450MB に約 75MB の余裕がある | 前提 8 の形で前後の base から作ったコンテナで `du -sbx /` を測り、差と内訳を PR に記録する | +| 移行性 | 利用者は base を建て直すだけで移る。戻すときは前の Dockerfile で建て直す | 変えるのはイメージの中身と entrypoint だけで、ボリューム・設定・機密の形を変えない。`ENABLE_DIND` を残した利用者は起動が止まらず、知らせで気づく | 建て直した base で既存の entrypoint の試験が通ること・E8 の起動の出力を PR に記録する | +| システム環境 | arm64 と amd64 の両方で建ち、受け入れ条件 1〜5 を満たす | アーキの `case` を足さない。外すのはアーキに依らない行だけで、文書の除外もアーキに依らない | arm64 で建てて 1〜7・9 を、amd64 で建てて 1〜5 を確かめ、amd64 の端末と方法を PR に書く | + +見込みの内訳(arm64): + +| 中身 | 大きさ | 出所 | +| --- | --- | --- | +| `docker-ce`(dockerd) | 106MB | 課題の本文 | +| `containerd.io` | 81MB | 課題の本文 | +| グローバルの `aws-cdk-lib` | 181MB | 実測(2026-10-03) | +| root の uv | 40MB | 課題の本文 | +| `/var/lib/apt/lists` | 42MB | 実測 | +| `/usr/include/node` | 67MB | 実測 | +| `/usr/share/doc` の changelog と `/usr/share/info` | 約 9MB | 実測(8.0MB と 940KB) | +| 合計 | 約 525MB | — | + +`docker-ce` が依存で引き込んでいたパッケージ(`iptables` など)も、他に要る物が無ければ入らなくなる。この分は見込みに含めない。 + +## 決定の記録 + +### 決定 1: 使う者の有無で決めるため、DinD を廃止し、`dind` と dockerd を起こす分岐を消す + +`ENABLE_DIND` を設定する者は、リポジトリ・手元のプラグイン・手元のプロジェクトに 0 件である。DinD を前提に作られた +lfm(自分で dockerd を入れ、NVIDIA の runtime を DinD 向けに書く)は使う者が無く、#403 で廃止が決まった。DinD を +残しても動かす先が無く、`dind` と分岐は誰も通らない経路として base とすべての派生に配られ続ける。要求の前提 1 は +lfm が残る前提で書かれていたため、課題の本文を改め「変更の記録」に残した。 + +dockerd を入れた新しい派生へ DinD を移す形は採らない。移す先を使う者がいない。lfm に残す形は、lfm ごと消えるため採らない。 + +根拠: Value 1 / P1(MVV 版 1) + +### 決定 2: 設定を残した利用者が原因に気づけるよう、`ENABLE_DIND` は 1 行で知らせて起動を続ける + +分岐を消すだけだと、`ENABLE_DIND` を残した利用者は DinD が起きない理由を知る手段が無い。起動を止めると、使っていない +設定の残りのためにコンテナが使えなくなる。知らせは関数に切り出し、既存の entrypoint の試験と同じく +`DEVBASE_ENTRYPOINT_LIB_ONLY` で source して呼べるようにする。 + +`ENABLE_DIND` を黙って無視する形と、起動を止める形は採らない。前者は原因が見えず、後者は作業を止める。 + +根拠: Mission(MVV 版 1) + +### 決定 3: #403 を待たずに進めるため、lfm からは `dind` の取り込みだけを外す + +base から `dind` を消すと、lfm の `COPY --from=devbase-base:latest /usr/local/bin/dind` が取り込み元を失い、lfm が建たない。 +lfm の他の中身(自分で入れる `docker-ce`・`daemon.json`・`VOLUME /var/lib/docker`)は #403 が lfm ごと消すため触らない。 + +#403 を先にマージするよう順を縛る形は採らない。#403 は設計の前で、#400 を止める理由にならない。`dind` を base に +残して lfm の取り込みを保つ形は、使う者のいない台本を配り続けるため採らない。 + +根拠: Value 1(MVV 版 1) + +### 決定 4: 派生にも効かせて層の大きさから外すため、文書の除外を Ubuntu の `excludes` の後に読まれる別のファイルで置く + +`ubuntu:26.04` は `/etc/dpkg/dpkg.cfg.d/excludes` で man・`.mo`・doc を既に外し、copyright と changelog だけを +`path-include` で残している。dpkg は後に読んだ規則を優先するため、`excludes` より後に並ぶ名前 +(`excludes-devbase`)のファイルで doc を外し直し、copyright だけを入れ直せば changelog が外れる。同じファイルで +`/usr/share/info/*`・`/usr/share/man/*`・`/usr/include/node/*` を外す。ファイルは `containers/base/dpkg-excludes` に置き、 +最初の `RUN` の前に `COPY` する。`FROM` の層に既にある changelog と info は、最初の `RUN` の中で消す(層の大きさは +減らないが、受け入れ条件 5 の「copyright のほかのファイルが無い」を満たす)。 + +翻訳(`/usr/share/locale`)は外さない。`.mo` は Ubuntu が既に外しており、残る `locale.alias` は glibc が読む。 +Ubuntu の `excludes` を書き換える形は、Ubuntu の持ち物を混ぜるため採らない。`RUN` の中で `printf` で書く形は、 +試験がファイルとして読めないため採らない。入れた後に `rm` する形は、前の層に大きさが残るため採らない。 + +根拠: Value 1(MVV 版 1) + +### 決定 5: 試験が外した物を名前で挙げるよう、base の形の試験を新しいファイルに置く + +外した物ごとに 1 つの試験にし、Dockerfile へ戻すと名前を挙げて落ちる(受け入れ条件 11)。既存の +`test_base_dockerfile_playwright.py` などは #401・#402 が直すため、同じファイルに書くと並行する変更がぶつかる。 +Dockerfile の読み方(命令への分け方)は既存の試験の部品を使い、新しく書かない。 + +根拠: Value 1(MVV 版 1) + +### 決定 6: 空の置き場を指さないよう、`PATH` から `/root/.local/bin` を外し、lfm の除外表の行も消す + +root の uv を外すと `/root/.local/bin` に入る物が無くなる。`PATH` に残すと、lfm の除外表の行が「base で root の uv が +入る場所」という誤った理由のまま残る。除外表の試験は使われない除外を落とすため、`PATH` と除外表の行を同じ変更で消す。 + +`PATH` を残す形は、理由の無い要素を配り続けるため採らない。 + +根拠: Value 1(MVV 版 1) + +### 決定 7: #402 が Playwright を外しても壊れないよう、apt の一覧の片付けを規則で縛る + +試験は「利用者の層の片付けに `/var/lib/apt/lists` がある」ではなく、「`/var/lib/apt` を cache mount せずに apt の一覧を +取得する `RUN` は、同じ `RUN` で一覧を消す」(I4)を見る。#402 が `--with-deps` を外すと、利用者の層は一覧を取得しなく +なり、規則は当たる `RUN` が無いまま通る。片付けの 1 語が残っても害は無く、#402 が消してもよい。 + +`--with-deps` の有無に関わらず利用者の層に片付けの語を求める形は、#402 の後に意味の無い要求になるため採らない。 + +根拠: Value 1(MVV 版 1) + +### 決定 8: 並行する削減がぶつからないよう、#400 → #401 → #402 の順に 1 本ずつ入れ、Dockerfile の行の持ち主を分ける + +3 つは段階の番号の順で、外す量の小さい順でもある。#400 は arm64 の測りが #401 に依らず、#401 は amd64 だけを触り、 +#402 は Playwright と apt の一覧の両方を変える。後の課題ほど前の結果を前提にできる。`main` は strict で、続けて +マージすると後の 1 本が BEHIND になるため、1 本ずつ main を取り込み、建てて測り直してからマージする。行の持ち主は +「同じスプリントの課題との境目」の表に従う。 + +3 つを 1 本の PR にまとめる形は、測りが混ざり、どの削減が何を減らしたかを PR に記録できないため採らない。 + +根拠: Value 1 / P1(MVV 版 1) + +## テスト設計 + +| 受け入れ条件・不変条件 | どの振る舞いで縛るか | どう壊したら落ちるべきか | +| --- | --- | --- | +| I1(受け入れ条件 1・2) | base の apt の一覧に `docker-ce`・`containerd.io` が無く、`docker-ce-cli`・`docker-buildx-plugin`・`docker-compose-plugin` がある | `docker-ce` か `containerd.io` を一覧へ戻す・`docker-buildx-plugin` を消すと、そのパッケージの名前を挙げて落ちる | +| I2(受け入れ条件 2・3) | npm のグローバルの一覧に `aws-cdk-lib` が無く、`aws-cdk` がある | `aws-cdk-lib` を戻す・`aws-cdk` を消すと落ちる | +| I3(受け入れ条件 2・3) | uv のインストーラを呼ぶ `RUN` が `USER ubuntu` の後にだけあり、`ENV PATH` に `/root/.local/bin` が無い | root の `RUN` に uv のインストーラを戻す・利用者の `RUN` から消す・`PATH` に戻すと落ちる | +| I4(受け入れ条件 4) | cache mount の無い apt の一覧の取得を持つ `RUN` は、同じ `RUN` で `/var/lib/apt/lists` を消す | 利用者の層の片付けから一覧を外すと、その `RUN` を挙げて落ちる。`--with-deps` を消した Dockerfile では当たる `RUN` が無く通る | +| I5(受け入れ条件 5) | 文書の除外の設定が `excludes` より後に並ぶ名前で、最初の `RUN` より前に置かれ、doc の除外の後に copyright の取り込みがあり、changelog・info・man・`/usr/include/node` を外す | 名前を `devbase-excludes`(`excludes` より前)にする・`COPY` を最初の `RUN` の後へ動かす・copyright の取り込みを消す・`/usr/include/node` の行を消すと落ちる | +| I6(受け入れ条件 11) | `containers/base/dind` が無く、Dockerfile に `/usr/local/bin/dind` が無い | `dind` を戻す・`COPY` を戻すと落ちる | +| I7(受け入れ条件 9) | `ENABLE_DIND` が `true`・`1` のとき、DinD の知らせが 1 行だけ出て 0 で返り、`sudo`・`dockerd`・`docker`・`rm` を呼ばない | 知らせの後に `docker info` を待つ・docker.sock を消す・dockerd を起こす・0 以外で返るように壊すと落ちる | +| I8(受け入れ条件 10) | `ENABLE_DIND` が無い・`false`・空のとき、何も出さずに 0 で返る。既存の entrypoint の試験が変わらず通る | 未設定でも知らせを出すように壊すと落ちる | +| I9(受け入れ条件 7) | lfm の Dockerfile が base から `/usr/local/bin/dind` を取り込まない | lfm に取り込みの行を戻すと落ちる | +| 受け入れ条件 1〜5(建てた base) | arm64 と amd64 で建てた base で `command -v dockerd`・`command -v containerd` が失敗し、`docker --version` などの 5 つが 0 で終わり、`npm ls -g aws-cdk-lib` が空で、`/var/lib/apt/lists`・`/usr/share/man`・`/usr/include/node`・`/usr/share/doc` が条件どおりである | 手動確認(マージ前)。出力を PR に記録する | +| 受け入れ条件 6 | 前提 8 の形で前後の展開後の大きさの差が 450,000,000 バイト以上 | 手動確認。届かなければ内訳を PR に書いて人へ戻す | +| 受け入れ条件 7・8 | 変更後の base から lfm と派生 7 つが建ち、lfm に `/usr/local/bin/dind` が無い | 手動確認。建たなければ取り込みか手順を直す | +| 受け入れ条件 9(建てた base) | `ENABLE_DIND=true` で起こしたコンテナの起動の出力に知らせが 1 行あり、完了の印ができる | 手動確認。出力を PR に記録する | +| 受け入れ条件 12 | `env -u DEVBASE_ROOT uv run --locked pytest tests/ -q` が通る | ShellCheck の対象に `dind` が残る・除外表に `/root/.local/bin` が残ると、既存の試験が落ちる | +| 受け入れ条件 13 | `CHANGELOG.md` の `[Unreleased]` に、外した 5 つと DinD の廃止(破壊的変更・ホストの docker.sock を使う)がある | 実装のレビューで見る | +| 受け入れ条件 14 | base の Dockerfile の差分が、次の 6 つの変更(除外の `COPY`・apt の層・root の道具の層・`PATH`・片付け・`dind` の `COPY`)だけである | 実装のレビューで `git diff main -- containers/base/Dockerfile` を見る | + +## 設計の結果 + +| 課題 | 扱い | 取り込み先 | 触るファイル | +| --- | --- | --- | --- | +| #400 | 実装する | — | `containers/base/Dockerfile`、`containers/base/dpkg-excludes`、`containers/base/dind`、`containers/base/entrypoint.sh`、`containers/lfm/Dockerfile`、`tests/containers/`、`.github/workflows/ci.yml`、`docs/developer/contributing.md`、`docs/specifications/`、`docs/glossary/glossary.json`、`docs/glossary.md`、`CHANGELOG.md` | + +## 未確認のまま残ること + +| 項目 | 内容 | +| --- | --- | +| 大きさの見込み | docker-ce・containerd・root の uv の値は課題の本文の実測で、この設計では測り直していない。450MB に届くかは E5 で決まる。届かなければ人へ戻す | +| amd64 の確かめ方 | WSL2 の端末で建てるか `docker buildx build --platform linux/amd64` で建てるかは実装の担当が決め、PR に書く(要求の前提 7) | +| node のヘッダの無い環境 | ネイティブアドオンを入れるプロジェクトで node-gyp がヘッダを取得できるか(要求の前提 6)は、リリース後テストで利用者のプロジェクトで分かる | +| 派生の apt の文書 | latex・php・php85 が自分で入れるパッケージの文書も外れる。実行時に `/usr/share/doc` の中身を読む道具が派生にあるかは、派生を建てて使うまで分からない | +| #402 の要求との食い違い | #402 の前提 5 は amd64 の Chrome を base に残すとしているが、#401 がそれを外す。#402 の設計で前提を直す必要がある(#402 へ書き残した) | +| #403 との順 | #403 が #400 より先にマージされると、受け入れ条件 7 と I9 は対象が無くなる。そのときは PR に書いて外す | diff --git a/issues/issue-400-requirements.md b/issues/issue-400-requirements.md index 499ab6ec..6507587f 100644 --- a/issues/issue-400-requirements.md +++ b/issues/issue-400-requirements.md @@ -42,11 +42,13 @@ | 派生イメージに root で uv を使う手順は無い(bi-tools の `uv tool install` は `USER ubuntu` の下) | `containers/bi-tools/Dockerfile:29-47` | | `PATH` の `/root/.local/bin` は、lfm の設定の取り込みの試験が「lfm へ届けない要素」として名前で除外している | `tests/containers/test_lfm_base_settings.py:40`・`docs/specifications/lfm-base-settings.md:225` | | CI はイメージを建てない。イメージの確かめは手元で行う | `.github/workflows/ci.yml` | +| dockerd を自分で入れ `ENABLE_DIND` で DinD を起こせる lfm は、使うプロジェクトが無く、同じマイルストーンの #403 で廃止が決まった | #403 の本文 | +| `ENABLE_DIND` を設定している compose・env は、手元のプラグイン(`repos/*/`)と `projects/*/` に 0 件である(設計で再び確かめた) | `grep -rIl ENABLE_DIND repos/*/ projects/*/ --include=compose.yml --include=env --include=.env` | ## 前提 -- 前提 1(DinD の扱い): DinD は廃止しない。base から dockerd と containerd を外し、DinD を使える派生は lfm だけにする。lfm が取り込む `dind` と entrypoint の `ENABLE_DIND` の分岐は lfm で今と同じに動かす(置き場を base に残すか lfm へ移すかは設計で決める)。根拠: lfm は自分で dockerd を入れ NVIDIA の runtime を DinD 向けに設定しており、分岐を消すと lfm の機能が落ちる。起票時の選択肢「消す」「使う派生へ移す」のうち、退行の無い後者を採る -- 前提 2: base とその派生で `ENABLE_DIND=true` を設定している利用者はいない(上の調べ)。設定していた利用者は、base の建て直しの後に DinD が起きなくなる。この利用者へは CHANGELOG と entrypoint の知らせで伝え、lfm を使うよう案内する +- 前提 1(DinD の扱い): DinD を廃止する。base から dockerd と containerd を外し、`containers/base/dind` と entrypoint の `ENABLE_DIND` の分岐(dockerd を起こす手順)を消す。根拠: `ENABLE_DIND` を設定する者がリポジトリ・手元のプラグイン・手元のプロジェクトに無く、DinD を前提に作られた lfm は使う者が無く #403 で廃止が決まった。起票時の選択肢「消す」「使う派生へ移す」のうち、移す先を使う者がいないため前者を採る(設計で前提を改めた。「変更の記録」) +- 前提 2: base とその派生・lfm で `ENABLE_DIND=true` を設定している利用者はいない(上の調べ)。設定していた利用者は、base を建て直した後に DinD が起きなくなる。entrypoint はこの設定を見つけたら廃止を 1 行で知らせて起動を続け、CHANGELOG でホストの docker.sock を使うよう案内する - 前提 3: root で uv を使う利用者・処理は無い。base の root の uv を外した後、`sudo uv` は「コマンドが無い」で失敗してよい - 前提 4: グローバルの `aws-cdk-lib` を `require` する利用者は無い。CDK のアプリは自分の `package.json` に `aws-cdk-lib` を持ち、`cdk synth` はそれを使う - 前提 5: dpkg の除外設定は base を `FROM` で継ぐ派生イメージにも効き、派生が後から apt で入れるパッケージの文書も入らなくてよい(copyright は残る)。lfm は `/etc/dpkg` を取り込まないため対象外 @@ -60,14 +62,14 @@ - base の Dockerfile から `docker-ce`・`containerd.io`・グローバルの `aws-cdk-lib`・root の uv を外す - base の最後の利用者の層で残る `/var/lib/apt/lists` を消す - dpkg の除外設定で、`/usr/share/doc`(copyright を除く)・`/usr/share/man` などの文書と `/usr/include/node` を入れない -- base に dockerd が無いときの entrypoint の `ENABLE_DIND` の扱い -- lfm の DinD を今と同じに動かすための、`dind` と分岐の置き場の調整 +- `containers/base/dind` と entrypoint の DinD の分岐を消し、`ENABLE_DIND` を設定したときは廃止の知らせを 1 行出す +- lfm が base から `dind` を取り込む行を消す(lfm が建ち続けるための最小の変更) - 外した中身に触れる試験(`tests/containers/`)と仕様(`docs/specifications/`)の追従 - `CHANGELOG.md` の `[Unreleased]` への記入 含まない: - 段階 2・3 の削減(重い道具を派生イメージへ移す・版の固定の見直し)。別の課題 -- lfm の中身の削減(lfm が自分で入れる `docker-ce` などは触らない) +- lfm の廃止(#403)と、lfm の中身の削減(lfm が自分で入れる `docker-ce`・`daemon.json` などは触らない) - base の他の道具の追加・版の変更 - イメージを建てる CI の追加 - 利用者の環境で `devbase up` を実行して確かめること(P3。リリース後テストで利用者が行う) @@ -81,16 +83,16 @@ | E3 | 変更後の base を amd64 で建てた | E2 の成功 | 建たなければ変更を直す(アーキの差は `case` の分岐で起きやすい) | E2 | | E4 | 建てた base の中身を確かめた(外した物が無く、残す道具が動く) | E2・E3 の成功 | 残す道具が動かなければ変更を直す | E2・E3 | | E5 | 展開後の大きさを測り、減った量を PR に記録した | E4 の成功 | 450MB に届かなければ、届かない理由と内訳を PR に書いて人へ戻す | E1・E4 | -| E6 | 変更後の base から lfm と、`FROM` で継ぐ派生イメージを建てた | E2 の成功 | `COPY --from` の取り込み元が消えて建たなければ、取り込みの置き場を直す | E2 | -| E7 | lfm で `ENABLE_DIND=true` のコンテナを起こし、DinD の dockerd が応答した | E6 の成功 | 応答しなければ `dind` か分岐の置き場の調整を直す | E6 | -| E8 | base(またはその派生)で `ENABLE_DIND=true` のコンテナを起こし、entrypoint が dockerd の無いことを知らせて起動を続けた | E2 の成功 | 起動が止まる・30 秒待つ・ホストの docker.sock が消えるなら分岐を直す | E2 | +| E6 | 変更後の base から lfm と、`FROM` で継ぐ派生イメージを建てた | E2 の成功 | 建たなければ、外した物を前提にした取り込みや手順を直す | E2 | +| E7 | lfm に `/usr/local/bin/dind` が無いことを確かめた | E6 の成功 | 残っていれば lfm の取り込みの行を直す | E6 | +| E8 | base で `ENABLE_DIND=true` のコンテナを起こし、entrypoint が DinD の廃止を知らせて起動を続けた | E2 の成功 | 起動が止まる・dockerd を起こそうとする・ホストの docker.sock が消えるなら entrypoint を直す | E2 | | E9 | 利用者が base を建て直した | main へのマージ(配布) | 建たなければ利用者は前のイメージで動き続ける。リリース後テストで見つける | E2〜E8・マージ | ## 用語 | 用語 | 意味 | | --- | --- | -| DinD | コンテナの中で dockerd を起こし、そのコンテナの中だけの docker を使う形。`ENABLE_DIND` で有効にする。ホストの docker.sock を mount して使う形と区別する | +| DinD | コンテナの中で dockerd を起こし、そのコンテナの中だけの docker を使う形。`ENABLE_DIND` で有効にする。ホストの docker.sock を mount して使う形と区別する。この課題で廃止する | | 展開後の大きさ | 建てたイメージから作ったコンテナで `du -sbx /` を測ったバイト数。`docker images` の圧縮後の大きさとは違う | | 文書の除外 | dpkg の `path-exclude` の設定で、apt が入れるパッケージから文書などの置き場を展開しないこと | @@ -102,13 +104,13 @@ - [ ] 4. 変更後の base で、`/var/lib/apt/lists` の下に `lock` と `partial` のほかのファイルが無い - [ ] 5. 変更後の base で、`/usr/share/man` の下と `/usr/include/node` にファイルが無く、`/usr/share/doc` の下には `copyright` のほかのファイルが無い。`/usr/share/doc/<パッケージ>/copyright` は apt で入れたパッケージについて残る - [ ] 6. arm64 で、変更前の base と変更後の base の展開後の大きさの差が 450MB(450,000,000 バイト)以上ある。前後の値と差を PR に記録する -- [ ] 7. 変更後の base から lfm が建ち、lfm に `dockerd` と `/usr/local/bin/dind` があり、`ENABLE_DIND=true` で起こした lfm のコンテナの中で `docker info` が DinD の dockerd から応答する +- [ ] 7. 変更後の base から lfm が建ち、lfm に `/usr/local/bin/dind` が無い - [ ] 8. 変更後の base から、`FROM devbase-base:latest` で継ぐ派生イメージ(bi-tools・general・go・latex・php・php85・trygroup)が建つ -- [ ] 9. dockerd の無いイメージで `ENABLE_DIND=true` を設定して起こすと、entrypoint は dockerd が無いことを 1 行で出して DinD の手順を飛ばし、起動を続ける。`/var/run/docker.sock` を消さず、`docker info` を待たない +- [ ] 9. `ENABLE_DIND` に `true` か `1` を設定して base のコンテナを起こすと、entrypoint は DinD を廃止したことを 1 行出して起動を続ける。`/var/run/docker.sock` を消さず、dockerd を起こさず、`docker info` を待たない - [ ] 10. `ENABLE_DIND` を設定しない base のコンテナの起動は、変更の前と同じ順で同じ用意を行う(entrypoint の既存の試験が通る) -- [ ] 11. base の Dockerfile が 1〜5 を満たす形であることを、Docker を起こさない試験(`tests/containers/` の Dockerfile を読む試験)が固定する。外した物を Dockerfile へ戻すと、その試験が名前を挙げて落ちる +- [ ] 11. base の Dockerfile が 1〜5 を満たす形であり、`containers/base/dind` が無いことを、Docker を起こさない試験(`tests/containers/` の Dockerfile を読む試験)が固定する。外した物を Dockerfile へ戻すと、その試験が名前を挙げて落ちる - [ ] 12. `env -u DEVBASE_ROOT uv run --locked pytest tests/ -q` が通る -- [ ] 13. `CHANGELOG.md` の `[Unreleased]` に、base から dockerd・containerd・グローバルの `aws-cdk-lib`・root の uv・文書を外したことと、DinD は lfm で使えることを書く +- [ ] 13. `CHANGELOG.md` の `[Unreleased]` に、base から dockerd・containerd・グローバルの `aws-cdk-lib`・root の uv・文書を外したことと、DinD(`ENABLE_DIND`)を廃止したこと(破壊的変更。ホストの docker.sock を使う)を書く - [ ] 14. base の Dockerfile の差分は「対象範囲」の含むに挙げた物を外す変更だけで、ほかの道具の追加・削除・版の変更を含まない ## 非機能の条件 @@ -123,9 +125,9 @@ | 対象 | 影響 | | --- | --- | -| 公開インタフェース | devbase の CLI は変わらない。base のイメージから `dockerd`・`containerd`・グローバルの `aws-cdk-lib`・root の uv・文書が消える。base とその派生での `ENABLE_DIND=true` は DinD を起こさなくなる(lfm は変わらない) | +| 公開インタフェース | devbase の CLI は変わらない。base のイメージから `dockerd`・`containerd`・グローバルの `aws-cdk-lib`・root の uv・文書が消える。base とその派生・lfm での `ENABLE_DIND=true` は DinD を起こさなくなり、廃止の知らせを 1 行出す | | データ | 変わらない | -| 既存の振る舞い | base の entrypoint の `ENABLE_DIND` の分岐(dockerd が無いときの扱い)。派生イメージで apt が入れるパッケージの文書が入らなくなる | +| 既存の振る舞い | entrypoint の DinD の分岐が無くなる。派生イメージで apt が入れるパッケージの文書が入らなくなる | ## 検証手段 @@ -151,13 +153,18 @@ | --- | --- | | 常に行う | 全体のテスト・lint・固有の語の検査を push の前に打つ。base を建てる前に `docker system df` で空きを見て、作業用のタグは記録の後に消す(`AGENTS.md` の落とし穴) | | 確認してから行う | 対象範囲の外の道具を base から外す・足す・版を変える(P1) | -| 行わない | 利用者の環境で `devbase up` を実行する(P3)。タグ・Release を作る(P2)。lfm の中身を削る。プラグインのリポジトリの compose を直す | +| 行わない | 利用者の環境で `devbase up` を実行する(P3)。タグ・Release を作る(P2)。lfm を廃止する・lfm の中身を削る(#403)。プラグインのリポジトリの compose を直す | ## 未決 | 項目 | 誰が決めるか | 期限 | | --- | --- | --- | -| `dind` と entrypoint の `ENABLE_DIND` の分岐の置き場(base に残して lfm が取り込み続けるか、lfm へ移すか) | 設計(`design`) | 設計 PR | | dpkg の除外設定で外す置き場の一覧(`/usr/share/doc`・`man`・`info`・`locale`・`/usr/include/node` のどこまでか)と、除外設定を置く位置(最初の `apt-get install` より前) | 設計(`design`) | 設計 PR | | 外した後の `PATH` の `/root/.local/bin` を残すか消すか(lfm の設定の取り込みの試験の除外表に影響する) | 設計(`design`) | 設計 PR | | amd64 を建てる端末と方法(前提 7) | 実装の担当 | 手動確認(マージ前) | + +## 変更の記録 + +| 日 | 工程 | 変えたこと | 理由 | +| --- | --- | --- | --- | +| 2026-10-03 | 設計 | 前提 1 を「DinD を lfm に残す」から「DinD を廃止する」へ改め、前提 2・対象範囲・E6〜E8・受け入れ条件 7・9・11・13・影響・境界・未決を合わせて直した | 要求を書いた後に #403 で lfm の廃止が決まり、DinD を使える唯一の派生が無くなる。`ENABLE_DIND` を設定する者も 0 件である | From 8fb0c845f1899543d48ba73c940b8c22d631217b Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Sat, 3 Oct 2026 10:47:35 +0900 Subject: [PATCH 3/5] =?UTF-8?q?docs:=20#400=20=E3=81=AE=E8=A8=AD=E8=A8=88?= =?UTF-8?q?=E3=82=92=20#403=20=E3=81=AE=E5=BE=8C=E3=81=AB=E5=85=A5?= =?UTF-8?q?=E3=82=8C=E3=82=8B=E5=89=8D=E6=8F=90=E3=81=B8=E6=94=B9=E3=82=81?= =?UTF-8?q?=E3=80=81=E7=B5=84=E3=81=BF=E7=9B=B4=E3=81=99=EF=BC=88#400?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit lfm は #403 で #400 より先に廃止されるため、lfm への変更・試験・受け入れ条件を外す。 受け入れ条件 7 と E7 は番号を詰めずに削除と書き、決定 3・6・8 と境目の表を改める。 設計文書は document-restructuring で章立てを組み直した。 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Kh8mn2JbTzTgViRhYtZkqT --- issues/issue-400-design.md | 204 +++++++++++++++---------------- issues/issue-400-requirements.md | 31 +++-- 2 files changed, 113 insertions(+), 122 deletions(-) diff --git a/issues/issue-400-design.md b/issues/issue-400-design.md index cb397ceb..af0c437c 100644 --- a/issues/issue-400-design.md +++ b/issues/issue-400-design.md @@ -2,13 +2,13 @@ ## 目的 -- **何が壊れているか**: base に、使う者が見当たらない dockerd・containerd・グローバルの `aws-cdk-lib`・root の uv・node のヘッダと、片付けの漏れた apt の一覧が入っている。合わせて約 525MB ある +- **何が壊れているか**: base に、使う者が見当たらない中身と片付けの漏れが合わせて約 525MB ある。dockerd・containerd・グローバルの `aws-cdk-lib`・root の uv・node のヘッダと、apt の一覧である - **誰が困るか**: base とその派生を建てる・取得する・置くすべての利用者。建てる時間とディスクを、誰も使わない中身の分だけ払っている - **直すと何が成り立つか**: base の展開後の大きさが arm64 で 450MB 以上減る。docker CLI・buildx・compose・`cdk`・uv は今と同じに使える。`ENABLE_DIND` は廃止を 1 行で知らせて起動を続ける ## 適用範囲 -- **働く範囲**: このリポジトリの `containers/base`(とそれを `FROM` で継ぐ派生 7 つ)と、base から取り込む `containers/lfm`。利用者が base を建て直した時点で届く +- **働く範囲**: このリポジトリの `containers/base` と、それを `FROM` で継ぐ派生 7 つ。利用者が base を建て直した時点で届く。lfm は #403 で #400 より先に無くなるため含まない(決定 3) - **プロジェクトごとに違うもの**: 無し(イメージの中身だけを変え、プロジェクトの設定・引数を読まない) - **当たるモード**: `standard` @@ -19,7 +19,8 @@ | `docker run --rm --entrypoint bash devbase-base:latest` で測った値(2026-10-03・arm64): `/usr/include/node` 67MB・`/usr/share/doc` 8.0MB・`/usr/share/info` 940KB・`/var/lib/apt/lists` 42MB・グローバルの `aws-cdk-lib` 181MB | 実測 | 外す中身の大きさ。docker-ce 106MB・containerd 81MB・root の uv 40MB は課題の本文の実測 | | 同じコンテナの `/etc/dpkg/dpkg.cfg.d/excludes` が既に `man`・翻訳の `.mo`・`doc`(copyright と changelog を除く)を外している。`/usr/share/doc` に残るのは `changelog*` の 257 ファイルだけで、`/usr/share/man` の下のファイルは 0 | 実測 | 文書の除外で足すのは changelog・info・`/usr/include/node` の 3 つで足りる | | `grep -rIl ENABLE_DIND` を `repos/*/`・`projects/*/` の compose.yml・env・.env にかけて 0 件。当たった compose の注記 1 件はホストの dockerd を指す | 実測 | `ENABLE_DIND` を設定する者がいない | -| #403 の本文: lfm を使うプロジェクトは無く、利用者が 2026-10-03 に lfm の廃止を決めた | 利用者の指示 | DinD を前提に作られた唯一の派生が無くなる | +| #403 の本文: lfm を使うプロジェクトは無く、利用者が 2026-10-03 に lfm の廃止を決めた。Dockerfile を読む試験の部品(`Instruction` / `parse`)をテストの共通の置き場へ移す | 利用者の指示 | DinD を前提に作られた唯一の派生が無くなる。#400 の試験は移した先の部品を使える | +| #400 への利用者のコメント(2026-10-03): lfm は #403 で先に廃止する。lfm への影響は考えなくてよい | 利用者の指示 | #400 は lfm のファイル・試験・仕様が無い状態から始める | | 設計の起動の指示「DinD を廃止するかは …… grep して使う者の有無で決める」 | 利用者の指示の原文 | DinD の扱いを使う者の有無で決める | 要求と受け入れ条件は #400 の本文にある(コピーは `issues/issue-400-requirements.md`)。この文書は「どう作るか」だけを扱う。 @@ -31,7 +32,7 @@ | コンテキスト | 何の語が 1 つの意味に決まるか | | --- | --- | -| イメージの継承(`image-lineage`) | base の中身・文書の除外・展開後の大きさ・DinD。base が入れる物と、派生と lfm へ届く道筋 | +| イメージの継承(`image-lineage`) | base の中身・文書の除外・展開後の大きさ・DinD。base が入れる物と、派生へ届く道筋 | | コンテナの起動(`container-start`) | entrypoint が起動のたびに行う用意。`ENABLE_DIND` の読み方 | イメージの継承が供給者、コンテナの起動が顧客の関係(顧客 / 供給者)。entrypoint は base が入れた物だけを前提に動く。 @@ -43,9 +44,6 @@ base が dockerd を入れなくなるため、entrypoint は dockerd を起こ | --- | --- | --- | --- | --- | | base の中身 | `containers/base/Dockerfile` | base イメージ | apt のパッケージ・npm のグローバルのモジュール・root と ubuntu の道具 | 文書の除外の設定・片付けの対象のパス・`PATH` | | 起動の用意 | `containers/base/entrypoint.sh` | 起動の手順 | DinD の知らせ | `ENABLE_DIND` の値 | -| lfm の取り込み | `containers/lfm/Dockerfile` | lfm イメージ | base から取り込む行 | — | - -この変更は lfm の取り込みから `dind` の 1 つを外すだけで、lfm の他の中身を書き換えない(lfm の廃止は #403)。 ### 不変条件 @@ -59,7 +57,6 @@ base が dockerd を入れなくなるため、entrypoint は dockerd を起こ | I6 | base の中身 | `containers/base/dind` が無く、Dockerfile は `/usr/local/bin/dind` を置かない | 同上 | | I7 | 起動の用意 | `ENABLE_DIND` が `true` か `1` のとき、DinD の廃止を 1 行出して起動を続ける。dockerd を起こさず、`/var/run/docker.sock` を消さず、`docker info` を待たない | 実装の誤り。entrypoint の試験で落とす | | I8 | 起動の用意 | `ENABLE_DIND` が無い・`true` と `1` 以外のとき、何も出さず、起動の手順と順序は変わらない | 同上 | -| I9 | lfm の取り込み | lfm は base から `/usr/local/bin/dind` を取り込まない | 実装の誤り。lfm の取り込みの試験で落とす | ### ドメインイベント @@ -70,8 +67,8 @@ base が dockerd を入れなくなるため、entrypoint は dockerd を起こ | E3 | 変更後の base を amd64 で建てた | 実装の担当 | E4 | | E4 | 建てた base の中身を確かめた | 実装の担当 | PR の記録 | | E5 | 展開後の大きさを測り、減った量を PR に記録した | 実装の担当 | PR の記録・承認する人 | -| E6 | 変更後の base から lfm と派生イメージを建てた | 実装の担当 | E7・PR の記録 | -| E7 | lfm に `/usr/local/bin/dind` が無いことを確かめた | 実装の担当 | PR の記録 | +| E6 | 変更後の base から派生イメージを建てた | 実装の担当 | PR の記録 | +| E7 | (#403 で対象が無くなったため削除) | — | — | | E8 | base で `ENABLE_DIND=true` のコンテナを起こし、廃止の知らせが出て起動が続いた | entrypoint | PR の記録 | | E9 | 利用者が base を建て直した | 利用者(main へのマージの後) | リリース後テスト | @@ -92,7 +89,6 @@ base が dockerd を入れなくなるため、entrypoint は dockerd を起こ | F3 | base の最後の利用者の層に apt の一覧が残らない | 同上 | | F4 | docker CLI・buildx・compose・`cdk`・ubuntu の uv が今と同じに使える | コンテナの中で作業する利用者 | | F5 | `ENABLE_DIND` を設定したままの利用者に、DinD の廃止を 1 行で知らせ、起動は止めない | `ENABLE_DIND` を設定していた利用者 | -| F6 | lfm が base から `dind` を取り込まずに建つ | lfm を建てる利用者(#403 まで) | ## 構成要素 @@ -109,12 +105,10 @@ base が dockerd を入れなくなるため、entrypoint は dockerd を起こ | `containers/base/dind` | — | 消す | | entrypoint の DinD の知らせ(`devbase_notice_dind_removed`、新規) | `ENABLE_DIND` が `true` か `1` なら廃止を 1 行出して 0 で返る。それ以外は何も出さずに 0 で返る。`DEVBASE_ENTRYPOINT_LIB_ONLY` で source した試験から呼べる(決定 2) | 作る | | entrypoint の本体の手順 5 | dockerd を起こす分岐を消し、DinD の知らせを呼ぶ 1 行にする。手順 4 と AI の設定の間という位置は変えない | 変える | -| lfm の Dockerfile の取り込み | `/usr/local/bin/dind` の `COPY --from` を外し、`chmod` を `entrypoint.sh` だけにする(決定 3) | 変える | -| base の形の試験(`tests/containers/test_base_dockerfile_slim.py`、新規) | I1〜I6 を Docker を起こさずに固定する | 作る | +| base の形の試験(`tests/containers/test_base_dockerfile_slim.py`、新規) | I1〜I6 を Docker を起こさずに固定する。Dockerfile の読み方は #403 が共通の置き場へ移した `Instruction` / `parse` を import する(決定 5) | 作る | | DinD の知らせの試験(`tests/containers/test_entrypoint_dind_removed.py`、新規) | I7・I8 を固定する | 作る | -| lfm の取り込みの試験(`tests/containers/test_lfm_base_settings.py`) | 除外表から `PATH /root/.local/bin` の行を消し、I9 の試験を足す | 変える | | base のシェルスクリプトの数え上げ(`tests/containers/test_base_shellcheck_ci.py`・`.github/workflows/ci.yml`・`docs/developer/contributing.md`) | ShellCheck の対象の並びから `dind` を外す | 変える | -| 確定仕様(`docs/specifications/lfm-base-settings.md`・`base-image-shellcheck.md`・`ci-checks.md`) | `dind` の取り込み・`/root/.local/bin` の除外・2 回目の apt の一覧・`dind` の ShellCheck・`SC2009` の抑止の記述を今の形へ直す | 変える | +| 確定仕様(`docs/specifications/base-image-shellcheck.md`・`ci-checks.md`) | 2 回目の apt の一覧・`dind` の ShellCheck・`SC2009` の抑止の記述を今の形へ直す | 変える | | 用語集(`docs/glossary/glossary.json`) | DinD・文書の除外の意味を直し、`glossary.py render` で `docs/glossary.md` を作り直す | 変える | | `CHANGELOG.md` の `[Unreleased]` | 外した中身と、DinD の廃止(破壊的変更・ホストの docker.sock を使う)を書く | 変える | @@ -131,22 +125,16 @@ graph TD subgraph 派生["FROM で継ぐ派生 7 つ"] D[自分の apt-get install] end - subgraph lfm["containers/lfm"] - L[base からの取り込み] - end subgraph 試験["tests/containers"] T1[base の形の試験] T2[DinD の知らせの試験] - T3[lfm の取り込みの試験] end X -->|dpkg の設定を継ぐ| D - E -->|entrypoint.sh だけ| L T1 -.読む.-> base T2 -.source.-> N - T3 -.読む.-> L ``` -### 置き場所 +## 構造 ```text containers/ @@ -155,67 +143,14 @@ containers/ │ ├── dpkg-excludes 新規 │ ├── dind 消す │ └── entrypoint.sh 変える -└── lfm/ - └── Dockerfile 変える(dind の取り込みの 2 行) tests/containers/ ├── test_base_dockerfile_slim.py 新規 ├── test_entrypoint_dind_removed.py 新規 -├── test_lfm_base_settings.py 変える └── test_base_shellcheck_ci.py 変える ``` -### 同じスプリントの課題との境目 - -#401・#402・#403 は base の Dockerfile の同じ層を触る。行ごとに持ち主を 1 つに決め、他の課題の行には触れない(決定 8)。 -行番号は main の `9f3e5c5` の `containers/base/Dockerfile` で数えた。 - -| 場所(行) | 中身 | 持ち主 | -| --- | --- | --- | -| 最初の `RUN` の前(新しい `COPY`) | 文書の除外の設定 | #400 | -| 22 | `fonts-noto-cjk-extra` | #402 | -| 23〜25 の後(最初の apt の一覧) | `fonts-liberation` などの明示 | #402 | -| 37〜43 | Docker の apt の取得元 | 変えない(CLI・buildx・compose に要る) | -| 44〜48 | HashiCorp の apt の取得元 | #402 | -| 56〜67 | amd64 の Chrome の取得元と `BROWSER_PKG` | #401 | -| 71 | `docker-ce`・`containerd.io` | #400(`docker-ce-cli` は残す) | -| 73 | `terraform` | #402 | -| 73 | `$BROWSER_PKG` | #401 | -| 75〜76 の後 | `FROM` の層の changelog・info の削除 | #400 | -| 84〜89・111〜113・247〜251・259 | lfm を前提にした注記と `NPM_GID` | #403 | -| 155〜156 | root の uv | #400 | -| 159 | `aws-cdk-lib` | #400 | -| 177 | `/root/.local/bin` | #400 | -| 234〜235 | Playwright の Chromium と `--with-deps` | #402 | -| 236〜245 | 片付け(`/var/lib/apt/lists/*` を足す) | #400。注記の `--with-deps` の語は #402 | -| 304〜308 | `fc-cache` の注記 | #402 | -| 310〜312 | `dind` の `COPY` | #400 | - -Dockerfile の外で重なるもの: - -| 場所 | 重なり | 扱い | -| --- | --- | --- | -| `docs/specifications/base-image-shellcheck.md` の 2 回目の apt の一覧の行 | #400(`docker-ce` → `docker-ce-cli`)・#401(Chrome)・#402(`terraform`) | 後から入る側が main を取り込み、前の課題の直しを残して自分の語を直す | -| `tests/containers/test_base_dockerfile_playwright.py` | #401・#402 | #400 は触らない。#400 の試験は新しいファイルに置く | -| `tests/containers/test_lfm_base_settings.py`・`containers/lfm/` | #400(除外表の 1 行・I9・取り込みの 2 行)・#403(ファイルごと消す) | #403 が先にマージされたら、#400 は lfm の変更をすべて落とし、受け入れ条件 7 は対象が無いと PR に書く | -| 新しい base の形の試験が使う Dockerfile の読み方の部品(今は `test_lfm_base_settings.py` の `Instruction` / `parse`) | #400(import する)・#403(部品を共通の置き場へ移す) | #403 が部品を移すとき、`test_base_dockerfile_playwright.py` と同じく #400 の試験の import も直す | -| `CHANGELOG.md`・`docs/glossary/glossary.json` | 4 つすべて | 両側の記入を残して解く。`docs/glossary.md` は `glossary.py render` で作り直す | - ## 処理の流れ -### 実装の順 - -```mermaid -graph LR - A["#400 段階 1
使う者のいない中身"] --> B["#401 段階 2
amd64 の Chrome"] - B --> C["#402 段階 3
ブラウザ・フォント・terraform"] - D["#403 lfm の廃止"] -.どの位置でもよい.-> A -``` - -- **#400 → #401 → #402 の順に 1 本ずつマージする。** 後の課題は、前の課題がマージされた main を取り込んでから建てて測る。 - 大きさの比べる元は、その時点の main で建てた base である -- **#400 の 450MB は arm64 で測る。** #401 は amd64 だけを変えるため、#400 の測りに #401 は入らない -- **#403 は順に縛らない。** #400 が先なら #400 が lfm の 2 行を消し、#403 が後で lfm ごと消す。#403 が先なら #400 は lfm の変更を落とす - ### base を建てる順(変更後) ```mermaid @@ -229,7 +164,6 @@ graph TD R4 --> R5["USER ubuntu の RUN
uv・claude・agy・kiro・playwright
片付けで apt の一覧も消す"] R5 --> R6[設定の COPY と fc-cache] R6 --> C2[COPY entrypoint.sh] - C2 -.建てた base から.-> LF["lfm の取り込み
entrypoint.sh だけ(dind なし)"] ``` 建てる流れと起動の流れに乗らない要素(試験・ShellCheck の対象の並び・確定仕様・用語集・`CHANGELOG.md`)は図に含めない。 @@ -257,7 +191,7 @@ graph TD | --- | --- | --- | --- | | 性能・拡張性 | arm64 で展開後の大きさが 450MB 以上減る | 下の内訳の 7 つを外す。見込みは合わせて約 525MB で、450MB に約 75MB の余裕がある | 前提 8 の形で前後の base から作ったコンテナで `du -sbx /` を測り、差と内訳を PR に記録する | | 移行性 | 利用者は base を建て直すだけで移る。戻すときは前の Dockerfile で建て直す | 変えるのはイメージの中身と entrypoint だけで、ボリューム・設定・機密の形を変えない。`ENABLE_DIND` を残した利用者は起動が止まらず、知らせで気づく | 建て直した base で既存の entrypoint の試験が通ること・E8 の起動の出力を PR に記録する | -| システム環境 | arm64 と amd64 の両方で建ち、受け入れ条件 1〜5 を満たす | アーキの `case` を足さない。外すのはアーキに依らない行だけで、文書の除外もアーキに依らない | arm64 で建てて 1〜7・9 を、amd64 で建てて 1〜5 を確かめ、amd64 の端末と方法を PR に書く | +| システム環境 | arm64 と amd64 の両方で建ち、受け入れ条件 1〜5 を満たす | アーキの `case` を足さない。外すのはアーキに依らない行だけで、文書の除外もアーキに依らない | arm64 で建てて 1〜6・8・9 を、amd64 で建てて 1〜5 を確かめ、amd64 の端末と方法を PR に書く | 見込みの内訳(arm64): @@ -274,13 +208,64 @@ graph TD `docker-ce` が依存で引き込んでいたパッケージ(`iptables` など)も、他に要る物が無ければ入らなくなる。この分は見込みに含めない。 +## 同じスプリントの課題との順と境目 + +### 実装の順 + +- **#403 → #400 → #401 → #402 の順に 1 本ずつマージする。** 後の課題は、前の課題がマージされた main を取り込んでから建てて測る。 + 大きさの比べる元は、その時点の main で建てた base である +- **#400 の 450MB は arm64 で測る。** #401 は amd64 だけを変えるため、#400 の測りに #401 は入らない +- **#400 は #403 の後の main から始める。** lfm・`test_lfm_base_settings.py`・`lfm-base-settings.md` は既に無く、#400 は lfm に触れない。前提 8 の「前」の base も #403 の後の main で建てる + +```mermaid +graph LR + D["#403
lfm の廃止"] --> A["#400 段階 1
使う者のいない中身"] + A --> B["#401 段階 2
amd64 の Chrome"] + B --> C["#402 段階 3
ブラウザ・フォント・terraform"] +``` + +### Dockerfile の行の持ち主 + +#401・#402 は base の Dockerfile の同じ層を触る。#403 は #400 より先に入り、lfm を前提にした行を片付ける。行ごとに持ち主を 1 つに決め、他の課題の行には触れない(決定 8)。 +行番号は main の `9f3e5c5` の `containers/base/Dockerfile` で数えた。#403 の後の main では行がずれるため、実装の担当は中身で読み替える。 + +| 場所(行) | 中身 | 持ち主 | +| --- | --- | --- | +| 最初の `RUN` の前(新しい `COPY`) | 文書の除外の設定 | #400 | +| 22 | `fonts-noto-cjk-extra` | #402 | +| 23〜25 の後(最初の apt の一覧) | `fonts-liberation` などの明示 | #402 | +| 37〜43 | Docker の apt の取得元 | 変えない(CLI・buildx・compose に要る) | +| 44〜48 | HashiCorp の apt の取得元 | #402 | +| 56〜67 | amd64 の Chrome の取得元と `BROWSER_PKG` | #401 | +| 71 | `docker-ce`・`containerd.io` | #400(`docker-ce-cli` は残す) | +| 73 | `terraform` | #402 | +| 73 | `$BROWSER_PKG` | #401 | +| 75〜76 の後 | `FROM` の層の changelog・info の削除 | #400 | +| 84〜89・111〜113・247〜251・259 | lfm を前提にした注記と `NPM_GID` | #403(先に入る。#400 は触らない) | +| 155〜156 | root の uv | #400 | +| 159 | `aws-cdk-lib` | #400 | +| 177 | `/root/.local/bin` | #400 | +| 234〜235 | Playwright の Chromium と `--with-deps` | #402 | +| 236〜245 | 片付け(`/var/lib/apt/lists/*` を足す) | #400。注記の `--with-deps` の語は #402 | +| 304〜308 | `fc-cache` の注記 | #402 | +| 310〜312 | `dind` の `COPY` | #400 | + +### Dockerfile の外で重なるもの + +| 場所 | 重なり | 扱い | +| --- | --- | --- | +| `docs/specifications/base-image-shellcheck.md` の 2 回目の apt の一覧の行 | #400(`docker-ce` → `docker-ce-cli`)・#401(Chrome)・#402(`terraform`) | 後から入る側が main を取り込み、前の課題の直しを残して自分の語を直す | +| `tests/containers/test_base_dockerfile_playwright.py` | #401・#402 | #400 は触らない。#400 の試験は新しいファイルに置く | +| Dockerfile の読み方の部品(`Instruction` / `parse`) | #403(`test_lfm_base_settings.py` から共通の置き場へ移す)・#400(import する) | #400 の試験は #403 が移した先を import する。部品は直さない | +| `CHANGELOG.md`・`docs/glossary/glossary.json` | 4 つすべて | 両側の記入を残して解く。`docs/glossary.md` は `glossary.py render` で作り直す | + ## 決定の記録 ### 決定 1: 使う者の有無で決めるため、DinD を廃止し、`dind` と dockerd を起こす分岐を消す `ENABLE_DIND` を設定する者は、リポジトリ・手元のプラグイン・手元のプロジェクトに 0 件である。DinD を前提に作られた -lfm(自分で dockerd を入れ、NVIDIA の runtime を DinD 向けに書く)は使う者が無く、#403 で廃止が決まった。DinD を -残しても動かす先が無く、`dind` と分岐は誰も通らない経路として base とすべての派生に配られ続ける。要求の前提 1 は +lfm は使う者が無く、#403 で #400 より先に廃止する。lfm は自分で dockerd を入れ、NVIDIA の runtime を DinD 向けに書いていた。 +DinD を残しても動かす先が無く、`dind` と分岐は誰も通らない経路として base とすべての派生に配られ続ける。要求の前提 1 は lfm が残る前提で書かれていたため、課題の本文を改め「変更の記録」に残した。 dockerd を入れた新しい派生へ DinD を移す形は採らない。移す先を使う者がいない。lfm に残す形は、lfm ごと消えるため採らない。 @@ -297,28 +282,34 @@ dockerd を入れた新しい派生へ DinD を移す形は採らない。移す 根拠: Mission(MVV 版 1) -### 決定 3: #403 を待たずに進めるため、lfm からは `dind` の取り込みだけを外す +### 決定 3: #403 の後に入れるため、lfm には触らない -base から `dind` を消すと、lfm の `COPY --from=devbase-base:latest /usr/local/bin/dind` が取り込み元を失い、lfm が建たない。 -lfm の他の中身(自分で入れる `docker-ce`・`daemon.json`・`VOLUME /var/lib/docker`)は #403 が lfm ごと消すため触らない。 +利用者は m7c を #403 → #400 → #401 → #402 の順に入れると決め、#400 に「lfm への影響は考えなくてよい」とコメントした。 +#400 の起点の main には lfm の 3 つが無い。`containers/lfm`・`tests/containers/test_lfm_base_settings.py`・ +`docs/specifications/lfm-base-settings.md` である。base から `dind` を消しても、取り込む側が無いため壊れる物は無い。 -#403 を先にマージするよう順を縛る形は採らない。#403 は設計の前で、#400 を止める理由にならない。`dind` を base に -残して lfm の取り込みを保つ形は、使う者のいない台本を配り続けるため採らない。 +#400 が先に入る場合に備えて、lfm から `dind` の取り込みの 2 行を消す形は採らない。順が決まっているため、 +誰も通らない分岐を設計と PR に抱えるだけになる。 根拠: Value 1(MVV 版 1) ### 決定 4: 派生にも効かせて層の大きさから外すため、文書の除外を Ubuntu の `excludes` の後に読まれる別のファイルで置く -`ubuntu:26.04` は `/etc/dpkg/dpkg.cfg.d/excludes` で man・`.mo`・doc を既に外し、copyright と changelog だけを -`path-include` で残している。dpkg は後に読んだ規則を優先するため、`excludes` より後に並ぶ名前 -(`excludes-devbase`)のファイルで doc を外し直し、copyright だけを入れ直せば changelog が外れる。同じファイルで -`/usr/share/info/*`・`/usr/share/man/*`・`/usr/include/node/*` を外す。ファイルは `containers/base/dpkg-excludes` に置き、 -最初の `RUN` の前に `COPY` する。`FROM` の層に既にある changelog と info は、最初の `RUN` の中で消す(層の大きさは -減らないが、受け入れ条件 5 の「copyright のほかのファイルが無い」を満たす)。 +`ubuntu:26.04` は `/etc/dpkg/dpkg.cfg.d/excludes` で man・`.mo`・doc を既に外している。copyright と changelog だけは +`path-include` で残している。dpkg は後に読んだ規則を優先する。そのため `excludes` より後に並ぶ名前(`excludes-devbase`)の +ファイルで doc を外し直し、copyright だけを入れ直せば changelog が外れる。 + +同じファイルで `/usr/share/info/*`・`/usr/share/man/*`・`/usr/include/node/*` を外す。ファイルは +`containers/base/dpkg-excludes` に置き、最初の `RUN` の前に `COPY` する。`FROM` の層に既にある changelog と info は、 +最初の `RUN` の中で消す。層の大きさは減らないが、受け入れ条件 5 の「copyright のほかのファイルが無い」を満たす。 翻訳(`/usr/share/locale`)は外さない。`.mo` は Ubuntu が既に外しており、残る `locale.alias` は glibc が読む。 -Ubuntu の `excludes` を書き換える形は、Ubuntu の持ち物を混ぜるため採らない。`RUN` の中で `printf` で書く形は、 -試験がファイルとして読めないため採らない。入れた後に `rm` する形は、前の層に大きさが残るため採らない。 + +| 採らない形 | 理由 | +| --- | --- | +| Ubuntu の `excludes` を書き換える | Ubuntu の持ち物を混ぜる | +| `RUN` の中で `printf` で書く | 試験がファイルとして読めない | +| 入れた後に `rm` する | 前の層に大きさが残る | 根拠: Value 1(MVV 版 1) @@ -326,14 +317,15 @@ Ubuntu の `excludes` を書き換える形は、Ubuntu の持ち物を混ぜる 外した物ごとに 1 つの試験にし、Dockerfile へ戻すと名前を挙げて落ちる(受け入れ条件 11)。既存の `test_base_dockerfile_playwright.py` などは #401・#402 が直すため、同じファイルに書くと並行する変更がぶつかる。 -Dockerfile の読み方(命令への分け方)は既存の試験の部品を使い、新しく書かない。 +Dockerfile の読み方(命令への分け方)は新しく書かない。#403 が `test_lfm_base_settings.py` からテストの共通の置き場へ +移した部品(`Instruction` / `parse`)を import する。 根拠: Value 1(MVV 版 1) -### 決定 6: 空の置き場を指さないよう、`PATH` から `/root/.local/bin` を外し、lfm の除外表の行も消す +### 決定 6: 空の置き場を指さないよう、`PATH` から `/root/.local/bin` を外す -root の uv を外すと `/root/.local/bin` に入る物が無くなる。`PATH` に残すと、lfm の除外表の行が「base で root の uv が -入る場所」という誤った理由のまま残る。除外表の試験は使われない除外を落とすため、`PATH` と除外表の行を同じ変更で消す。 +root の uv を外すと `/root/.local/bin` に入る物が無くなる。`PATH` に残すと、何も入らない置き場を base とすべての派生に +配り続ける。この要素を名前で除外していた lfm の試験は #403 で消えているため、外しても他の試験は変わらない。 `PATH` を残す形は、理由の無い要素を配り続けるため採らない。 @@ -341,22 +333,23 @@ root の uv を外すと `/root/.local/bin` に入る物が無くなる。`PATH` ### 決定 7: #402 が Playwright を外しても壊れないよう、apt の一覧の片付けを規則で縛る -試験は「利用者の層の片付けに `/var/lib/apt/lists` がある」ではなく、「`/var/lib/apt` を cache mount せずに apt の一覧を -取得する `RUN` は、同じ `RUN` で一覧を消す」(I4)を見る。#402 が `--with-deps` を外すと、利用者の層は一覧を取得しなく +試験は I4 の規則を見る。「`/var/lib/apt` を cache mount せずに apt の一覧を取得する `RUN` は、同じ `RUN` で一覧を消す」 +である。「利用者の層の片付けに `/var/lib/apt/lists` がある」は見ない。#402 が `--with-deps` を外すと、利用者の層は一覧を取得しなく なり、規則は当たる `RUN` が無いまま通る。片付けの 1 語が残っても害は無く、#402 が消してもよい。 `--with-deps` の有無に関わらず利用者の層に片付けの語を求める形は、#402 の後に意味の無い要求になるため採らない。 根拠: Value 1(MVV 版 1) -### 決定 8: 並行する削減がぶつからないよう、#400 → #401 → #402 の順に 1 本ずつ入れ、Dockerfile の行の持ち主を分ける +### 決定 8: 並行する削減がぶつからないよう、#403 → #400 → #401 → #402 の順に 1 本ずつ入れ、Dockerfile の行の持ち主を分ける -3 つは段階の番号の順で、外す量の小さい順でもある。#400 は arm64 の測りが #401 に依らず、#401 は amd64 だけを触り、 +#403 は lfm と、lfm を前提にした base の行を先に片付け、後の 3 つの比べる元から lfm を外す。#400 以下の 3 つは段階の +番号の順で、外す量の小さい順でもある。#400 は arm64 の測りが #401 に依らず、#401 は amd64 だけを触り、 #402 は Playwright と apt の一覧の両方を変える。後の課題ほど前の結果を前提にできる。`main` は strict で、続けて マージすると後の 1 本が BEHIND になるため、1 本ずつ main を取り込み、建てて測り直してからマージする。行の持ち主は 「同じスプリントの課題との境目」の表に従う。 -3 つを 1 本の PR にまとめる形は、測りが混ざり、どの削減が何を減らしたかを PR に記録できないため採らない。 +削減の 3 つを 1 本の PR にまとめる形は、測りが混ざり、どの削減が何を減らしたかを PR に記録できないため採らない。 根拠: Value 1 / P1(MVV 版 1) @@ -372,12 +365,11 @@ root の uv を外すと `/root/.local/bin` に入る物が無くなる。`PATH` | I6(受け入れ条件 11) | `containers/base/dind` が無く、Dockerfile に `/usr/local/bin/dind` が無い | `dind` を戻す・`COPY` を戻すと落ちる | | I7(受け入れ条件 9) | `ENABLE_DIND` が `true`・`1` のとき、DinD の知らせが 1 行だけ出て 0 で返り、`sudo`・`dockerd`・`docker`・`rm` を呼ばない | 知らせの後に `docker info` を待つ・docker.sock を消す・dockerd を起こす・0 以外で返るように壊すと落ちる | | I8(受け入れ条件 10) | `ENABLE_DIND` が無い・`false`・空のとき、何も出さずに 0 で返る。既存の entrypoint の試験が変わらず通る | 未設定でも知らせを出すように壊すと落ちる | -| I9(受け入れ条件 7) | lfm の Dockerfile が base から `/usr/local/bin/dind` を取り込まない | lfm に取り込みの行を戻すと落ちる | | 受け入れ条件 1〜5(建てた base) | arm64 と amd64 で建てた base で `command -v dockerd`・`command -v containerd` が失敗し、`docker --version` などの 5 つが 0 で終わり、`npm ls -g aws-cdk-lib` が空で、`/var/lib/apt/lists`・`/usr/share/man`・`/usr/include/node`・`/usr/share/doc` が条件どおりである | 手動確認(マージ前)。出力を PR に記録する | | 受け入れ条件 6 | 前提 8 の形で前後の展開後の大きさの差が 450,000,000 バイト以上 | 手動確認。届かなければ内訳を PR に書いて人へ戻す | -| 受け入れ条件 7・8 | 変更後の base から lfm と派生 7 つが建ち、lfm に `/usr/local/bin/dind` が無い | 手動確認。建たなければ取り込みか手順を直す | +| 受け入れ条件 8 | 変更後の base から派生 7 つが建つ | 手動確認。建たなければ外した物を前提にした手順を直す | | 受け入れ条件 9(建てた base) | `ENABLE_DIND=true` で起こしたコンテナの起動の出力に知らせが 1 行あり、完了の印ができる | 手動確認。出力を PR に記録する | -| 受け入れ条件 12 | `env -u DEVBASE_ROOT uv run --locked pytest tests/ -q` が通る | ShellCheck の対象に `dind` が残る・除外表に `/root/.local/bin` が残ると、既存の試験が落ちる | +| 受け入れ条件 12 | `env -u DEVBASE_ROOT uv run --locked pytest tests/ -q` が通る | ShellCheck の対象に `dind` が残ると、既存の試験が落ちる | | 受け入れ条件 13 | `CHANGELOG.md` の `[Unreleased]` に、外した 5 つと DinD の廃止(破壊的変更・ホストの docker.sock を使う)がある | 実装のレビューで見る | | 受け入れ条件 14 | base の Dockerfile の差分が、次の 6 つの変更(除外の `COPY`・apt の層・root の道具の層・`PATH`・片付け・`dind` の `COPY`)だけである | 実装のレビューで `git diff main -- containers/base/Dockerfile` を見る | @@ -385,7 +377,7 @@ root の uv を外すと `/root/.local/bin` に入る物が無くなる。`PATH` | 課題 | 扱い | 取り込み先 | 触るファイル | | --- | --- | --- | --- | -| #400 | 実装する | — | `containers/base/Dockerfile`、`containers/base/dpkg-excludes`、`containers/base/dind`、`containers/base/entrypoint.sh`、`containers/lfm/Dockerfile`、`tests/containers/`、`.github/workflows/ci.yml`、`docs/developer/contributing.md`、`docs/specifications/`、`docs/glossary/glossary.json`、`docs/glossary.md`、`CHANGELOG.md` | +| #400 | 実装する | — | `containers/base/Dockerfile`、`containers/base/dpkg-excludes`、`containers/base/dind`、`containers/base/entrypoint.sh`、`tests/containers/`、`.github/workflows/ci.yml`、`docs/developer/contributing.md`、`docs/specifications/`、`docs/glossary/glossary.json`、`docs/glossary.md`、`CHANGELOG.md` | ## 未確認のまま残ること @@ -396,4 +388,4 @@ root の uv を外すと `/root/.local/bin` に入る物が無くなる。`PATH` | node のヘッダの無い環境 | ネイティブアドオンを入れるプロジェクトで node-gyp がヘッダを取得できるか(要求の前提 6)は、リリース後テストで利用者のプロジェクトで分かる | | 派生の apt の文書 | latex・php・php85 が自分で入れるパッケージの文書も外れる。実行時に `/usr/share/doc` の中身を読む道具が派生にあるかは、派生を建てて使うまで分からない | | #402 の要求との食い違い | #402 の前提 5 は amd64 の Chrome を base に残すとしているが、#401 がそれを外す。#402 の設計で前提を直す必要がある(#402 へ書き残した) | -| #403 との順 | #403 が #400 より先にマージされると、受け入れ条件 7 と I9 は対象が無くなる。そのときは PR に書いて外す | +| 共通の部品の置き場 | #400 の試験が import する `Instruction` / `parse` の置き場の名前は #403 の実装で決まる。#400 の実装の担当は #403 の後の main で確かめる | diff --git a/issues/issue-400-requirements.md b/issues/issue-400-requirements.md index 6507587f..6112a807 100644 --- a/issues/issue-400-requirements.md +++ b/issues/issue-400-requirements.md @@ -35,26 +35,25 @@ | 事実 | 出所 | | --- | --- | -| lfm は base を `FROM` で継がず、`/entrypoint.sh` と `/usr/local/bin/dind` を base のイメージから `COPY --from` で取り込む。lfm は自分で `docker-ce`・`containerd.io` を入れ、`/etc/docker/daemon.json` に NVIDIA の runtime を書く(DinD を前提にした作り) | `containers/lfm/Dockerfile:55-60`・`:169-173`・`:175-200` | | entrypoint の DinD の分岐は `ENABLE_DIND` が `true` / `1` のときだけ動き、最初に `/var/run/docker.sock` を消してから `dind dockerd` を起こし、`docker info` を最大 30 秒待つ | `containers/base/entrypoint.sh:862-` | | `ENABLE_DIND` を設定している compose・env は、このリポジトリと手元のプラグイン(`repos/` の下)に見当たらない。利用者向けの文書(`docs/`・`README`・`CHANGELOG.md`)にも DinD の案内は無い | `grep -rn "ENABLE_DIND\|DinD" docs README* CHANGELOG.md lib` と `grep -rln "ENABLE_DIND\|dockerd" repos/ projects/`(当たりはプラグインの 1 つ(proj-a)の compose の注記だけで、ホストの dockerd を指す) | | base を `FROM` で継ぐ派生イメージは bi-tools・general・go・latex・php・php85・trygroup。dpkg の設定(`/etc/dpkg/dpkg.cfg.d/`)は継がれ、latex・php・php85 は自分で `apt-get install` する | `containers/*/Dockerfile` | | 派生イメージに root で uv を使う手順は無い(bi-tools の `uv tool install` は `USER ubuntu` の下) | `containers/bi-tools/Dockerfile:29-47` | -| `PATH` の `/root/.local/bin` は、lfm の設定の取り込みの試験が「lfm へ届けない要素」として名前で除外している | `tests/containers/test_lfm_base_settings.py:40`・`docs/specifications/lfm-base-settings.md:225` | | CI はイメージを建てない。イメージの確かめは手元で行う | `.github/workflows/ci.yml` | -| dockerd を自分で入れ `ENABLE_DIND` で DinD を起こせる lfm は、使うプロジェクトが無く、同じマイルストーンの #403 で廃止が決まった | #403 の本文 | +| DinD を前提に作られた唯一の派生 lfm(自分で dockerd を入れ、base から `dind` を `COPY --from` で取り込む)は、使うプロジェクトが無く、同じスプリント m7c の #403 で #400 より先に廃止する | #403 の本文・#400 への利用者のコメント(2026-10-03) | | `ENABLE_DIND` を設定している compose・env は、手元のプラグイン(`repos/*/`)と `projects/*/` に 0 件である(設計で再び確かめた) | `grep -rIl ENABLE_DIND repos/*/ projects/*/ --include=compose.yml --include=env --include=.env` | ## 前提 -- 前提 1(DinD の扱い): DinD を廃止する。base から dockerd と containerd を外し、`containers/base/dind` と entrypoint の `ENABLE_DIND` の分岐(dockerd を起こす手順)を消す。根拠: `ENABLE_DIND` を設定する者がリポジトリ・手元のプラグイン・手元のプロジェクトに無く、DinD を前提に作られた lfm は使う者が無く #403 で廃止が決まった。起票時の選択肢「消す」「使う派生へ移す」のうち、移す先を使う者がいないため前者を採る(設計で前提を改めた。「変更の記録」) -- 前提 2: base とその派生・lfm で `ENABLE_DIND=true` を設定している利用者はいない(上の調べ)。設定していた利用者は、base を建て直した後に DinD が起きなくなる。entrypoint はこの設定を見つけたら廃止を 1 行で知らせて起動を続け、CHANGELOG でホストの docker.sock を使うよう案内する +- 前提 1(DinD の扱い): DinD を廃止する。base から dockerd と containerd を外し、`containers/base/dind` と entrypoint の `ENABLE_DIND` の分岐(dockerd を起こす手順)を消す。根拠: `ENABLE_DIND` を設定する者がリポジトリ・手元のプラグイン・手元のプロジェクトに無く、DinD を前提に作られた lfm は使う者が無く、#400 より先に #403 で廃止する。起票時の選択肢「消す」「使う派生へ移す」のうち、移す先を使う者がいないため前者を採る(設計で前提を改めた。「変更の記録」) +- 前提 2: base とその派生で `ENABLE_DIND=true` を設定している利用者はいない(上の調べ)。設定していた利用者は、base を建て直した後に DinD が起きなくなる。entrypoint はこの設定を見つけたら廃止を 1 行で知らせて起動を続け、CHANGELOG でホストの docker.sock を使うよう案内する - 前提 3: root で uv を使う利用者・処理は無い。base の root の uv を外した後、`sudo uv` は「コマンドが無い」で失敗してよい - 前提 4: グローバルの `aws-cdk-lib` を `require` する利用者は無い。CDK のアプリは自分の `package.json` に `aws-cdk-lib` を持ち、`cdk synth` はそれを使う -- 前提 5: dpkg の除外設定は base を `FROM` で継ぐ派生イメージにも効き、派生が後から apt で入れるパッケージの文書も入らなくてよい(copyright は残る)。lfm は `/etc/dpkg` を取り込まないため対象外 +- 前提 5: dpkg の除外設定は base を `FROM` で継ぐ派生イメージにも効き、派生が後から apt で入れるパッケージの文書も入らなくてよい(copyright は残る) - 前提 6: `/usr/include/node` を外すと、npm のネイティブアドオンのビルドでは node-gyp がヘッダを取得する(ネットワークが要る)。これを許す - 前提 7: amd64 の確かめは、amd64 の Docker が動く端末(WSL2 の端末など)か、`docker buildx build --platform linux/amd64` で行う。どちらで行ったかを PR に書く - 前提 8: 大きさは、建てた base から作ったコンテナで `du -sbx /` を測った値で比べる。前は main の Dockerfile で建てた base、後はこの変更の Dockerfile で建てた base とし、同じ端末・同じ日に建てる(apt と npm の取得する版の差を小さくする) +- 前提 9: #403(lfm の廃止)が #400 より先にスプリントの統合先へ入る。#400 の起点には `containers/lfm`・`tests/containers/test_lfm_base_settings.py`・`docs/specifications/lfm-base-settings.md` が無く、Dockerfile を読む試験の部品(`Instruction` / `parse`)は #403 が移した共通の置き場にある。#400 は lfm への影響を考えない(利用者のコメント、2026-10-03) ## 対象範囲 @@ -63,13 +62,12 @@ - base の最後の利用者の層で残る `/var/lib/apt/lists` を消す - dpkg の除外設定で、`/usr/share/doc`(copyright を除く)・`/usr/share/man` などの文書と `/usr/include/node` を入れない - `containers/base/dind` と entrypoint の DinD の分岐を消し、`ENABLE_DIND` を設定したときは廃止の知らせを 1 行出す -- lfm が base から `dind` を取り込む行を消す(lfm が建ち続けるための最小の変更) - 外した中身に触れる試験(`tests/containers/`)と仕様(`docs/specifications/`)の追従 - `CHANGELOG.md` の `[Unreleased]` への記入 含まない: - 段階 2・3 の削減(重い道具を派生イメージへ移す・版の固定の見直し)。別の課題 -- lfm の廃止(#403)と、lfm の中身の削減(lfm が自分で入れる `docker-ce`・`daemon.json` などは触らない) +- lfm の廃止(#403。#400 より先に入るため、#400 は lfm に触れない) - base の他の道具の追加・版の変更 - イメージを建てる CI の追加 - 利用者の環境で `devbase up` を実行して確かめること(P3。リリース後テストで利用者が行う) @@ -83,8 +81,8 @@ | E3 | 変更後の base を amd64 で建てた | E2 の成功 | 建たなければ変更を直す(アーキの差は `case` の分岐で起きやすい) | E2 | | E4 | 建てた base の中身を確かめた(外した物が無く、残す道具が動く) | E2・E3 の成功 | 残す道具が動かなければ変更を直す | E2・E3 | | E5 | 展開後の大きさを測り、減った量を PR に記録した | E4 の成功 | 450MB に届かなければ、届かない理由と内訳を PR に書いて人へ戻す | E1・E4 | -| E6 | 変更後の base から lfm と、`FROM` で継ぐ派生イメージを建てた | E2 の成功 | 建たなければ、外した物を前提にした取り込みや手順を直す | E2 | -| E7 | lfm に `/usr/local/bin/dind` が無いことを確かめた | E6 の成功 | 残っていれば lfm の取り込みの行を直す | E6 | +| E6 | 変更後の base から、`FROM` で継ぐ派生イメージを建てた | E2 の成功 | 建たなければ、外した物を前提にした取り込みや手順を直す | E2 | +| E7 | (#403 で対象が無くなったため削除) | — | — | — | | E8 | base で `ENABLE_DIND=true` のコンテナを起こし、entrypoint が DinD の廃止を知らせて起動を続けた | E2 の成功 | 起動が止まる・dockerd を起こそうとする・ホストの docker.sock が消えるなら entrypoint を直す | E2 | | E9 | 利用者が base を建て直した | main へのマージ(配布) | 建たなければ利用者は前のイメージで動き続ける。リリース後テストで見つける | E2〜E8・マージ | @@ -104,7 +102,7 @@ - [ ] 4. 変更後の base で、`/var/lib/apt/lists` の下に `lock` と `partial` のほかのファイルが無い - [ ] 5. 変更後の base で、`/usr/share/man` の下と `/usr/include/node` にファイルが無く、`/usr/share/doc` の下には `copyright` のほかのファイルが無い。`/usr/share/doc/<パッケージ>/copyright` は apt で入れたパッケージについて残る - [ ] 6. arm64 で、変更前の base と変更後の base の展開後の大きさの差が 450MB(450,000,000 バイト)以上ある。前後の値と差を PR に記録する -- [ ] 7. 変更後の base から lfm が建ち、lfm に `/usr/local/bin/dind` が無い +- 7. (#403 で lfm が #400 より先に無くなるため削除。番号は参照を保つため詰めない) - [ ] 8. 変更後の base から、`FROM devbase-base:latest` で継ぐ派生イメージ(bi-tools・general・go・latex・php・php85・trygroup)が建つ - [ ] 9. `ENABLE_DIND` に `true` か `1` を設定して base のコンテナを起こすと、entrypoint は DinD を廃止したことを 1 行出して起動を続ける。`/var/run/docker.sock` を消さず、dockerd を起こさず、`docker info` を待たない - [ ] 10. `ENABLE_DIND` を設定しない base のコンテナの起動は、変更の前と同じ順で同じ用意を行う(entrypoint の既存の試験が通る) @@ -125,7 +123,7 @@ | 対象 | 影響 | | --- | --- | -| 公開インタフェース | devbase の CLI は変わらない。base のイメージから `dockerd`・`containerd`・グローバルの `aws-cdk-lib`・root の uv・文書が消える。base とその派生・lfm での `ENABLE_DIND=true` は DinD を起こさなくなり、廃止の知らせを 1 行出す | +| 公開インタフェース | devbase の CLI は変わらない。base のイメージから `dockerd`・`containerd`・グローバルの `aws-cdk-lib`・root の uv・文書が消える。base とその派生での `ENABLE_DIND=true` は DinD を起こさなくなり、廃止の知らせを 1 行出す | | データ | 変わらない | | 既存の振る舞い | entrypoint の DinD の分岐が無くなる。派生イメージで apt が入れるパッケージの文書が入らなくなる | @@ -133,10 +131,10 @@ | 項目 | 手段 | | --- | --- | -| 起動 | `devbase build` で base と lfm・派生を建てる(建て方は設計で決める) | +| 起動 | `devbase build` で base と派生を建てる(建て方は設計で決める) | | テスト | `env -u DEVBASE_ROOT uv run --locked pytest tests/ -q` | | 静的解析・型検査 | `uvx ruff check --select=E9,F63,F7,F82 lib`・`python3 .github/scripts/proper_term_check.py`・base のシェルスクリプトの ShellCheck(開発参加ガイドの「CI が実行するもの」) | -| 手動確認(マージ前) | arm64 で建てた base と lfm で受け入れ条件 1〜7・9 を確かめ、出力と大きさを PR に記録する。amd64 で建てた base で受け入れ条件 1〜5 を確かめ、どの端末・どの方法で建てたかを PR に記録する | +| 手動確認(マージ前) | arm64 で建てた base と派生で受け入れ条件 1〜6・8・9 を確かめ、出力と大きさを PR に記録する。amd64 で建てた base で受け入れ条件 1〜5 を確かめ、どの端末・どの方法で建てたかを PR に記録する | | 手動確認 | 利用者が自分の環境で base を建て直し、普段のプロジェクトで docker・`cdk`・uv が使えることを確かめる(リリース後テスト。P3 のため利用者が行う) | ## 前提とする取り決め @@ -153,14 +151,14 @@ | --- | --- | | 常に行う | 全体のテスト・lint・固有の語の検査を push の前に打つ。base を建てる前に `docker system df` で空きを見て、作業用のタグは記録の後に消す(`AGENTS.md` の落とし穴) | | 確認してから行う | 対象範囲の外の道具を base から外す・足す・版を変える(P1) | -| 行わない | 利用者の環境で `devbase up` を実行する(P3)。タグ・Release を作る(P2)。lfm を廃止する・lfm の中身を削る(#403)。プラグインのリポジトリの compose を直す | +| 行わない | 利用者の環境で `devbase up` を実行する(P3)。タグ・Release を作る(P2)。lfm に触れる(#403 で #400 より先に廃止される)。プラグインのリポジトリの compose を直す | ## 未決 | 項目 | 誰が決めるか | 期限 | | --- | --- | --- | | dpkg の除外設定で外す置き場の一覧(`/usr/share/doc`・`man`・`info`・`locale`・`/usr/include/node` のどこまでか)と、除外設定を置く位置(最初の `apt-get install` より前) | 設計(`design`) | 設計 PR | -| 外した後の `PATH` の `/root/.local/bin` を残すか消すか(lfm の設定の取り込みの試験の除外表に影響する) | 設計(`design`) | 設計 PR | +| 外した後の `PATH` の `/root/.local/bin` を残すか消すか | 設計(`design`) | 設計 PR | | amd64 を建てる端末と方法(前提 7) | 実装の担当 | 手動確認(マージ前) | ## 変更の記録 @@ -168,3 +166,4 @@ | 日 | 工程 | 変えたこと | 理由 | | --- | --- | --- | --- | | 2026-10-03 | 設計 | 前提 1 を「DinD を lfm に残す」から「DinD を廃止する」へ改め、前提 2・対象範囲・E6〜E8・受け入れ条件 7・9・11・13・影響・境界・未決を合わせて直した | 要求を書いた後に #403 で lfm の廃止が決まり、DinD を使える唯一の派生が無くなる。`ENABLE_DIND` を設定する者も 0 件である | +| 2026-10-03 | 設計 | #403 が #400 より先に入る前提へ改めた。前提 9 を足し、lfm の事実の 2 行・前提 2・5 の lfm・対象範囲の lfm の取り込み・E6・E7・受け入れ条件 7・影響・検証手段・境界・未決の lfm を消すか直した。E7 と受け入れ条件 7 は番号を詰めずに削除と書いた | 利用者が #403 → #400 → #401 → #402 の順に入れると決め、#400 で lfm への影響を考えなくてよいとコメントした | From 9d3c7d66985fdec4b26cb0a299c196b357cc3c90 Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Sat, 3 Oct 2026 11:00:41 +0900 Subject: [PATCH 4/5] =?UTF-8?q?docs:=20#400=20=E3=81=AE=E8=A8=AD=E8=A8=88?= =?UTF-8?q?=E3=81=AE=E7=94=A8=E8=AA=9E=E3=83=BB=E6=96=87=E6=9B=B8=E3=81=AE?= =?UTF-8?q?=E5=89=8A=E9=99=A4=E3=83=BBuv=20=E3=81=AE=E7=A2=BA=E3=81=8B?= =?UTF-8?q?=E3=82=81=E6=96=B9=E3=82=92=E3=83=AC=E3=83=93=E3=83=A5=E3=83=BC?= =?UTF-8?q?=E3=81=AB=E5=90=88=E3=82=8F=E3=81=9B=E3=81=A6=E7=9B=B4=E3=81=99?= =?UTF-8?q?=EF=BC=88#400=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 展開後の大きさを用語集へ新しく載せる語として扱い、意味の文を glossary と揃える - /usr/share/doc に残る copyright でないファイルと symlink(実測 40 個)を最初の RUN と利用者の層で消す手順と I5 の試験を足す - 受け入れ条件 2 の uv をログインシェル(bash -lc)で確かめると書く Co-Authored-By: Claude Opus 5.5 --- issues/issue-400-design.md | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/issues/issue-400-design.md b/issues/issue-400-design.md index af0c437c..1adda1ce 100644 --- a/issues/issue-400-design.md +++ b/issues/issue-400-design.md @@ -17,7 +17,7 @@ | 根拠 | 種類 | 何を示すか | | --- | --- | --- | | `docker run --rm --entrypoint bash devbase-base:latest` で測った値(2026-10-03・arm64): `/usr/include/node` 67MB・`/usr/share/doc` 8.0MB・`/usr/share/info` 940KB・`/var/lib/apt/lists` 42MB・グローバルの `aws-cdk-lib` 181MB | 実測 | 外す中身の大きさ。docker-ce 106MB・containerd 81MB・root の uv 40MB は課題の本文の実測 | -| 同じコンテナの `/etc/dpkg/dpkg.cfg.d/excludes` が既に `man`・翻訳の `.mo`・`doc`(copyright と changelog を除く)を外している。`/usr/share/doc` に残るのは `changelog*` の 257 ファイルだけで、`/usr/share/man` の下のファイルは 0 | 実測 | 文書の除外で足すのは changelog・info・`/usr/include/node` の 3 つで足りる | +| 同じコンテナの `/etc/dpkg/dpkg.cfg.d/excludes` が既に `man`・翻訳の `.mo`・`doc`(copyright と changelog を除く)を外している。`/usr/share/man` の下のファイルは 0。`/usr/share/doc` には copyright と `changelog*` のほかに 40 個のファイルと symlink が残る(`apt/NEWS.Debian.gz`・`gnupg/TODO`・`gnupg/examples/*`・`base-files/FAQ`・`libavahi-common3/README`・`python3/README.Debian`・`fonts-dejavu-core/*` などのファイルと、`libgcc-s1`・`libpython3.14` などの symlink)(2026-10-03・arm64 で `find /usr/share/doc ! -type d ! -name copyright ! -name 'changelog*'` を数えた) | 実測 | 文書の除外で足すのは changelog・info・`/usr/include/node` の 3 つ。dpkg の規則だけでは既に残る物が消えないため、最初の `RUN` と利用者の層で `/usr/share/doc` の下の copyright でないファイルと symlink を消す(決定 4) | | `grep -rIl ENABLE_DIND` を `repos/*/`・`projects/*/` の compose.yml・env・.env にかけて 0 件。当たった compose の注記 1 件はホストの dockerd を指す | 実測 | `ENABLE_DIND` を設定する者がいない | | #403 の本文: lfm を使うプロジェクトは無く、利用者が 2026-10-03 に lfm の廃止を決めた。Dockerfile を読む試験の部品(`Instruction` / `parse`)をテストの共通の置き場へ移す | 利用者の指示 | DinD を前提に作られた唯一の派生が無くなる。#400 の試験は移した先の部品を使える | | #400 への利用者のコメント(2026-10-03): lfm は #403 で先に廃止する。lfm への影響は考えなくてよい | 利用者の指示 | #400 は lfm のファイル・試験・仕様が無い状態から始める | @@ -53,7 +53,7 @@ base が dockerd を入れなくなるため、entrypoint は dockerd を起こ | I2 | base の中身 | npm のグローバルに `aws-cdk-lib` を入れず、`aws-cdk` を入れる | 同上 | | I3 | base の中身 | uv のインストーラを呼ぶのは `USER ubuntu` の後の `RUN` だけで、`ENV PATH` に `/root/.local/bin` が無い | 同上 | | I4 | base の中身 | apt の一覧を取得する `RUN`(`apt-get update` か `--with-deps` を含み、`/var/lib/apt` を cache mount しないもの)は、同じ `RUN` で `/var/lib/apt/lists` を消す | 同上。どの `RUN` かを挙げて落ちる | -| I5 | base の中身 | 文書の除外の設定が、最初の `RUN` より前に Ubuntu の `excludes` より後に読まれる名前で置かれ、copyright を残して changelog・info・man・`/usr/include/node` を外す | 同上 | +| I5 | base の中身 | 文書の除外の設定が、最初の `RUN` より前に Ubuntu の `excludes` より後に読まれる名前で置かれ、copyright を残して changelog・info・man・`/usr/include/node` を外す。最初の `RUN` と利用者の層の `RUN` は、`/usr/share/doc` の下の copyright でないファイルと symlink を消す | 同上 | | I6 | base の中身 | `containers/base/dind` が無く、Dockerfile は `/usr/local/bin/dind` を置かない | 同上 | | I7 | 起動の用意 | `ENABLE_DIND` が `true` か `1` のとき、DinD の廃止を 1 行出して起動を続ける。dockerd を起こさず、`/var/run/docker.sock` を消さず、`docker info` を待たない | 実装の誤り。entrypoint の試験で落とす | | I8 | 起動の用意 | `ENABLE_DIND` が無い・`true` と `1` 以外のとき、何も出さず、起動の手順と順序は変わらない | 同上 | @@ -78,7 +78,9 @@ base が dockerd を入れなくなるため、entrypoint は dockerd を起こ | --- | --- | --- | | DinD | コンテナの中で dockerd を起こし、そのコンテナの中だけの docker を使う形。#400 で廃止し、`ENABLE_DIND` は知らせを 1 行出すだけになった。ホストの docker.sock を mount して使う形と区別する | 意味の変更(`image-lineage`) | | 文書の除外 | dpkg の `path-exclude` の設定で、apt が入れるパッケージから文書などの置き場を展開しないこと。base は Ubuntu の `excludes` に加え、changelog・info・`/usr/include/node` を外す(copyright は残す)。base を `FROM` で継ぐ派生イメージにも効く | 意味の変更(`image-lineage`) | -| 展開後の大きさ | 建てたイメージから作ったコンテナで `du -sbx /` を測ったバイト数 | 既存(意味は変えない) | +| 展開後の大きさ | 建てたイメージから作ったコンテナで `du -sbx /` を測ったバイト数。`docker images` の圧縮後の大きさとは違う | 新規(`image-lineage`) | + +意味の文はこの表が正本で、`docs/glossary/glossary.json` の `meaning` はこの表の文と同じ文にする(コードの印の backtick だけを除く)。 ## 機能一覧 @@ -97,10 +99,10 @@ base が dockerd を入れなくなるため、entrypoint は dockerd を起こ | 要素 | 責務 | 変更 | | --- | --- | --- | | 文書の除外の設定(`containers/base/dpkg-excludes`、新規) | `/etc/dpkg/dpkg.cfg.d/excludes-devbase` として置かれ、Ubuntu の `excludes` の後に読まれて changelog・info・man・`/usr/include/node` を外し、copyright を残す(決定 4) | 作る | -| base の Dockerfile の apt の層(最初の `RUN`) | 文書の除外の設定を `COPY` で先に置き、`docker-ce`・`containerd.io` を一覧から外す。`FROM` の層に既にある changelog・info を同じ `RUN` で消す | 変える | +| base の Dockerfile の apt の層(最初の `RUN`) | 文書の除外の設定を `COPY` で先に置き、`docker-ce`・`containerd.io` を一覧から外す。同じ `RUN` の最後で `/usr/share/doc` の下の copyright でないファイルと symlink(changelog を含む)と `/usr/share/info` の中身を消す(決定 4) | 変える | | base の Dockerfile の root の道具の層(2 つ目の大きな `RUN`) | root の uv のインストーラの呼び出しと、npm の `aws-cdk-lib` を外す | 変える | | base の Dockerfile の `ENV PATH` | `/root/.local/bin` を外す(決定 6) | 変える | -| base の Dockerfile の利用者の層 | 片付けに `/var/lib/apt/lists/*` を足す(決定 7) | 変える | +| base の Dockerfile の利用者の層 | 片付けに `/var/lib/apt/lists/*` を足す(決定 7)。同じ片付けで `/usr/share/doc` の下の copyright でないファイルと symlink を消す(決定 4) | 変える | | base の Dockerfile の最後の `COPY` | `dind` の `COPY` を外し、`entrypoint.sh` だけを置く | 変える | | `containers/base/dind` | — | 消す | | entrypoint の DinD の知らせ(`devbase_notice_dind_removed`、新規) | `ENABLE_DIND` が `true` か `1` なら廃止を 1 行出して 0 で返る。それ以外は何も出さずに 0 で返る。`DEVBASE_ENTRYPOINT_LIB_ONLY` で source した試験から呼べる(決定 2) | 作る | @@ -109,7 +111,7 @@ base が dockerd を入れなくなるため、entrypoint は dockerd を起こ | DinD の知らせの試験(`tests/containers/test_entrypoint_dind_removed.py`、新規) | I7・I8 を固定する | 作る | | base のシェルスクリプトの数え上げ(`tests/containers/test_base_shellcheck_ci.py`・`.github/workflows/ci.yml`・`docs/developer/contributing.md`) | ShellCheck の対象の並びから `dind` を外す | 変える | | 確定仕様(`docs/specifications/base-image-shellcheck.md`・`ci-checks.md`) | 2 回目の apt の一覧・`dind` の ShellCheck・`SC2009` の抑止の記述を今の形へ直す | 変える | -| 用語集(`docs/glossary/glossary.json`) | DinD・文書の除外の意味を直し、`glossary.py render` で `docs/glossary.md` を作り直す | 変える | +| 用語集(`docs/glossary/glossary.json`) | DinD・文書の除外の意味を直し、展開後の大きさを `image-lineage` に新しく載せ(意味は用語の表の文のまま)、`glossary.py render` で `docs/glossary.md` を作り直す | 変える | | `CHANGELOG.md` の `[Unreleased]` | 外した中身と、DinD の廃止(破壊的変更・ホストの docker.sock を使う)を書く | 変える | ```mermaid @@ -156,12 +158,12 @@ tests/containers/ ```mermaid graph TD F[FROM ubuntu:26.04] --> C1["COPY dpkg-excludes
/etc/dpkg/dpkg.cfg.d/excludes-devbase"] - C1 --> R1["RUN apt の層
docker-ce-cli・buildx・compose を入れる
FROM の層の changelog・info を消す"] + C1 --> R1["RUN apt の層
docker-ce-cli・buildx・compose を入れる
doc の copyright でない物と info を消す"] R1 --> R2[RUN 利用者とグループ] R2 --> R3["RUN root の道具
aws・gcloud・npm(aws-cdk-lib なし)
root の uv なし"] R3 --> P["ENV PATH
/opt/google-cloud-sdk/bin を足す"] P --> R4[RUN bao・確認] - R4 --> R5["USER ubuntu の RUN
uv・claude・agy・kiro・playwright
片付けで apt の一覧も消す"] + R4 --> R5["USER ubuntu の RUN
uv・claude・agy・kiro・playwright
片付けで apt の一覧と doc の copyright でない物も消す"] R5 --> R6[設定の COPY と fc-cache] R6 --> C2[COPY entrypoint.sh] ``` @@ -240,13 +242,13 @@ graph LR | 71 | `docker-ce`・`containerd.io` | #400(`docker-ce-cli` は残す) | | 73 | `terraform` | #402 | | 73 | `$BROWSER_PKG` | #401 | -| 75〜76 の後 | `FROM` の層の changelog・info の削除 | #400 | +| 75〜76 の後 | `/usr/share/doc` の下の copyright でないファイルと symlink・`/usr/share/info` の中身の削除 | #400 | | 84〜89・111〜113・247〜251・259 | lfm を前提にした注記と `NPM_GID` | #403(先に入る。#400 は触らない) | | 155〜156 | root の uv | #400 | | 159 | `aws-cdk-lib` | #400 | | 177 | `/root/.local/bin` | #400 | | 234〜235 | Playwright の Chromium と `--with-deps` | #402 | -| 236〜245 | 片付け(`/var/lib/apt/lists/*` を足す) | #400。注記の `--with-deps` の語は #402 | +| 236〜245 | 片付け(`/var/lib/apt/lists/*` と `/usr/share/doc` の下の copyright でない物の削除を足す) | #400。注記の `--with-deps` の語は #402 | | 304〜308 | `fc-cache` の注記 | #402 | | 310〜312 | `dind` の `COPY` | #400 | @@ -300,8 +302,15 @@ dockerd を入れた新しい派生へ DinD を移す形は採らない。移す ファイルで doc を外し直し、copyright だけを入れ直せば changelog が外れる。 同じファイルで `/usr/share/info/*`・`/usr/share/man/*`・`/usr/include/node/*` を外す。ファイルは -`containers/base/dpkg-excludes` に置き、最初の `RUN` の前に `COPY` する。`FROM` の層に既にある changelog と info は、 -最初の `RUN` の中で消す。層の大きさは減らないが、受け入れ条件 5 の「copyright のほかのファイルが無い」を満たす。 +`containers/base/dpkg-excludes` に置き、最初の `RUN` の前に `COPY` する。 + +dpkg の規則だけでは受け入れ条件 5 の「copyright のほかのファイルが無い」を満たせない。今の base には changelog のほかに +`NEWS.Debian.gz`・`README`・`examples/*` などのファイルと、別のパッケージの置き場を指す symlink(`libgcc-s1` など)が +40 個残る(根拠の表の実測)。そのため最初の `RUN` の最後と利用者の層の片付けの両方で、 +`find /usr/share/doc -mindepth 1 ! -type d ! -name copyright -delete` を実行し、`/usr/share/doc` の下の copyright でない +ファイルと symlink をすべて消す(`! -type d` は symlink も含み、指す先をたどらない)。最初の `RUN` では +`/usr/share/info` の中身も消す。利用者の層で消すのは、`playwright install --with-deps` の `apt-get` が入れる物を +同じ規則で片付けるためである。`FROM` の層にある分は層の大きさが減らないが、条件 5 を満たす。 翻訳(`/usr/share/locale`)は外さない。`.mo` は Ubuntu が既に外しており、残る `locale.alias` は glibc が読む。 @@ -362,10 +371,11 @@ root の uv を外すと `/root/.local/bin` に入る物が無くなる。`PATH` | I3(受け入れ条件 2・3) | uv のインストーラを呼ぶ `RUN` が `USER ubuntu` の後にだけあり、`ENV PATH` に `/root/.local/bin` が無い | root の `RUN` に uv のインストーラを戻す・利用者の `RUN` から消す・`PATH` に戻すと落ちる | | I4(受け入れ条件 4) | cache mount の無い apt の一覧の取得を持つ `RUN` は、同じ `RUN` で `/var/lib/apt/lists` を消す | 利用者の層の片付けから一覧を外すと、その `RUN` を挙げて落ちる。`--with-deps` を消した Dockerfile では当たる `RUN` が無く通る | | I5(受け入れ条件 5) | 文書の除外の設定が `excludes` より後に並ぶ名前で、最初の `RUN` より前に置かれ、doc の除外の後に copyright の取り込みがあり、changelog・info・man・`/usr/include/node` を外す | 名前を `devbase-excludes`(`excludes` より前)にする・`COPY` を最初の `RUN` の後へ動かす・copyright の取り込みを消す・`/usr/include/node` の行を消すと落ちる | +| I5(受け入れ条件 5・残る文書の削除) | 最初の `RUN` と利用者の層の `RUN` は、どちらも `/usr/share/doc` の下の copyright でないファイルと symlink を消す(`find /usr/share/doc` に `! -type d` と `! -name copyright` と `-delete` がある) | どちらかの `RUN` から削除を消す・`! -name copyright` を外す・`! -type d` を `-type f` に変える(symlink が残る)と、その `RUN` を挙げて落ちる | | I6(受け入れ条件 11) | `containers/base/dind` が無く、Dockerfile に `/usr/local/bin/dind` が無い | `dind` を戻す・`COPY` を戻すと落ちる | | I7(受け入れ条件 9) | `ENABLE_DIND` が `true`・`1` のとき、DinD の知らせが 1 行だけ出て 0 で返り、`sudo`・`dockerd`・`docker`・`rm` を呼ばない | 知らせの後に `docker info` を待つ・docker.sock を消す・dockerd を起こす・0 以外で返るように壊すと落ちる | | I8(受け入れ条件 10) | `ENABLE_DIND` が無い・`false`・空のとき、何も出さずに 0 で返る。既存の entrypoint の試験が変わらず通る | 未設定でも知らせを出すように壊すと落ちる | -| 受け入れ条件 1〜5(建てた base) | arm64 と amd64 で建てた base で `command -v dockerd`・`command -v containerd` が失敗し、`docker --version` などの 5 つが 0 で終わり、`npm ls -g aws-cdk-lib` が空で、`/var/lib/apt/lists`・`/usr/share/man`・`/usr/include/node`・`/usr/share/doc` が条件どおりである | 手動確認(マージ前)。出力を PR に記録する | +| 受け入れ条件 1〜5(建てた base) | arm64 と amd64 で建てた base で、ubuntu の利用者のログインシェル(`docker run --rm --entrypoint bash devbase-base:latest -lc '<コマンド>'`)で確かめる。`/home/ubuntu/.local/bin` は `ENV PATH` に無く `~/.profile` が足すため、`-lc` でない `bash -c` では変更の前後どちらでも `uv` が見つからない。`ENV PATH` に足して通すと受け入れ条件 14 を破る。`command -v dockerd`・`command -v containerd` が失敗し、`docker --version` などの 5 つが 0 で終わり、`npm ls -g aws-cdk-lib` が空で、`/var/lib/apt/lists`・`/usr/share/man`・`/usr/include/node`・`/usr/share/doc` が条件どおりである(`find /usr/share/doc ! -type d ! -name copyright` が 0 件) | 手動確認(マージ前)。出力を PR に記録する | | 受け入れ条件 6 | 前提 8 の形で前後の展開後の大きさの差が 450,000,000 バイト以上 | 手動確認。届かなければ内訳を PR に書いて人へ戻す | | 受け入れ条件 8 | 変更後の base から派生 7 つが建つ | 手動確認。建たなければ外した物を前提にした手順を直す | | 受け入れ条件 9(建てた base) | `ENABLE_DIND=true` で起こしたコンテナの起動の出力に知らせが 1 行あり、完了の印ができる | 手動確認。出力を PR に記録する | From 718106eae96fa2ff9aea024925cba194fb73cc26 Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Sat, 3 Oct 2026 11:05:56 +0900 Subject: [PATCH 5/5] =?UTF-8?q?docs:=20#400=20=E3=81=AE=E6=96=87=E6=9B=B8?= =?UTF-8?q?=E3=81=AE=E5=89=8A=E9=99=A4=E3=82=92=E5=88=A9=E7=94=A8=E8=80=85?= =?UTF-8?q?=E3=81=AE=E5=B1=A4=E3=81=A7=20sudo=20=E3=81=AB=E3=81=97?= =?UTF-8?q?=E3=80=81=E3=83=87=E3=82=A3=E3=83=AC=E3=82=AF=E3=83=88=E3=83=AA?= =?UTF-8?q?=E3=82=92=E6=8C=87=E3=81=99=20symlink=20=E3=82=92=E6=AE=8B?= =?UTF-8?q?=E3=81=99=EF=BC=88#400=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- issues/issue-400-design.md | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/issues/issue-400-design.md b/issues/issue-400-design.md index 1adda1ce..a0260ce9 100644 --- a/issues/issue-400-design.md +++ b/issues/issue-400-design.md @@ -17,7 +17,7 @@ | 根拠 | 種類 | 何を示すか | | --- | --- | --- | | `docker run --rm --entrypoint bash devbase-base:latest` で測った値(2026-10-03・arm64): `/usr/include/node` 67MB・`/usr/share/doc` 8.0MB・`/usr/share/info` 940KB・`/var/lib/apt/lists` 42MB・グローバルの `aws-cdk-lib` 181MB | 実測 | 外す中身の大きさ。docker-ce 106MB・containerd 81MB・root の uv 40MB は課題の本文の実測 | -| 同じコンテナの `/etc/dpkg/dpkg.cfg.d/excludes` が既に `man`・翻訳の `.mo`・`doc`(copyright と changelog を除く)を外している。`/usr/share/man` の下のファイルは 0。`/usr/share/doc` には copyright と `changelog*` のほかに 40 個のファイルと symlink が残る(`apt/NEWS.Debian.gz`・`gnupg/TODO`・`gnupg/examples/*`・`base-files/FAQ`・`libavahi-common3/README`・`python3/README.Debian`・`fonts-dejavu-core/*` などのファイルと、`libgcc-s1`・`libpython3.14` などの symlink)(2026-10-03・arm64 で `find /usr/share/doc ! -type d ! -name copyright ! -name 'changelog*'` を数えた) | 実測 | 文書の除外で足すのは changelog・info・`/usr/include/node` の 3 つ。dpkg の規則だけでは既に残る物が消えないため、最初の `RUN` と利用者の層で `/usr/share/doc` の下の copyright でないファイルと symlink を消す(決定 4) | +| 同じコンテナの `/etc/dpkg/dpkg.cfg.d/excludes` が既に `man`・翻訳の `.mo`・`doc`(copyright と changelog を除く)を外している。`/usr/share/man` の下のファイルは 0。`/usr/share/doc` には copyright と `changelog*` のほかに 40 個のファイルと symlink が残る(`apt/NEWS.Debian.gz`・`gnupg/TODO`・`gnupg/examples/*`・`base-files/FAQ`・`libavahi-common3/README`・`python3/README.Debian`・`fonts-dejavu-core/*` などのファイルと、`libgcc-s1`・`libpython3.14` などの symlink)(2026-10-03・arm64 で `find /usr/share/doc ! -type d ! -name copyright ! -name 'changelog*'` を数えた) | 実測 | 文書の除外で足すのは changelog・info・`/usr/include/node` の 3 つ。dpkg の規則だけでは既に残る物が消えないため、最初の `RUN` と利用者の層で `/usr/share/doc` の下の copyright でないファイルと、ディレクトリを指さない symlink を消す(ディレクトリを指す symlink は copyright への経路なので残す。決定 4) | | `grep -rIl ENABLE_DIND` を `repos/*/`・`projects/*/` の compose.yml・env・.env にかけて 0 件。当たった compose の注記 1 件はホストの dockerd を指す | 実測 | `ENABLE_DIND` を設定する者がいない | | #403 の本文: lfm を使うプロジェクトは無く、利用者が 2026-10-03 に lfm の廃止を決めた。Dockerfile を読む試験の部品(`Instruction` / `parse`)をテストの共通の置き場へ移す | 利用者の指示 | DinD を前提に作られた唯一の派生が無くなる。#400 の試験は移した先の部品を使える | | #400 への利用者のコメント(2026-10-03): lfm は #403 で先に廃止する。lfm への影響は考えなくてよい | 利用者の指示 | #400 は lfm のファイル・試験・仕様が無い状態から始める | @@ -53,7 +53,7 @@ base が dockerd を入れなくなるため、entrypoint は dockerd を起こ | I2 | base の中身 | npm のグローバルに `aws-cdk-lib` を入れず、`aws-cdk` を入れる | 同上 | | I3 | base の中身 | uv のインストーラを呼ぶのは `USER ubuntu` の後の `RUN` だけで、`ENV PATH` に `/root/.local/bin` が無い | 同上 | | I4 | base の中身 | apt の一覧を取得する `RUN`(`apt-get update` か `--with-deps` を含み、`/var/lib/apt` を cache mount しないもの)は、同じ `RUN` で `/var/lib/apt/lists` を消す | 同上。どの `RUN` かを挙げて落ちる | -| I5 | base の中身 | 文書の除外の設定が、最初の `RUN` より前に Ubuntu の `excludes` より後に読まれる名前で置かれ、copyright を残して changelog・info・man・`/usr/include/node` を外す。最初の `RUN` と利用者の層の `RUN` は、`/usr/share/doc` の下の copyright でないファイルと symlink を消す | 同上 | +| I5 | base の中身 | 文書の除外の設定が、最初の `RUN` より前に Ubuntu の `excludes` より後に読まれる名前で置かれ、copyright を残して changelog・info・man・`/usr/include/node` を外す。最初の `RUN` と利用者の層の `RUN` は、`/usr/share/doc` の下の copyright でないファイルと、ディレクトリを指さない symlink を消す(利用者の層は `sudo` で消す)。ディレクトリを指す symlink は残し、`/usr/share/doc/<パッケージ>/copyright` の経路を保つ | 同上 | | I6 | base の中身 | `containers/base/dind` が無く、Dockerfile は `/usr/local/bin/dind` を置かない | 同上 | | I7 | 起動の用意 | `ENABLE_DIND` が `true` か `1` のとき、DinD の廃止を 1 行出して起動を続ける。dockerd を起こさず、`/var/run/docker.sock` を消さず、`docker info` を待たない | 実装の誤り。entrypoint の試験で落とす | | I8 | 起動の用意 | `ENABLE_DIND` が無い・`true` と `1` 以外のとき、何も出さず、起動の手順と順序は変わらない | 同上 | @@ -99,10 +99,10 @@ base が dockerd を入れなくなるため、entrypoint は dockerd を起こ | 要素 | 責務 | 変更 | | --- | --- | --- | | 文書の除外の設定(`containers/base/dpkg-excludes`、新規) | `/etc/dpkg/dpkg.cfg.d/excludes-devbase` として置かれ、Ubuntu の `excludes` の後に読まれて changelog・info・man・`/usr/include/node` を外し、copyright を残す(決定 4) | 作る | -| base の Dockerfile の apt の層(最初の `RUN`) | 文書の除外の設定を `COPY` で先に置き、`docker-ce`・`containerd.io` を一覧から外す。同じ `RUN` の最後で `/usr/share/doc` の下の copyright でないファイルと symlink(changelog を含む)と `/usr/share/info` の中身を消す(決定 4) | 変える | +| base の Dockerfile の apt の層(最初の `RUN`) | 文書の除外の設定を `COPY` で先に置き、`docker-ce`・`containerd.io` を一覧から外す。同じ `RUN` の最後で `/usr/share/doc` の下の copyright でないファイルとディレクトリを指さない symlink(changelog を含む)と `/usr/share/info` の中身を消す。ディレクトリを指す symlink は残す(決定 4) | 変える | | base の Dockerfile の root の道具の層(2 つ目の大きな `RUN`) | root の uv のインストーラの呼び出しと、npm の `aws-cdk-lib` を外す | 変える | | base の Dockerfile の `ENV PATH` | `/root/.local/bin` を外す(決定 6) | 変える | -| base の Dockerfile の利用者の層 | 片付けに `/var/lib/apt/lists/*` を足す(決定 7)。同じ片付けで `/usr/share/doc` の下の copyright でないファイルと symlink を消す(決定 4) | 変える | +| base の Dockerfile の利用者の層 | 片付けに `/var/lib/apt/lists/*` を足す(決定 7)。同じ片付けで `/usr/share/doc` の下の copyright でないファイルとディレクトリを指さない symlink を `sudo find` で消す。`USER ubuntu` の下で動き、apt が root 所有で作る物は `sudo` なしでは消せず `set -e` でビルドが止まるため(決定 4) | 変える | | base の Dockerfile の最後の `COPY` | `dind` の `COPY` を外し、`entrypoint.sh` だけを置く | 変える | | `containers/base/dind` | — | 消す | | entrypoint の DinD の知らせ(`devbase_notice_dind_removed`、新規) | `ENABLE_DIND` が `true` か `1` なら廃止を 1 行出して 0 で返る。それ以外は何も出さずに 0 で返る。`DEVBASE_ENTRYPOINT_LIB_ONLY` で source した試験から呼べる(決定 2) | 作る | @@ -242,13 +242,13 @@ graph LR | 71 | `docker-ce`・`containerd.io` | #400(`docker-ce-cli` は残す) | | 73 | `terraform` | #402 | | 73 | `$BROWSER_PKG` | #401 | -| 75〜76 の後 | `/usr/share/doc` の下の copyright でないファイルと symlink・`/usr/share/info` の中身の削除 | #400 | +| 75〜76 の後 | `/usr/share/doc` の下の copyright でないファイルとディレクトリを指さない symlink・`/usr/share/info` の中身の削除 | #400 | | 84〜89・111〜113・247〜251・259 | lfm を前提にした注記と `NPM_GID` | #403(先に入る。#400 は触らない) | | 155〜156 | root の uv | #400 | | 159 | `aws-cdk-lib` | #400 | | 177 | `/root/.local/bin` | #400 | | 234〜235 | Playwright の Chromium と `--with-deps` | #402 | -| 236〜245 | 片付け(`/var/lib/apt/lists/*` と `/usr/share/doc` の下の copyright でない物の削除を足す) | #400。注記の `--with-deps` の語は #402 | +| 236〜245 | 片付け(`/var/lib/apt/lists/*` と `/usr/share/doc` の下の copyright でない物の削除を足す。どちらも `sudo` で消す) | #400。注記の `--with-deps` の語は #402 | | 304〜308 | `fc-cache` の注記 | #402 | | 310〜312 | `dind` の `COPY` | #400 | @@ -307,9 +307,14 @@ dockerd を入れた新しい派生へ DinD を移す形は採らない。移す dpkg の規則だけでは受け入れ条件 5 の「copyright のほかのファイルが無い」を満たせない。今の base には changelog のほかに `NEWS.Debian.gz`・`README`・`examples/*` などのファイルと、別のパッケージの置き場を指す symlink(`libgcc-s1` など)が 40 個残る(根拠の表の実測)。そのため最初の `RUN` の最後と利用者の層の片付けの両方で、 -`find /usr/share/doc -mindepth 1 ! -type d ! -name copyright -delete` を実行し、`/usr/share/doc` の下の copyright でない -ファイルと symlink をすべて消す(`! -type d` は symlink も含み、指す先をたどらない)。最初の `RUN` では -`/usr/share/info` の中身も消す。利用者の層で消すのは、`playwright install --with-deps` の `apt-get` が入れる物を +`find /usr/share/doc -mindepth 1 ! -type d ! -xtype d ! -name copyright -delete` を実行し、`/usr/share/doc` の下の +copyright でないファイルと、ディレクトリを指さない symlink(指す先の無い物を含む)を消す。`! -type d` は symlink を +含み、`! -xtype d` は指す先がディレクトリの symlink を外す。`libgcc-s1` などのディレクトリを指す symlink は、 +条件 5 が残すと定める `/usr/share/doc/<パッケージ>/copyright` への経路なので消さない(指す先のディレクトリの copyright は +同じ削除で残る)。利用者の層は `USER ubuntu` の下の `set -eux` の `RUN` で動き、`/usr/share/doc` は apt が root 所有で +作るため、`sudo find /usr/share/doc ...` で消す(同じ層の `rm` が `sudo rm -rf` なのと同じ理由。`sudo` が無いと +Permission denied で `find` が 0 でなく終わり、ビルドが止まる)。最初の `RUN` は root で動くので `sudo` を付けない。 +最初の `RUN` では `/usr/share/info` の中身も消す。利用者の層で消すのは、`playwright install --with-deps` の `apt-get` が入れる物を 同じ規則で片付けるためである。`FROM` の層にある分は層の大きさが減らないが、条件 5 を満たす。 翻訳(`/usr/share/locale`)は外さない。`.mo` は Ubuntu が既に外しており、残る `locale.alias` は glibc が読む。 @@ -371,11 +376,11 @@ root の uv を外すと `/root/.local/bin` に入る物が無くなる。`PATH` | I3(受け入れ条件 2・3) | uv のインストーラを呼ぶ `RUN` が `USER ubuntu` の後にだけあり、`ENV PATH` に `/root/.local/bin` が無い | root の `RUN` に uv のインストーラを戻す・利用者の `RUN` から消す・`PATH` に戻すと落ちる | | I4(受け入れ条件 4) | cache mount の無い apt の一覧の取得を持つ `RUN` は、同じ `RUN` で `/var/lib/apt/lists` を消す | 利用者の層の片付けから一覧を外すと、その `RUN` を挙げて落ちる。`--with-deps` を消した Dockerfile では当たる `RUN` が無く通る | | I5(受け入れ条件 5) | 文書の除外の設定が `excludes` より後に並ぶ名前で、最初の `RUN` より前に置かれ、doc の除外の後に copyright の取り込みがあり、changelog・info・man・`/usr/include/node` を外す | 名前を `devbase-excludes`(`excludes` より前)にする・`COPY` を最初の `RUN` の後へ動かす・copyright の取り込みを消す・`/usr/include/node` の行を消すと落ちる | -| I5(受け入れ条件 5・残る文書の削除) | 最初の `RUN` と利用者の層の `RUN` は、どちらも `/usr/share/doc` の下の copyright でないファイルと symlink を消す(`find /usr/share/doc` に `! -type d` と `! -name copyright` と `-delete` がある) | どちらかの `RUN` から削除を消す・`! -name copyright` を外す・`! -type d` を `-type f` に変える(symlink が残る)と、その `RUN` を挙げて落ちる | +| I5(受け入れ条件 5・残る文書の削除) | 最初の `RUN` と利用者の層の `RUN` は、どちらも `/usr/share/doc` の下の copyright でないファイルとディレクトリを指さない symlink を消す(`find /usr/share/doc` に `! -type d` と `! -xtype d` と `! -name copyright` と `-delete` がある)。利用者の層の `RUN` ではその `find` が `sudo find` である | どちらかの `RUN` から削除を消す・`! -name copyright` を外す・`! -type d` を `-type f` に変える(symlink が残る)・`! -xtype d` を外す(ディレクトリを指す symlink が消え copyright への経路が失われる)・利用者の層の `sudo` を外すと、その `RUN` を挙げて落ちる | | I6(受け入れ条件 11) | `containers/base/dind` が無く、Dockerfile に `/usr/local/bin/dind` が無い | `dind` を戻す・`COPY` を戻すと落ちる | | I7(受け入れ条件 9) | `ENABLE_DIND` が `true`・`1` のとき、DinD の知らせが 1 行だけ出て 0 で返り、`sudo`・`dockerd`・`docker`・`rm` を呼ばない | 知らせの後に `docker info` を待つ・docker.sock を消す・dockerd を起こす・0 以外で返るように壊すと落ちる | | I8(受け入れ条件 10) | `ENABLE_DIND` が無い・`false`・空のとき、何も出さずに 0 で返る。既存の entrypoint の試験が変わらず通る | 未設定でも知らせを出すように壊すと落ちる | -| 受け入れ条件 1〜5(建てた base) | arm64 と amd64 で建てた base で、ubuntu の利用者のログインシェル(`docker run --rm --entrypoint bash devbase-base:latest -lc '<コマンド>'`)で確かめる。`/home/ubuntu/.local/bin` は `ENV PATH` に無く `~/.profile` が足すため、`-lc` でない `bash -c` では変更の前後どちらでも `uv` が見つからない。`ENV PATH` に足して通すと受け入れ条件 14 を破る。`command -v dockerd`・`command -v containerd` が失敗し、`docker --version` などの 5 つが 0 で終わり、`npm ls -g aws-cdk-lib` が空で、`/var/lib/apt/lists`・`/usr/share/man`・`/usr/include/node`・`/usr/share/doc` が条件どおりである(`find /usr/share/doc ! -type d ! -name copyright` が 0 件) | 手動確認(マージ前)。出力を PR に記録する | +| 受け入れ条件 1〜5(建てた base) | arm64 と amd64 で建てた base で、ubuntu の利用者のログインシェル(`docker run --rm --entrypoint bash devbase-base:latest -lc '<コマンド>'`)で確かめる。`/home/ubuntu/.local/bin` は `ENV PATH` に無く `~/.profile` が足すため、`-lc` でない `bash -c` では変更の前後どちらでも `uv` が見つからない。`ENV PATH` に足して通すと受け入れ条件 14 を破る。`command -v dockerd`・`command -v containerd` が失敗し、`docker --version` などの 5 つが 0 で終わり、`npm ls -g aws-cdk-lib` が空で、`/var/lib/apt/lists`・`/usr/share/man`・`/usr/include/node`・`/usr/share/doc` が条件どおりである(`find /usr/share/doc ! -type d ! -xtype d ! -name copyright` が 0 件で、`dpkg-query -W -f '${Package}\n'` の各パッケージのうち元の base で `/usr/share/doc/<パッケージ>/copyright` を読めた物が、変更後も読める。`libgcc-s1` などの symlink の先を含む) | 手動確認(マージ前)。出力を PR に記録する | | 受け入れ条件 6 | 前提 8 の形で前後の展開後の大きさの差が 450,000,000 バイト以上 | 手動確認。届かなければ内訳を PR に書いて人へ戻す | | 受け入れ条件 8 | 変更後の base から派生 7 つが建つ | 手動確認。建たなければ外した物を前提にした手順を直す | | 受け入れ条件 9(建てた base) | `ENABLE_DIND=true` で起こしたコンテナの起動の出力に知らせが 1 行あり、完了の印ができる | 手動確認。出力を PR に記録する |