devbase のコンテナ管理機能について、ライフサイクル、並行開発、ボリューム構造、イメージ階層を解説します。
コマンド体系について: コンテナ操作は
devbase project <sub>グループ(および トップレベルショートカットdevbase up等)で行います。旧devbase container <sub>は 非推奨となり、projectへのエイリアスとして警告付きで当面動作します。projectでは[name]を指定することで 任意のディレクトリから 対象プロジェクトを操作できます。[name]を 取るサブコマンドは位置引数の解決の「[name]を受け付けるサブコマンド」 の表を参照してください。プロジェクト一覧はdevbase project listを参照 してください。詳細は CLI リファレンス: project グループ を参照。
devbase のコンテナは以下のライフサイクルで管理されます。
stateDiagram-v2
[*] --> ビルド: devbase build
ビルド --> 停止: イメージ作成完了
停止 --> 起動中: devbase up
起動中 --> 起動中: devbase login
起動中 --> 停止: devbase down
停止 --> 起動中: devbase up
note right of 起動中
up 時にスナップショット自動作成
end note
note right of 停止
down 時にローテーション自動実行
end note
# 1. コンテナイメージをビルド(初回のみ)
devbase build
# 2. コンテナを起動(自動スナップショット作成)
devbase up
# 3. コンテナにログイン
devbase login
# 4. コンテナ内で作業
# ...
# 5. コンテナから退出
exit
# 6. コンテナを停止・削除(自動ローテーション)
devbase downコンテナのライフサイクルに連動して、スナップショットが自動管理されます。
| タイミング | 動作 | 条件 |
|---|---|---|
devbase up |
フルバックアップ or 差分追加 | 起動するアカウントグループの系列の最新の世代へ差分を追加。系列に世代が無いか差分が上限に達していればフルバックアップで新しい世代 |
devbase down |
古い世代のローテーション | グループ(系列)ごとに DEFAULT_MAX_GENERATIONS(3)を超えた世代と、全体の上限(9)を超えた古い世代を削除。各系列の最新の世代は残す |
詳細は スナップショットガイド を参照してください。
devbase は複数のコンテナを同時に起動し、並行開発を行うことができます。
プロジェクトの project.yml で scale を設定します。デフォルト値は 2 です。
version: 1
scale: 2
repos:
- owner: your-org
repo: my-repo起動中のコンテナを再起動せずに、コンテナ数を変更できます。
# コンテナを3台に増やす(既存コンテナは再起動しない)
devbase project scale 3
# コンテナを1台に減らす
devbase project scale 1
# 任意のディレクトリから adminer を3台に
devbase project scale adminer 3コンテナ番号を指定してログインします。
# 1番目のコンテナにログイン
devbase login 1
# 2番目のコンテナにログイン
devbase login 2
# 3番目のコンテナにログイン
devbase login 3graph LR
subgraph ホストマシン
A[ターミナル 1]
B[ターミナル 2]
end
subgraph devbase
C[コンテナ 1<br/>/work 専用]
D[コンテナ 2<br/>/work 専用]
E[共通AI設定<br/>/persistent/ai]
F[グループ別の認証・履歴<br/>/persistent/group]
end
A --> C
B --> D
C --> E
D --> E
C --> F
D --> F
- 各コンテナは独立した
/workボリュームを持つ /persistent/ai(共通の AI 資産・共有ファイル)は全コンテナで共有される/persistent/group(認証情報・会話履歴)は同じアカウントグループのコンテナだけで共有される/home/ubuntu直下のうち永続化されるのは symlink 対象のみ(下記「AI 設定の永続化」参照)- 異なるブランチでの並行作業に便利
devbase のコンテナは 4 種類のボリュームを使用します。
| ボリューム名 | マウント先 | 共有範囲 | 用途 |
|---|---|---|---|
devbase_home_ubuntu |
/persistent/ai |
全コンテナで共有 | 契約やテナントに紐づかない共通資産(~/.claude/plugins / skills / commands / CLAUDE.md / settings.json、.codex / .serena / .kiro、SSH 鍵、共有ファイル置き場 share) |
devbase_home_{group} |
/persistent/group |
同じアカウントグループのコンテナで共有 | 企業テナントに紐づくもの(Claude Code の認証と会話ログ、.gemini、Kiro CLI の .local/share/kiro-cli、gcloud / gws の設定ディレクトリ、作り直しても残るシェルの設定の置き場所 .shellrc.d) |
devbase_work_{index} |
/work |
同じ index のコンテナで共有(プロジェクト間も共有) | プロジェクトのソースコード、作業ファイル |
devbase_vscode-server-bin |
/home/ubuntu/.vscode-server/bin |
全コンテナで共有(プロジェクト・グループを問わず 1 本) | VS Code Server の本体(bin/<commit>)だけ。拡張機能・接続トークン・リモート側の設定は持たない |
Note:
devbase_home_ubuntuは/persistent/aiにマウントされます(/home/ubuntuへの直接マウントは廃止)。/home/ubuntu直下はコンテナ層(揮発)で、永続化されるのは entrypoint が/persistent/ai//persistent/group配下へ symlink する設定ファイルのみです。シェル履歴など symlink 対象外のファイルは再生成で失われます。
devbase_home_{group} の {group} は DEVBASE_ACCOUNT_GROUP で宣言します。
使用する Google / AWS アカウントの単位で、どのプロジェクトも projects/<name>/env での
宣言が必須です(既定の値はありません。宣言が無いと devbase up が止まります)。
# projects/<name>/env
DEVBASE_ACCOUNT_GROUP=globexこれは「acme.example で認証した gcloud を globex.example のプロジェクトが引き継がない」
ようにするための仕切りです。同じグループのコンテナは認証を共有し、違うグループのコンテナは
互いの認証に到達できません。一方で ~/.claude/plugins(238MB)のような共通資産は
/persistent/ai に置かれるため、グループを増やしても重複しません。
いま自分がどのグループにいるかは、プロジェクトのディレクトリで打つ devbase status の
[環境] セクションで確認できます。
[環境]
devbase/.env 42変数 (最終更新: 2026-08-29)
アカウントグループ globex (devbase_home_globex / projects/web/env:1)
末尾は宣言のファイルと行です。プロジェクトの外では「なし(プロジェクトの外)」、宣言の
無いプロジェクトでは (設定エラー) と宣言の書き方が出ます。
グループ名には次のものが使えません。devbase up の前にエラーになります。
| 使えない名前 | 理由 |
|---|---|
^[a-zA-Z0-9][a-zA-Z0-9._-]*$ に合わないもの |
Docker のボリューム名にできない |
ubuntu |
共通ボリューム devbase_home_ubuntu と同名になる |
default |
旧既定のボリューム devbase_home_default と同名になる(予約語) |
数字だけの名前(1 / 042) |
インスタンス番号のボリューム devbase_home_<index> と同名になる |
Google 認証の具体的な手順は Google 認証ガイド を参照してください。
VS Code を attach すると、コンテナ内の ~/.vscode-server に VS Code Server が入ります。
ボリュームに置くのは本体(bin/<commit>、1 版で約 0.6GB)だけで、全コンテナ共通の 1 本
devbase_vscode-server-bin を ~/.vscode-server/bin にマウントします。
本体を共有するのは、版ごとに中身が変わらず、プロジェクトとインスタンスの数だけ同じ版を 重ねて持つ理由が無いためです。どれか 1 つのコンテナで一度取れば、ほかのコンテナの attach は本体を 取り直しません。
| 置き場 | どこにあるか | 消えるとき |
|---|---|---|
bin/(本体) |
共通のボリューム devbase_vscode-server-bin |
コンテナの起動の片付けが古い版を消す(下記) |
extensions/・extensionsCache/・data/ など bin/ 以外 |
コンテナの書き込みレイヤー(ボリュームではない) | devbase up の作り直し(down → up)。docker restart と端末の再起動では残る |
| 拡張のキャッシュと、新しい版の本体(Dev Containers が置く) | Dev Containers の共有の置き場 vscode(/vscode) |
拡張は起動の後の処理が拡張ごとに新しい 3 版を残して消す。本体は Dev Containers が新しい 9 版を残して消す |
dev コンテナには、名前 vscode のボリュームも /vscode に付きます。Dev Containers 拡張は、このボリュームが
付いたコンテナでは拡張のキャッシュをこの中に持ち、VS Code を動かしている手元の端末のキャッシュを使いません。
ボリュームは docker ホストごとにあるので、arm64 の端末(Mac など)で入った拡張が x86_64 のサーバーのコンテナへ
送られることはありません。新しい版の本体も Dev Containers がこの中(/vscode/vscode-server/bin/<build>/<commit>)に置き、
~/.vscode-server/bin/<commit> にはそこへのリンクを張ります。
devbase up でコンテナを作り直すたびに、次のものが消えます。
- 手で入れた拡張機能。Dev Containers の既定の拡張機能は、 作り直しの後の最初の attach で入り直します
- リモート側の設定(
data/Machine/settings.json)のうち、手で入れたもの。window.titleはdevbase upが毎回書き直します - ローカル履歴(
data/User/History)と、拡張機能がリモート側に保存する状態 (data/User/globalStorage・data/User/workspaceStorage。Copilot Chat など) - ログ(
data/logs)。消えるため溜まりません - 接続トークンと
.devport。次のサーバーの起動で作り直されます
bin/ 以外がコンテナごとに分かれているため、窓のタイトルと窓の再接続(ウィンドウの再読み込み)は
コンテナごとに働きます。
VS Code を更新するたびに bin/ へ新しい版が足されます。コンテナの起動(entrypoint)が毎回
bin/ を片付け、次のものを消します。
- 新しい順に 5 版を残し、それより古い版。順は各版の
product.jsonの更新時刻で決めます - 複数の窓が同じ版を同時に展開したときに、版のディレクトリの中に入れ子で残った本体
(
bin/<commit>/vscode-server-linux-<arch>/) - 60 分より前に始まって終わらなかった展開の途中のディレクトリ(
bin/<commit>_<数字>)
消せないものがあっても起動は止まらず、WARNING: VS Code Server の片付けで消せなかった: <パス>
の行が出ます。片付けは base と派生イメージを建て直した後から効きます。それまでは bin/ に
版が溜まりますが、共通の 1 本なので、プロジェクトとインスタンスの数だけ重なりません。
- プロジェクトが
compose.ymlで~/.vscode-serverか~/.vscode-server/binを自分で マウントしている場合、devbase は何も足しません。~/.vscode-server/dataなど下の別のパス だけをマウントしているときは、共通のボリュームをbinに足します - スナップショット(
devbase snapshot)の対象外です。失っても attach し直せば再取得されます - 空のボリュームは root の所有で付きます。コンテナの起動と、
devbase up/scale/project post-startの起動の後の処理が、~/.vscode-server/binを開発ユーザーが書ける形に 揃えます(建て直す前のイメージでも attach できます)
以前の devbase は ~/.vscode-server を丸ごと、コンテナ 1 つに 1 本のボリューム
devbase_vscode_{project}_{index} に置いていました。今の devbase はこれを付けず、中身も
引き継ぎません。移った後の最初の attach で本体(約 215MB、約 55 秒)を取り直し、拡張機能は
入れ直しになります。
以前のボリュームが残っている間、devbase up の最後に名前と消すコマンドが出ます。devbase は
消しません。下の「使わなくなった VS Code Server ボリュームを消す」の手順で消してください。
- ボリュームは
devbase downでもコンテナが削除されても保持されます - コンテナの再起動(
devbase up)で同じボリュームが再マウントされます - ボリュームを明示的に削除するには
docker volume rmを使用します
Warning:
devbase_work_{index}はCOMPOSE_PROJECT_NAMEの接頭辞が付かない external ボリュームです。同じ index(コンテナ 1 ならdevbase_work_1)を使う限り 別プロジェクトからも同じ実体を参照するため、docker volume rm devbase_work_1は停止中の他プロジェクトの作業ファイルまで削除します。削除前にdocker ps -a --filter volume=devbase_work_1で利用コンテナを確認してください。
# Docker ボリュームの一覧
docker volume ls | grep devbase
# 特定ボリュームの詳細
docker volume inspect devbase_home_ubuntu以前の形式の devbase_vscode_{project}_{index} は、今の devbase では使いません。自動では
消えないため、手で削除します。1 本で数 GB を使うことがあります。
# 一覧(共通の devbase_vscode-server-bin は出ない)
docker volume ls --filter name=devbase_vscode_ --format '{{.Name}}'
docker system df -v | grep devbase_vscode_
# 要るデータを退避する(下の注意を参照。カレントディレクトリへ tar で書き出す)
docker run --rm -v devbase_vscode_<project>_1:/from:ro -v "$PWD":/to alpine \
tar czf /to/vscode_<project>_1.tgz -C /from .
# 使用中のコンテナが無いことを確認してから削除する
docker ps -a --filter volume=devbase_vscode_<project>_1
docker volume rm devbase_vscode_<project>_1Warning: 以前の形式のボリュームは
~/.vscode-server全体を持っています。削除すると、 以前の VS Code Server の本体と拡張機能(extensions/)に加え、次のものも戻せなくなります。
- リモートの設定(
data/Machine/settings.json)- ローカル履歴(
data/User/History/)- 拡張機能が保存した状態(
data/User/globalStorage/・data/User/workspaceStorage/)要るものがあれば、削除の前に上の
tarの行で退避してください。戻すときは、展開した中の要る ファイルだけをdocker cpでコンテナの~/.vscode-server/の同じ場所へ写します。AI 設定 (~/.claudeなど)は別のボリュームにあるため、この削除では消えません。
devbase up の案内に出る docker volume rm … の行は、退避が要らないと確かめた後に打ってください。
以前の devbase で作ったコンテナが付けているボリュームは docker volume rm が
拒否します。そのプロジェクトで devbase up を打ってコンテナを作り直した後に消してください。
共通の devbase_vscode-server-bin は消さなくて構いません。消したときは、次の attach で本体を
取り直します。
Warning:
devbase_home_ubuntuボリューム(/persistent/ai、および symlink 経由でアクセスする~/.claude/plugins/~/share等)は全プロジェクトで共有されます。ここにプロジェクト固有のファイルを置くと、他のプロジェクトにも影響します。プロジェクト固有のファイルは/workに配置してください。
AI CLI ツールの設定や認証情報は、コンテナを再生成しても保持されるよう 2 つのボリュームに永続化されます。
仕組みは symlink です。コンテナ起動時、entrypoint(containers/base/entrypoint.sh)が
以下の各エントリについて symlink を作成します。
全コンテナ共通(/persistent/ai)
| エントリ | 内容 |
|---|---|
.codex |
Codex CLI の設定(ChatGPT アカウントで分離済み) |
.serena |
Serena MCP の設定 |
.kiro |
Kiro CLI の設定(AWS 側で分離済み) |
.ssh |
SSH 鍵 |
share |
全コンテナ共有のファイル置き場(任意用途) |
.claude/plugins .claude/skills .claude/commands .claude/CLAUDE.md .claude/settings.json |
Claude Code の共通資産 |
アカウントグループ単位(/persistent/group)
| エントリ | 内容 |
|---|---|
.claude.json |
Claude Code の設定(oauthAccount を含む) |
.claude |
Claude Code の認証・会話ログ・セッション状態(上表の共通資産を除くすべて) |
.gemini |
Gemini CLI と Antigravity CLI の設定(vertex-ai は GCP プロジェクトに紐づく。Antigravity CLI は .gemini/antigravity-cli/ 配下を使う) |
.local/share/kiro-cli |
Kiro CLI 2.x の認証状態・実行データ |
.shellrc.d |
対話シェルが起動時に読む *.sh の置き場所。パスは DEVBASE_SHELLRC_DIR が示す。反映には devbase build base --no-cache が要る(作り直しても残るシェルの設定) |
~/.claude は /persistent/group/.claude への symlink で、その配下の既定はグループ側です。
共通資産だけがその中から /persistent/ai/.claude/<name> へ張り直されます。既定をグループ側に
倒しているのは、Claude Code が projects / sessions / tasks のようなディレクトリを随時作るため、
永続化するものを列挙する方式だと列挙漏れが黙って揮発するからです。
$ readlink -f ~/.claude # グループ側
/persistent/group/.claude
$ readlink -f ~/.claude/plugins # 共通側(どのグループから見ても同じ実体)
/persistent/ai/.claude/plugins/persistent/aiは全コンテナ共通のdevbase_home_ubuntuボリュームなので、どのコンテナからも同じ実体を参照します(例:~/shareは全コンテナで共有)。/persistent/groupはdevbase_home_{group}で、同じアカウントグループのコンテナだけが同じ実体を参照します。- symlink 対象外のホーム配下ファイル(シェル履歴など)はコンテナ層に置かれ、再生成で失われます。永続化したいものは
/persistent/ai//persistent/group配下(= 上記 symlink 先)か/workに置いてください。
~/.claude/settings.json と ~/.claude/CLAUDE.md は共通側を指す symlink です。ツールが「一時ファイルへ書いて
rename する」形で保存すると、symlink そのものがグループ側の通常のファイルに置き換わります。
次の起動で entrypoint がこれを見つけると、中身を共通側の実体と比べます。
-
同じなら、何も残さずに symlink を張り直します
-
違うなら、張り直す前に同じ
.claudeの下へ控えを残します。控えの名前は<名前>.replaced-<UTC の時刻>(例:/persistent/group/.claude/settings.json.replaced-20261002T190116Z)で、中身・所有者・権限は置き換わって いたファイルと同じです。同じ中身の控えが既にあれば、新しい控えは作りません -
控えを残したときは、起動の記録(
docker logs <コンテナ>)に次の行が出ますWARNING: 共有のリンクが通常のファイルに置き換わっていたため、中身を控えに残して張り直す: <控えのパス> -
控えを作れない(書き込めないなど)ときは、ファイルを消さずに残し、そのリンクだけ張り直しません。起動の記録に
WARNING: 共有のリンクが通常のファイルに置き換わっているが、控えに残せないため張り直さずに残す: <パス>が出ます。 書き込めるようになった次の起動で控えを作って張り直します
控えの中身は共通側へ自動では取り込みません。あるグループで書いた設定が確認なしにすべてのグループへ広がらない ようにするためです。戻すかは次の手順で決めます。
docker logs <コンテナ>のWARNING:の行か、ls ~/.claude/*.replaced-*で控えを見つけるdiff ~/.claude/settings.json.replaced-<時刻> ~/.claude/settings.jsonで、控えと今の共通の設定の違いを見る- 残したい違いだけを
~/.claude/settings.jsonへ書く。このパスは共通側を指すため、すべてのグループに効きます。 控えのファイルをmvで~/.claude/settings.jsonの位置へ置かないでください(共通の設定が再び通常のファイルに 置き換わります) - 要らなくなった控えを消す(entrypoint は控えを消しません)
CLAUDE.md の控え(CLAUDE.md.replaced-<時刻>)も同じ手順で戻します。反映には base イメージの建て直しが要ります。
建て直す前のイメージのコンテナは、控えを残さずに消して張り直します。
グループのボリュームへ初めて付けたコンテナでは、/persistent/group の分類 B の設定
(.claude.json / 認証 / 会話ログ / .gemini / gcloud / gws)は空のプレースホルダです。
/persistent/ai からの取り込みは行わないため、新しいグループ(例: personal)では
claude・gh・gcloud などのログインを取り直します。グループの宣言が必須になる前に使っていた
devbase_home_default の中身は、devbase project migrate-volume --to <group> で移します
(default からの移行)。
コンテナは DEVBASE_ACCOUNT_GROUP が渡らないと起動しません(entrypoint がリンクを張る前に
0 でない終了コードで止まります)。devbase up はプロジェクトの宣言の値を必ず渡します。
entrypoint の変更はイメージを作り直すまで効かないため、devbase を更新したら
devbase build --no-cache を打ってください。
起動ログの 1 行で、どのグループとしてどのアカウントで動いているかを確認できます。
Account group: globex (gcloud account: someone@globex.example, CLOUDSDK_CONFIG: /persistent/group/gcloud)
share配下に置いた VS Code ワークスペースファイルはDEVBASE_WORKSPACEで開けます(リポジトリ 1 件の構成のみ。環境変数 参照)。
Note: symlink 対象は entrypoint にビルド時
COPYで焼き込まれます。エントリを増減した場合は イメージの再ビルドが必要です(devbase up単体では反映されない場合があります。CLI リファレンス: project グループ のdevbase project upの注記参照)。
gcloud と gws は symlink ではなく 環境変数で設定ディレクトリごと差し替えています。
| 変数 | 向き先 | 入るもの |
|---|---|---|
CLOUDSDK_CONFIG |
/persistent/group/gcloud |
credentials.db / access_tokens.db / legacy_credentials/ / configurations/ / application_default_credentials.json(ADC ファイル) |
GOOGLE_WORKSPACE_CLI_CONFIG_DIR |
/persistent/group/gws |
credentials.enc / .encryption_key |
CLOUDSDK_CONFIG は gcloud CLI 専用の仕組みではなく google.auth の探索経路そのものなので、
BigQuery クライアント等のライブラリも同じ場所を見ます。
Warning: この差し替えにより、
~/.config/gcloudは gcloud の設定ディレクトリでは なくなりました。鍵モード(GCP_AUTH_MODE=key)で書き出されるサービスアカウント鍵の 置き場でしかなく、コンテナ層(揮発)に残ります。したがって鍵は毎起動envから書き直され、 永続領域には残りません。設定を見たいときは$CLOUDSDK_CONFIGを参照してください。
認証モードの切り替えは 環境変数ガイド の GCP_AUTH_MODE、
実際の認証手順は Google 認証ガイド を参照してください。
Warning: gcloud は並行実行を想定していません(公式ドキュメント: "Parallel execution of multiple gcloud CLI commands is not supported.")。
credentials.dbは SQLite なので、 同じアカウントグループの複数コンテナが同時にgcloudを叩くとdatabase is lockedが 出ることがあります。恒久対策は取っていないので、その場合は少し待って再実行してください。
devbase のコンテナイメージは用途に応じた階層構造になっています。
graph TD
A[Ubuntu 26.04] --> B[base]
B --> C[general]
B --> G[go]
B --> J[browser]
B --> D[php]
B --> I[php85]
B --> E[latex]
A --> H[snapshot]
style A fill:#f0f0f0
style B fill:#e8e8f4
style C fill:#e8f4e8
style G fill:#f4f0e8
style H fill:#f4e8e8
| イメージ | ベース | 主な内容 | 用途 |
|---|---|---|---|
| base | Ubuntu 26.04 | Docker CLI、Python 3、AWS CLI、gcloud、Node.js(LTS)、AI CLI、日本語フォント、PDF / OOXML の道具、shellcheck | 汎用開発環境の土台 |
| general | base | base のまま(道具を足さない) | 汎用開発環境 |
| php | base | PHP 8.5、Composer、MySQL Shell | PHP 8.5 系 開発 |
| php85 | base | PHP 8.5、Composer、MySQL Shell | PHP 8.5 系 開発 |
| latex | base | LaTeX | 文書作成 |
| go | base | Go 開発環境 | Go 開発 |
| browser | base | Playwright の Chromium とその依存パッケージ、Noto CJK の追加の太さ(Thin〜Black) | ブラウザの操作、HTML の PDF・スクリーンショット |
| snapshot | Ubuntu 26.04 | zstd のみ(約 80MB) | スナップショット専用 |
派生イメージはどれも base を継ぐため、AWS CLI・gcloud・Node.js・AI CLI はどの派生イメージでも
使えます。terraform はどの標準イメージにも入っていません(入れ方は
ブラウザ・追加の太さのフォント・terraform を使う)。
containers/ にはこのほか、特定のプロジェクト用のイメージ(bi-tools / trygroup)があり、
どちらも base を継ぎます。
base イメージは、文字を描くときの既定を日本語にしています。総称ファミリ(sans-serif /
sans / serif / monospace)と、イメージに無い書体名(Meiryo / Yu Gothic /
MS PGothic / Noto Sans JP など)は、いずれも Noto CJK の JP フェイスへ解決されます。
fontconfig は Chromium / Playwright のスクリーンショット、PDF の生成、画像の生成がすべて
参照するため、日本語を含むページを撮っても日本語の字形で写ります。base が持つ Noto CJK は
標準の太さ(Regular・Bold)です。追加の太さ(Thin・Light・Medium・Black など)は browser の
イメージにあります。
| 指定 | 解決先 |
|---|---|
sans-serif / sans |
Noto Sans CJK JP |
serif |
Noto Serif CJK JP |
monospace |
Noto Sans Mono CJK JP |
Arial / Times New Roman / Courier New |
Liberation Sans / Serif / Mono(metric 互換) |
Calibri / Cambria |
Carlito / Caladea(metric 互換) |
sans-serif:lang=zh-cn など、言語を明示した指定 |
その言語の、同じ様式のフェイス(SC / KR) |
言語を明示しない中国語は、日本語の字形で描かれます。
langを伴わないsans-serifは どちらかの言語を選ばざるをえないためで、意図した振る舞いです。中国語・韓国語で描きたい ときはlang=zh-cn/lang=koを明示するか、書体を名指ししてください。
設定は /etc/fonts/local.conf(containers/base/fonts-local.conf)にあります。個人の設定
~/.config/fontconfig/fonts.conf はこれより先に読まれるため、コンテナの中で上書きできます。
文書を扱う道具も base に入っています。
| 道具 | 用途 |
|---|---|
pdftoppm / pdftocairo |
PDF を画像(PNG / JPEG / SVG)にする |
pdfinfo / pdffonts |
PDF のページ数・寸法・埋め込みフォントを調べる |
python3 -c "import PIL" |
画像の読み書き・変換(Pillow) |
python3 -c "import lxml, defusedxml" |
OOXML(.docx / .xlsx / .pptx)を壊さずに読み書きする |
LibreOffice と
pipは入っていません。 LibreOffice は展開 372〜459MB で base の規律に 見合わないため入れていません。Python パッケージが要るときはuv/uvxを使ってください。
base にはブラウザが入っていません。Playwright(@playwright/test)は入っていますが、
Chromium とその依存パッケージは browser のイメージにあります。base 系のイメージ(base・
general・php など)で Playwright の Chromium を起動すると、npx playwright install を
打つよう示して止まります。使い方は次の節を見てください。
これらは
devbase build base --no-cacheで base を建て直すと反映されます。devbase upだけでは反映されません。派生イメージ(general・browserなど)を使っている プロジェクトは、その派生イメージも建て直し、devbase down→devbase upでコンテナを 作り直してください。devbase rebuildでは建て直りません。devbase build --expires=7のシノニムのため、 期限内はビルドそのものを飛ばします。
規則の中身と、その置き場所を動かせない理由は base イメージの文字の描画と、文書を扱う道具 にあります。
base は、すべての利用者が使う道具だけを持ちます。次のものは base にありません。
| 要るもの | 使い方 |
|---|---|
| ブラウザ(Playwright の Chromium とその依存パッケージ) | browser のイメージを選ぶ |
Noto CJK の追加の太さ(fonts-noto-cjk-extra) |
browser のイメージを選ぶ |
terraform |
プロジェクトの Dockerfile かフックで入れる |
browser のイメージを選ぶ。 プロジェクトの compose.yml の dev サービスで、build.context を
containers/browser にします。ほかの派生イメージと同じく、devbase build は base を先に建ててから
このイメージを建てます。プロジェクトの Dockerfile が派生イメージを FROM に取るときも、devbase build は
containers/<名前>/Dockerfile の FROM devbase-* をたどり、下の段から順に建てます。
services:
dev:
build:
context: ${DEVBASE_ROOT}/containers/browser/建て直した直後から、ネットワーク無しで Chromium を起動し、日本語のページを PDF や
スクリーンショットにできます。置き場は /opt/ms-playwright(環境変数 PLAYWRIGHT_BROWSERS_PATH)です。
システムの Chrome(
google-chrome-stable、/usr/bin/google-chrome)はどのイメージにも入っていません。 Playwright から使うときは何も変えずに Chromium が起動します。Playwright を介さずにブラウザの 実行ファイルを渡す道具には、browserのイメージで次のコマンドが出す Playwright の Chromium の パスを渡してください。NODE_PATH="$(npm root -g)" node -e "console.log(require('@playwright/test').chromium.executablePath())"
php などほかの派生イメージの道具も要るとき。 browser のイメージには PHP などの道具が
ありません。次の道筋から、プロジェクトの道具立てに合うものを選びます。
| 道筋 | すること | 気をつけること |
|---|---|---|
browser のイメージを選ぶ |
上の build.context に替える |
元の派生イメージの道具が無くなる |
| プロジェクトの Dockerfile で足す | FROM devbase-php:latest などの上で、利用者 ubuntu が npx playwright install --with-deps chromium を打つ |
devbase build は継承の連なりを下の段から建てる(devbase-base → devbase-php → プロジェクト)。たどる途中の containers/<名前>/ が無いときは、何も建てずに止まる |
| 道具の起動引数でブラウザの場所を渡す | MCP の起動引数などで、上の 2 つのどちらかで用意した Chromium の実行ファイルを指させる | ブラウザと依存パッケージは、ほかの 2 つの道筋で用意する |
@playwright/mcp や chrome-devtools-mcp は、既定でシステムの Chrome を探すことがあります。
選んだ道筋で、実際に起動できることを確かめてください。
コンテナの中で一時的に取得する。 base 系のコンテナでも、次のコマンドで Chromium と依存 パッケージを取得できます。コンテナを作り直すと消え、取得のたびに数百 MB をネットワークから取ります。
npx playwright install --with-deps chromiumterraform を入れる。 プロジェクトの Dockerfile(root の RUN)か、コンテナ起動時のフックで
HashiCorp の apt の取得元を足して入れます。
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt-get update && sudo apt-get install -y terraformbase イメージには ShellCheck(shellcheck)が入っています。
コンテナの中で Bash スクリプトを検査できます。
shellcheck path/to/script.sh指摘は SC2086 のような番号つきで出て、指摘があれば終了コード 1 で終わります。
bash-language-server などの言語サーバは Bash の診断を shellcheck に任せているため、
コンテナの中で言語サーバを動かすときもこれが使われます(言語サーバ自体は base に入っていません)。
版は固定しておらず、base を建てた時点の Ubuntu のアーカイブの版が入ります。
containers/snapshot は base を継がないため入っていません。
置き場所・入れ損ないの止め方・版の扱いの仕様は
base イメージの Bash の静的検査(shellcheck)
にあります。
devbase build base --no-cacheで base を建て直すと反映されます。devbase upだけでは 反映されません。派生イメージ(general/phpなど)を使っているプロジェクトは、その 派生イメージも建て直し、稼働中のコンテナはdevbase down→devbase upで作り直して ください。devbase rebuildでは建て直りません。
base イメージ以降(snapshot を除くすべての標準イメージ)のコンテナ内では、以下の AI CLI ツールがエイリアスとして利用可能です。
| エイリアス | ツール | モード | 説明 |
|---|---|---|---|
claude |
Claude Code | skip-permissions | Anthropic の AI コーディングアシスタント |
claudb |
Claude Code (AWS Bedrock) | Opus 4.6 / us-west-2 | AWS Bedrock 経由の Claude |
gemini |
Gemini CLI | yolo mode | Google の AI アシスタント |
codex |
Codex CLI | bypass-approvals | OpenAI の AI コーディングツール |
kiro |
Kiro CLI | trust-all-tools | AWS の AI アシスタント |
agy |
Antigravity CLI | dangerously-skip-permissions | Google の AI コーディングエージェント |
# コンテナ内での使用例
claude "このコードをレビューして"
gemini "テストを書いて"
codex "リファクタリングして"コンテナの対話シェルでは、各 AI CLI が確認プロンプトを省くオプション付きで起動します。
定義は /etc/devbase/ai-cli-aliases.sh にあり、~/.bashrc から読み込まれます。
| コマンド | 起動するもの |
|---|---|
claude |
claude --dangerously-skip-permissions |
claudb |
claude --dangerously-skip-permissions(Amazon Bedrock 経由。CLAUDE_CODE_USE_BEDROCK=1 / AWS_REGION=us-west-2 を前置) |
gemini |
gemini --yolo |
codex |
codex --dangerously-bypass-approvals-and-sandbox |
kiro |
kiro-cli chat --trust-all-tools |
agy |
agy --dangerously-skip-permissions |
引数はそのまま後ろへ渡ります(gemini "テストを書いて" は gemini --yolo "テストを書いて")。
素の CLI を使いたいときは command gemini ... のように command を前置します。
起動定義は認証方式を決めません。 環境変数 GOOGLE_GENAI_USE_VERTEXAI で選びます。
| 設定 | 経路 |
|---|---|
GOOGLE_GENAI_USE_VERTEXAI=true |
Vertex AI(GOOGLE_CLOUD_PROJECT と ADC が要る) |
| 未設定・空 | ~/.gemini/settings.json の selectedType に従う(oauth-personal など) |
Vertex AI を既定にするなら共通の設定へ入れます。
devbase env set GOOGLE_GENAI_USE_VERTEXAI=trueVertex AI を使わないプロジェクト(別会社のアカウントで OAuth ログインするなど)は、
projects/<name>/env で空にして共通の値を打ち消します。GOOGLE_CLOUD_PROJECT と同じやり方です。
GOOGLE_GENAI_USE_VERTEXAI=
GOOGLE_CLOUD_PROJECT=
GOOGLE_CLOUD_PROJECTは認証方式を選ぶ変数ではありません。 gcloud や BigQuery でも使う プロジェクト指定なので、OAuth を使いながら別の用途で設定していても Vertex へは切り替わりません。
~/.gemini はアカウントグループのボリューム(/persistent/group/.gemini)にあるため、
OAuth のログインはコンテナを作り直しても残ります。
~/.bashrc はイメージの中にあるため、書き足した alias や関数はコンテナを作り直すと消えます。
作り直しても残したい設定は、置き場所 ~/.shellrc.d/ へ *.sh のファイルとして置きます。
cat > ~/.shellrc.d/my-aliases.sh <<'SH'
alias ll='ls -alF'
SH置いたファイルは、次に開く対話シェル(devbase login / tmux の窓 / VS Code の端末)から効きます。
| 項目 | 振る舞い |
|---|---|
| 実体 | /persistent/group/.shellrc.d/。同じアカウントグループのコンテナすべてで同じ設定が効き、別のグループには効かない |
| パス | 環境変数 DEVBASE_SHELLRC_DIR(/home/ubuntu/.shellrc.d)。docker exec の非対話の処理からも見える。設定を足すツールはこの変数の指す先へ 1 ファイル置き、~/.bashrc を書き換えない |
| 読まれるもの | 置き場所の直下の、名前が .sh で終わるファイル。サブディレクトリの中・. で始まる名前・他の拡張子は読まない |
| 読む順 | ファイル名の昇順。AI CLI の起動定義の後に読むので、同じ名前の alias(claude など)は置き場所の定義が勝つ |
| 読まれる時点 | 対話の bash の起動時だけ。スクリプトや docker exec ... bash -c などの非対話の処理では読まれない |
| 誤り | ファイルの中の構文・実行のエラーは標準エラーに出て、次のファイルへ進む。読み取り権限の無いファイル・リンク切れの symlink は、何も出さずに飛ばす |
置くファイルの作法:
- 1 つの用途につき 1 ファイルにし、
<名前>.shとします。順序を決めたいときは10-のような数字を前に付けます - 何度読まれても同じ結果になるように書きます。
exitは書きません(対話シェルが終わります)。標準出力へは何も出しません - devbase は置き場所へ何も書きません。置いたものを消すのは置いた側です
DEVBASE_SHELLRC_DIRを別の場所へ向けると、読み込みもそちらへ移ります。ただし向けた先は永続化されません
反映には devbase build base --no-cache が要ります。 devbase up だけでは反映されません
(読み込みの 1 行と DEVBASE_SHELLRC_DIR はイメージの中にあります)。派生イメージを使う
プロジェクトはその派生イメージも建て直し、稼働中のコンテナは devbase down → devbase up で
作り直してください。zsh(base には入っていません)は対象外です。
読む先の決め方・読み込みの前後で保つ条件・エラーの扱いの仕様は
作り直しても残るシェルの設定(~/.shellrc.d)にあります。
コンテナ内の tmux には、devbase 共通の既定設定 /etc/tmux.conf が入っています
(実体は containers/base/tmux.conf)。tmux は起動すると端末の代替画面へ切り替わるため、
出力履歴は VS Code のスクロールバックではなく tmux 自身のバッファに入ります。素の tmux は
履歴 2000 行・マウス無効なので、この履歴に実質手が届きません。既定設定はそこを埋めます。
| 設定 | 値 | 理由 |
|---|---|---|
mouse |
on |
ホイールを転がすと copy-mode に入り、履歴を遡れる |
history-limit |
100000 |
既定の 2000 行はビルドログ 1 回で流れ切る |
focus-events |
on |
端末のフォーカス通知を中のアプリへ渡す。Claude Code の完了通知が正しく出し分けられる |
default-terminal |
tmux-256color |
端末種別の固定 |
terminal-overrides |
,xterm-256color:Tc を追記 |
VS Code の統合ターミナルへ 24bit 色を通す |
terminal-features |
,xterm-256color:hyperlinks を追記 |
OSC 8 のハイパーリンクを外側の端末へ渡す。宣言しないと tmux がリンクを捨て、Claude Code などが出す URL がクリックできない |
| 操作 | キー |
|---|---|
| スクロール | マウスホイール(自動で copy-mode に入る) |
| 範囲選択 | ドラッグ(ボタンを離しても選択を保持) |
| コピー | 選択中に Ctrl+C(クリップボードへ入れて copy-mode を抜ける) |
| 選択解除 | q |
| copy-mode に入る | Ctrl-b [ |
| 履歴内を検索 | copy-mode 中に Ctrl-r(上方向)/Ctrl-s(下方向) |
| copy-mode を抜ける | q |
| ペインをまたいで選択 | Shift + ドラッグ(VS Code のネイティブ選択に切り替わる) |
ドラッグ終了後も選択範囲が残ります。Ctrl+C を押すと tmux が OSC 52 を送出し、VS Code の
クリップボードへ書き込んで copy-mode を抜けます。コピーせず選択を解除する場合は q を
押します。
上表の copy-mode のキーは tmux の mode-keys に従います。既定は emacs ですが、tmux は
EDITOR / VISUAL に vi を含む値が入っていると vi へ切り替えるため、その場合の検索は
/(下方向)と ?(上方向)になります。
tmux は /etc/tmux.conf を読んでから ~/.tmux.conf を読み、同じオプションは後から読んだ
~/.tmux.conf が勝ちます。既定値を変えたい場合は ~/.tmux.conf に書いてください。
# 例: ホイールを tmux に渡さず、端末側のスクロールに戻す
echo 'set -g mouse off' >> ~/.tmux.conf
tmux source-file ~/.tmux.conf # 実行中のセッションを保ったまま反映するNote:
source-fileはセッションや配下のプロセスを終了せずに設定を読み直し、mouseのような オプションは即時に反映されます。ただしhistory-limitは新しく作る pane から適用され、既存の pane は作成時の値を保持します。既存 pane にも効かせたい場合は、その pane を作り直してください。
Note:
~/.tmux.confは永続化の対象外です(/persistent/aiへ symlink されるのは~/.claudeなどの AI 設定のみ)。コンテナを作り直すと消えるため、残したい設定は~/share配下など永続領域へ置いてコピーしてください。
Note:
/etc/tmux.confはイメージに焼き込まれています。設定を変更した場合の反映にはdevbase container buildによるイメージの再ビルドと、コンテナの作り直しが必要です。
セッションが増えてしまったときの整理(tmux-first / tmux-clean)は
環境変数ガイド を参照してください。
# 起動中のコンテナを表示
devbase ps
# 停止中のコンテナも含めて表示
devbase ps -a# 最新のログを表示
devbase project logs
# リアルタイムでログを追跡
devbase project logs -f
# 末尾100行のみ追跡
devbase project logs -f --tail 100# 階層メニュー TUI を起動(TTY ではこれがデフォルト)
devbase list
# 選択せず NAME / PLUGIN / STATUS の一覧表示のみ
devbase list --no-interactive # --plain / -P も同義TTY(端末)では
devbase listはデフォルトで階層メニュー TUI になり、 プロジェクトを選んで起動・操作(up / down / login / ps / logs / scale / build / rebuild)できるほか、画面最下部の常設メニュー(環境変数 / プラグイン / スナップショット / ステータス)へ ←→ キーで移動して各管理操作を実行できます。 パイプ・リダイレクト・CI などの非 TTY 環境では自動的に一覧表示のみに フォールバックします。画面構成とキー操作の詳細は CLI リファレンス: project グループ を参照してください。
devbase project ps が「対象プロジェクト 1 つのコンテナ状態」を表示するのに対し、
devbase list は「全プロジェクトの横断一覧」を表示します。
# コンテナ、プラグイン、環境変数、スナップショットの状態を一括確認
devbase status- プロジェクト固有のファイルは
/workに配置する --/persistent/ai(~/.claude等の symlink 先・~/share)は全コンテナで共有されるため scaleは必要最小限に設定する -- リソース消費を抑制- 作業終了後は
devbase downを実行する -- 自動ローテーションでディスク容量を管理 devbase psで状態を確認してからログインする -- 異常終了したコンテナへのログイン試行を避ける- イメージのビルドは初回と更新時のみ -- 変更がない場合はキャッシュが利用される