Skip to content

feat: Compose の profiles で、dev に触れずに付随サービス群を後から起動・停止できるようにする #189

Closed

Description

@takemi-ohama

何をしたいか

dev のほかに app / db などのサービスを抱えるプロジェクトで、次の 2 つを両立させたい。

  1. devbase up の既定では dev コンテナだけ を起動する
  2. テスト用のサービス群は 後から起動・停止できる。そのとき dev コンテナは再作成も再起動もされない

Compose の profiles を使えば、プロジェクト側の compose.yml はほぼ書き換えるだけで済みます。ただし devbase が profiles を前提にしていないため、プロジェクト側だけでは片付かない穴が 3 つあります(下の「devbase 側で起きること」)。この issue ではその穴を塞ぎ、後から起動・停止するコマンドを devbase に用意します。

想定するプロジェクト側の書き方

services:
  dev:
    # dev から app への依存は外すか required: false にする
    depends_on:
      app:
        condition: service_started
        required: false
  app:
    profiles: [test]
    depends_on:
      mysql:
        condition: service_healthy
  mysql:
    profiles: [test]

required: false を付けないと、既定の up は service "dev" depends on undefined service "app": invalid compose project で止まります(下の検証 1)。

devbase 側で起きること

Docker Compose v5.1.4 で、profiles 付きの最小構成(dev / app / mysql、いずれも alpine:3)を作って確かめました。

# 操作 結果 devbase への影響
1 required: false なしで docker compose up -d invalid compose project で失敗 プロジェクト側で書けば済む(ドキュメントで案内)
2 --profile test up -d の後に、profile なしで docker compose down dev だけ消え、app / mysql は 動いたまま。network が Resource is still in use で消せず rc=1 devbase down と、devbase up 冒頭の停止(_previous_scale_compose → docker_compose_down)でテスト用サービスが孤児になる。rc=1 は警告に丸められて気づけない
3 docker compose --profile test up -d app mysql / stop app mysql / down app mysql dev の稼働は続く(再作成も再起動もされない) 後から起動・停止する操作は サービス名を明示すれば dev に触れずに済む
4 profile なしで docker compose ps 動いている app も表示される devbase ps はそのままでよい
5 docker compose --profile '*' down 全サービスが消える 停止時はこれを使えばよい

もう 1 点、検証 3 で サービス名を省いて --profile test up -d とすると、dev も reconcile の対象になります。devbase は機密を名前だけ(- GH_TOKEN など)で .docker-compose.scale.yml に書き、値は _inject_secrets が実行時の環境へ載せます。素の docker compose を手で叩くと値が空のまま構成のハッシュが変わり、dev が再作成されうるので、後から起動する操作も devbase を通して機密を注入した状態で、対象サービスを明示して呼ぶ必要があります。

イメージの確認にも影響があります。_ensure_images / _resolve_dev_service は profile なしの docker compose config を読むので、テスト用サービスのイメージは devbase up の時点ではビルドされません。これは狙いどおりの挙動ですが、後から起動するときにビルドが走る(初回は時間がかかる)ことを案内に書く必要があります。

やること(案)

1. 停止を全 profile に効かせる

  • docker_compose_down を --profile '*' 付きで呼ぶ(devbase down と devbase up 冒頭の停止の両方)
  • devbase up の冒頭停止でテスト用サービスまで止めてよいかは要判断。止めない場合は「dev-N だけ down → up」に変える必要があり、network の扱いが絡む

2. 後から起動・停止するコマンド

名前は仮です。top-level の位置引数はプロジェクト名に吸われるので、container / project のサブコマンドとして生やす。

devbase container profile up <profile>     # そのプロファイルのサービスを起動
devbase container profile down <profile>   # 停止して削除(dev は残す)
devbase container profile list             # compose.yml に書かれたプロファイルと稼働状況
devbase project profile up <name> <profile>  # CWD 非依存版

実装の骨子:

  1. _prepare_compose で context 反映と機密注入を済ませる
  2. 対象サービスを docker compose --profile <p> config --services と profile なしの config --services の差で求める
  3. docker compose -f .docker-compose.scale.yml --profile <p> up -d <services...>(停止は down <services...>)
  4. 起動後にプロジェクトのフックを呼ぶ(下の 3)

.docker-compose.scale.yml が無い(devbase up 前)ときはエラーにして devbase up を促す。

3. フックへ「どのプロファイルが立っているか」を渡す

既存の ./deploy はインスタンスごとに呼ばれ、テスト用サービスが立っている前提で DB 初期化などを行うプロジェクトがあります。既定で立たなくなると、deploy が app の healthy を待ち続けて timeout で up ごと失敗します。

  • hook_env に DEVBASE_ACTIVE_PROFILES(カンマ区切り、無ければ空)を足す
  • profile up の後にフックを呼ぶ。新しいフック名(例: ./post-profile-up)にするか、./deploy を DEVBASE_ACTIVE_PROFILES 付きで呼び直すかは設計で決める

4. 既定で立てるプロファイルを project.yml で選べるようにする(任意)

「うちは全部立てたい」プロジェクトのために、次のような指定を受ける。

compose:
  profiles: [test]   # devbase up で既定で有効にするプロファイル

5. ドキュメント

  • プロジェクト作者向けに、profiles の付け方と depends_on.required: false の必要性
  • 素の docker compose で起動すると dev が再作成されうるので devbase を通すこと

受け入れ条件

  • profiles を付けたサービスは devbase up で起動しない
  • devbase container profile up <p> で対象サービスだけが起動し、dev-N の Container ID と起動時刻が変わらない
  • devbase container profile down <p> で対象サービスだけが消え、dev-N の Container ID と起動時刻が変わらない
  • devbase down でテスト用サービスを含む全サービスと network が消える(rc=0)
  • profile up の後にフックが DEVBASE_ACTIVE_PROFILES 付きで呼ばれる
  • profiles を使っていない既存プロジェクトの up / down / scale の挙動が変わらない(テストで固定)

範囲外

  • scale 時にテスト用サービスをインスタンスごとに複製すること(現状どおり 1 組を共有)

進行

モード: standard / 作業ツリー: .worktrees/feat/issue-189 / 計画: issues/PLAN58_compose-profiles-impl.md

  • 要求と受け入れ条件 — 2026-09-16 11:09
  • 作業場所の用意 — 2026-09-16 11:09
  • 設計 — 2026-09-16 11:09
  • 素材の収集と出典の確定
  • ドキュメント再構成 — 2026-09-16 11:13
  • ドキュメントレビュー — 2026-09-16 11:15
  • 計画 — 2026-09-17 05:28
  • 実装 — 2026-09-17 05:30
  • 構造改善 — 2026-09-17 05:48
  • 実装レビュー — 2026-09-17 06:19
  • 完了判定 — 2026-09-17 07:29
  • Pull Request — 2026-09-17 07:31
  • 確定仕様化 — 2026-09-17 09:14
  • 後片付け — 2026-09-17 05:28
  • 配布 — 2026-09-17 09:23
  • 体裁レビュー
  • リリース後テスト — 2026-09-17 09:28
  • 振り返り — 2026-09-17 09:30

振り返り: #189 (comment)

Activity

  1. added 14 commits that reference this issue on Sep 16, 2026
  2. 3 remaining items

  3. takemi-ohama commented on Sep 17, 2026

    @takemi-ohama
    ContributorAuthor

    振り返り(2026-09-17)

    対象: issue #189 / 設計 PR #190 / 実装 PR #191 / 確定仕様 PR #193 / 配布 v3.5.0(PR #194)

    compose.yml の profiles を付けた付随サービス群を、dev コンテナに触れずに後から起動・停止する devbase project profile up|down|list と、devbase list の操作メニューの 2 項目を追加した。あわせて devbase up / down の停止を全プロファイルへ効かせ、devbase 経由の Compose で COMPOSE_PROFILES を無効にした。

    何が起きたか

    観点 事実
    受け入れ条件 変更なし。実装中に範囲へ 1 件入れた: TUI の _preserve_cwd_env() が機密の注入履歴を戻さず、別プロジェクトを続けて操作すると前のプロジェクト固有の機密が次の compose へ渡る欠陥(PR 前からの経路にもあった)。原因と形が同じため同じ PR で直した
    手戻り 実装レビューは 4 ラウンド、修正 5 件(major 4 / minor 1)、却下 1 件(Compose v2.13 未満の挙動。最低対応版 2.20.0 の範囲外)。major のうち 2 件は設計に無かった観点だった: devbase up で起動対象の解決(config --services)を停止の後に置いていた順序、TUI からの解決が対象プロジェクトの env と機密を載せていなかったこと
    見落とし round 1(agy + kiro)は収束と判定されたが codex が未参加だった。手で回した round 2〜3 で codex が上の順序の問題と機密の持ち越しを出した
    構造改善 テスト整備 3 件を適用。構造の提案は --scope がファイル単位のため PR が触れていない cmd_scale へ向き、要求仕様の境界に反するので適用を止めた(#192)。止めた後に同じ群が再起動されたため、ループごと停止した
    リリース後テスト 導入済みの v3.5.0 で 13 件中 10 件を実施し全件合格(devbase up 全経路、profile up/down/list、COMPOSE_PROFILES=test の端末、devbase down、layout: group の実サーバでの注入)。TUI の目視、名前指定での別ディレクトリからの実行、Compose 2.20〜5.x 未満は保留
    工程 飛ばした工程なし。マージ前に実 Docker での確認(21 件)を 2 回(実装直後とレビュー後)行った

    次に変えること

    変えること 落とし先 状態
    cross-review で母集合の 3 者のうち未参加の担当がいる間は収束にしない cross-review の手順 devbasex/ai-plugins#631 に実測を追記(この変更では state の final を戻して手で回した)
    cross-refactoring の提案範囲を PR の差分に絞れるようにする cross-refactoring の手順 devbasex/ai-plugins#622 に実測を追記
    実装担当を止めた群が再試行され続けないようにする cross-refactoring の手順 devbasex/ai-plugins#647 に実測を追記
    TUI から CLI の処理を呼ぶ設計では、対象プロジェクトへの切替(env・機密・注入履歴)と復元境界を設計の観点に入れる 次の変更で試すこと 変えない。今回は実装レビューで拾えており、同種の入口(tui/dispatch.py の委譲)は今回の修正で 1 か所に集まったため、観点を足す先の工程を決める材料がまだ 1 件しかない

    途中で起票した課題

    番号 何を見つけたか 見つけた場面
    #192 cmd_scale の長いメソッドと、_resolve_dev_service / _read_compose_services の config 読み取りの重複 構造改善中
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions