devbase の環境変数管理の仕組みと操作方法を解説します。
devbase の環境変数は 3 つのレベルで管理されます。後に読み込まれるレベルが同名のキーを上書きします(後勝ち)。
graph TD
A["グローバル .env<br/>devbase/.env"] --> D[最終的な環境変数]
B["プロジェクト設定 env<br/>projects/*/env"] --> D
C["プロジェクト機密 .env<br/>projects/*/.env"] --> D
style A fill:#e8f4e8
style B fill:#e8e8f4
style C fill:#f4e8e8
| 優先度 | レベル | ファイル | 用途 | Git 管理 |
|---|---|---|---|---|
| 1(低) | グローバル | devbase/.env |
共通 API キー・認証情報 | gitignore |
| 2 | プロジェクト環境変数 | projects/*/env |
コンテナへ渡すプロジェクト固有の環境変数(ENABLE_SSH 等) |
管理対象 |
| 3(高) | プロジェクト機密 | projects/*/.env |
プロジェクト固有の API キー | gitignore |
Note: 同じキーが複数のレベルに存在する場合、優先度が高いレベルの値が使用されます。例えば、グローバルの
AWS_PROFILEをプロジェクトの.envで上書きすることで、プロジェクトごとに異なる AWS プロファイルを使用できます。
グローバル .env(devbase/.env)
全プロジェクトで共有する認証情報や API キーを格納します。devbase env init で対話式に設定するか、devbase env set で直接設定します。
プロジェクト設定 env(projects/*/env)
コンテナへ渡すプロジェクト固有の環境変数を格納します。Git 管理対象のため、機密情報は含めないでください。
# env ファイルの例
ENABLE_SSH=truedevbase 自身の設定(どのリポジトリを clone するか、コンテナ数、エディタの自動オープン)は
環境変数ではなく projects/*/project.yml に書きます。env に
GIT_USER / GIT_REPO / WORK_DIR / CONTAINER_SCALE を書いても効果はありません。
compose.yml が env_file: - env で参照するため、中身が無くてもファイル自体は残してください。
プロジェクト機密 .env(projects/*/.env)
プロジェクト固有の機密情報を格納します。gitignore 対象のため、チームメンバーは個別に設定する必要があります。
devbase はホストマシンの認証情報を自動収集し、コンテナ内で利用可能にする「コレクター」機能を備えています。
aws・google・git のコレクターはホストの資格情報ファイルを読みますが、見つけた値をそのまま書かず、
既定では候補を示して尋ね、選んだものだけを書きます。尋ねずに取り込むグループ・取り込まないグループは
$DEVBASE_ROOT/secrets/host-import.yml で名指しします(devbase env init)。
| キー | 説明 |
|---|---|
AWS_CONFIG_BASE64 |
~/.aws/config と ~/.aws/credentials のうち、選んだプロファイルとその連なり(sso_session・source_profile)の節を tar + Base64 エンコード(all か import のグループでは丸ごと) |
AWS_PROFILE |
使用する AWS プロファイル |
AWS_ACCESS_KEY_ID |
アクセスキー ID |
AWS_SECRET_ACCESS_KEY |
シークレットアクセスキー |
AWS_DEFAULT_REGION |
デフォルトリージョン |
AWS_SSO_URL |
SSO の開始 URL |
ソースファイル: ~/.aws/config, ~/.aws/credentials
ソースタイプ: tar_base64(丸ごと)/ aws_profiles(選んだプロファイル)
| キー | 説明 |
|---|---|
GCP_CREDENTIALS_BASE64__* |
~/gcp-credentials/ 配下の、選んだプロファイル(Base64 エンコード) |
GCP_ACTIVE_PROFILE |
アクティブなプロファイル名 |
GOOGLE_CLOUD_PROJECT |
GCP プロジェクト ID |
GOOGLE_CLOUD_LOCATION |
GCP リージョン |
GOOGLE_APPLICATION_CREDENTIALS |
サービスアカウントキーのパス(鍵モードのみ。下記参照) |
BIGQUERY_PROJECT |
BigQuery プロジェクト |
BIGQUERY_DATASETS |
BigQuery データセット |
BIGQUERY_LOCATION |
BigQuery ロケーション |
BIGQUERY_KEY_FILE |
BigQuery キーファイルパス(鍵モードのみ。下記参照) |
ソースファイル: ~/gcp-credentials/
ソースタイプ: named_profiles
Google はサービスアカウント鍵を非推奨とし、ローカル開発には
gcloud auth application-default login(ユーザー認証 = ADC)を推奨しています。
devbase は gcloud の設定ディレクトリをアカウントグループごとに永続化するため、
ADC を既定の経路にできます。鍵が要る場面のために切り替えを残しています。
GCP_AUTH_MODE はプロジェクトの env かグローバル env に手書きします。
| 値 | 挙動 |
|---|---|
adc |
鍵を書かない。GOOGLE_APPLICATION_CREDENTIALS と BIGQUERY_KEY_FILE をコンテナへ渡さない。認証は $CLOUDSDK_CONFIG/application_default_credentials.json(= gcloud auth application-default login の結果)に委ねる |
key |
GCP_CREDENTIALS_BASE64__<profile> を復号して書き、上記 2 変数を渡す(従来どおり) |
| 未設定 | 鍵の env があれば key、無ければ adc(既存プロジェクトは従来どおり動きます) |
鍵の有無は GCP_ACTIVE_PROFILE(未設定なら default)のプロファイル 1 本だけで
判定します(無ければ後方互換の GOOGLE_APPLICATION_CREDENTIALS_BASE64)。別プロファイル
の鍵があっても、アクティブなプロファイルの鍵が無ければ adc です。GCP_AUTH_MODE=key を
明示していても同じで、鍵が無ければ adc として構成します(警告を出します)。ホスト側と
コンテナ側で判定が食い違うと、実体の無いパスだけがコンテナへ残るためです。
adc で 2 変数を渡さないのが要点です。値だけ残して実体が無いと、ADC は
ユーザー認証へフォールバックせず DefaultCredentialsError で落ちます。元の
compose.yml の environment: にパスが直書きされている場合も、adc では生成 compose
から取り除きます。
取り除く対象は dev サービス(dev-1 〜 dev-N)だけです。GCP_AUTH_MODE は dev の
認証方式の宣言なので、独自に鍵をマウントしている batch のような非 dev サービスが
environment: や env_file で受け取っている 2 変数はそのまま残します。
adc が止めるのは 鍵をファイルへ書き出すことだけで、鍵を運ぶ base64 変数の配布までは
止まりません。名前が生成 compose の environment: に載っている限り、Compose が値を解決して
コンテナへ渡すため、env で中身が読めてしまいます。
そこで devbase は、コンテナ内で使われない鍵の変数も dev の列挙から外します。entrypoint が 読むのはアクティブプロファイルの鍵 1 本だけだからです。
| 変数 | adc |
key |
|---|---|---|
GCP_CREDENTIALS_BASE64__<アクティブプロファイル> |
渡さない | 渡す |
GCP_CREDENTIALS_BASE64__<それ以外> |
渡さない | 渡さない |
GOOGLE_APPLICATION_CREDENTIALS_BASE64 |
渡さない | アクティブプロファイルの鍵が無いときだけ渡す |
adc でアクティブプロファイルの鍵も渡さないのが要点です。entrypoint の
devbase_setup_gcp_credentials は adc だと鍵を読む前に return するため、鍵の実体は
1 本も要りません。アクティブ分だけ残すと「鍵を使わない」と宣言したコンテナの env から
秘密鍵が読めてしまいます。
除外は compose.yml の dev サービスへ直書きされた変数にも効きます。列挙を絞るだけでは
直書きが生成物に残り、対策を迂回するためです。非 dev サービスの明示設定には触りません。
3 行目は後方互換キーの扱いです。entrypoint は key モードでアクティブプロファイルの鍵が
無いときだけこのキーへフォールバックするので、そのときは供給源になるため外せません。
逆に言うと、プロファイル別キーへ移行済みのプロジェクトでは渡らなくなります。
これはアカウントグループ(DEVBASE_ACCOUNT_GROUP)をまたいだ鍵の共有を防ぐためのものです。
グループを分けてもこの除外が無いと、別グループ用のサービスアカウント鍵がコンテナへ届きます。
Note: アクティブプロファイルの鍵が無く、
GCP_AUTH_MODEも宣言していない構成では、 後方互換キーがkeyモードを引き起こして渡り続けます。別グループの鍵を持ち込みたくない なら、プロジェクトのenvにGCP_AUTH_MODE=adcを明示してください。
# ADC を使う(推奨)
echo 'GCP_AUTH_MODE=adc' >> projects/<name>/env
devbase project up <name>切り替えには devbase up が必要です(コンテナへ渡す環境変数が変わるため)。
手順の全体は Google 認証ガイド を参照してください。
| 変数 | 値 | 意味 |
|---|---|---|
CLOUDSDK_CONFIG |
/persistent/group/gcloud |
gcloud の設定ディレクトリ。credentials.db / access_tokens.db / application_default_credentials.json がここに入る |
GOOGLE_WORKSPACE_CLI_CONFIG_DIR |
/persistent/group/gws |
gws(Google Workspace CLI)の設定ディレクトリ |
いずれも devbase が生成 compose で渡すため、env に書く必要はありません。
Warning:
CLOUDSDK_CONFIGを向け直したあとの~/.config/gcloudは gcloud の設定ディレクトリではありません。鍵モードで書き出される サービスアカウント鍵の置き場でしかなく、コンテナ層(揮発)に残ります。 gcloud の実際の設定を見たいときは$CLOUDSDK_CONFIGを参照してください。
| キー | 説明 |
|---|---|
GIT_USER_NAME |
Git ユーザー名 |
GIT_USER_EMAIL |
Git メールアドレス |
GIT_CREDENTIAL_HELPER |
認証ヘルパー設定 |
GIT_CREDENTIALS_BASE64 |
~/.git-credentials の Base64 エンコード |
GITHUB_PERSONAL_ACCESS_TOKEN |
GitHub PAT |
GH_TOKEN |
GitHub CLI 用トークン |
ソースファイル: ~/.git-credentials
ソースタイプ: file_base64
| キー | 説明 |
|---|---|
ANTHROPIC_API_KEY |
Anthropic API キー |
OPENAI_API_KEY |
OpenAI API キー |
GEMINI_API_KEY |
Google Gemini API キー |
CONTEXT7_API_KEY |
Context7 API キー |
PYPI_API_KEY |
PyPI API キー |
NPM_TOKEN |
npm トークン |
| キー | 説明 |
|---|---|
DEVIN_API_KEY |
Devin API キー |
DEVIN_API_ORG_WIDE |
組織全体の API 設定 |
DEVIN_ORG_ID |
組織 ID |
DEVIN_SERVICE_USER |
サービスユーザー名 |
DEVIN_SERVICE_ADMIN |
サービス管理者 |
| キー | 説明 |
|---|---|
SLACK_BOT_TOKEN |
Slack Bot トークン |
SLACK_TEAM_ID |
チーム ID |
SLACK_CHANNEL_ID |
チャンネル ID |
SLACK_USER_MENTION |
ユーザーメンション |
コンテナからホストへ SSH してホスト側 GUI アプリ(例: Chrome をリモートデバッグモードで起動)を起動するワークフロー向けの設定です。devbase env init はホスト上で実行されるため、ホストのログインユーザー名を自動取得して既定値として提示します。
| キー | 説明 |
|---|---|
HOST_SSH_USER |
コンテナ→ホスト SSH 時のホストログインユーザー名(既定: getpass.getuser() で自動取得) |
HOST_SSH_HOST |
SSH 先ホスト名(既定: host.docker.internal、WSL2/Windows では上書き可) |
ユーザー名のみで秘密情報ではありません。SSH 鍵やリモートログインの有効化はホスト側でユーザーが別途設定する前提です。devbase env sync 実行時には、未設定のキーのみ既定値で補完されます(既存値は上書きしません)。
使用する Google / AWS アカウントの単位を宣言します。devbase env init の収集対象では
なく、プロジェクトの env(projects/<name>/env)に手書きする devbase 動作設定です。
どのプロジェクトも宣言が必須で、既定の値はありません。
| キー | 説明 |
|---|---|
DEVBASE_ACCOUNT_GROUP |
アカウントグループ名(例: acme / personal / initech / globex)。グループごとに devbase_home_<group> ボリュームが作られ、コンテナへ /persistent/group としてマウントされる |
# projects/<name>/env
DEVBASE_ACCOUNT_GROUP=globex同じグループのコンテナは Claude Code / gcloud / gws の認証と会話ログを共有し、
違うグループのコンテナは互いの認証に到達できません。~/.claude/plugins のような
共通資産は別ボリューム (/persistent/ai) に残るため、グループを増やしても重複しません。
会社の機密を使わない個人・OSS のプロジェクトには personal を宣言します。
グループを決めるのはプロジェクトの env の空でない宣言だけです。次のどれかに当たると、
devbase up / scale / 機密のコマンド(env get など)/ snapshot create は、ボリューム・
生成物・コンテナ・pre-up のどれも作らずに終了コード 1 で止まり、直すファイルと行を示します。
| 状況 | 直し方 |
|---|---|
projects/<name>/env に DEVBASE_ACCOUNT_GROUP が無い |
projects/<name>/env に DEVBASE_ACCOUNT_GROUP=<グループ> を書く |
DEVBASE_ACCOUNT_GROUP=(空) |
示された行にグループ名を書く |
$DEVBASE_ROOT/env に DEVBASE_ACCOUNT_GROUP がある |
その行を消し、各プロジェクトの env に書く(全体の既定は置けない) |
DEVBASE_ACCOUNT_GROUP=default |
移し先のグループ名を書く(default は予約語。default からの移行) |
projects/ の外で devbase up を打った |
projects/<name>/ の下で打つか、devbase up <name> で名前を渡す |
login / ps / logs / down / profile / build / rebuild はグループを決めないため、
宣言の無いプロジェクトでも止まりません。宣言は devbase status の [環境] セクションで
確かめられます(プロジェクトの外では「なし(プロジェクトの外)」と出ます)。
グループ名には次のものが使えません(devbase up の前にエラーになります)。
| 使えない名前 | 理由 |
|---|---|
^[a-zA-Z0-9][a-zA-Z0-9._-]*$ に合わないもの |
Docker のボリューム名にできない |
ubuntu |
共通ボリューム devbase_home_ubuntu と同名になる |
default |
旧既定のボリューム devbase_home_default と同名になる(予約語) |
数字だけの名前(1 / 042) |
インスタンス番号のボリューム devbase_home_<index> と同名になる |
シェルの環境変数 DEVBASE_ACCOUNT_GROUP で渡した値が宣言と違うと、devbase up / scale は
2 つの値と出所を示して止まります。環境変数が未設定なら、devbase が宣言の値を使います。
ボリューム構造の全体は コンテナ運用ガイド、Google 認証の手順は Google 認証ガイド を参照してください。
DEVBASE_ACCOUNT_GROUP を決めるのはプロジェクトの env ファイル(projects/<name>/env)
だけです。機密の置き場(.env / age / OpenBao のどれでも、version: 1 でも)に書いた値は
使われず、コンテナへも渡りません。置き場に残っていれば、devbase のコマンドを打つたびに次の
警告が 1 回出ます(値は出しません)。
Warning: 機密の置き場(グローバル)にある DEVBASE_ACCOUNT_GROUP は使いません。アカウントグループは env ファイル(projects/<name>/env)で決まります。消すには: devbase env delete DEVBASE_ACCOUNT_GROUP
警告に書かれたとおり devbase env delete DEVBASE_ACCOUNT_GROUP(置き場に合わせて -p /
--user / --group が付きます)で消してください。devbase env set DEVBASE_ACCOUNT_GROUP=... は
置き場へ書かずに終了コード 1 で止まります。projects/<name>/env に書いてください。
機密の保存先に OpenBao を使い、グループ別の置き場(secrets/backend.yml の version: 2)を
選んだ端末では、機密の置き場もこのグループで分かれます。プロジェクトのコンテナへ届くのは、
そのプロジェクトのグループの置き場(team/<group>/…・users/<user>/<group>/…)の機密だけです。
設定・パスの対応・グループ名を別の名前の置き場で扱う読み替えは
機密の保存先を選ぶを参照してください。
- プロジェクトの中では、機密のコマンドはプロジェクトの宣言のグループの置き場を相手にします
- プロジェクトの外(
$DEVBASE_ROOTなど)では--group <名前>が必須です (env init/sync/list/set/get/delete/edit/export/import/backend test/backend migrate)。付けないと置き場を開かずに終了コード 2 で止まります devbase listの TUI は、共通の範囲を扱う前(キーの一覧・sync・init)とスナップショットの 作成の前にグループを選ばせます。候補は宣言済みのプロジェクトのグループです$DEVBASE_ROOTで打つdevbase buildやdevbase pluginには、共通の機密が載りません (どのグループの置き場も読みません)
グループを宣言していなかったプロジェクトは、ボリューム devbase_home_default(旧既定の
ボリューム)を使い、グループ別の置き場では group_aliases の default: <グループ> で
機密を読んでいました。default は予約語になったため、次の順に移します。例は移し先を
acme とした場合です(移し先は端末ごとに違います。devbase_home_default の中身の持ち主の
グループを選んでください)。
| 順 | 手順 |
|---|---|
| 1 | 更新する前に、宣言の無いプロジェクトと、移し先のグループを宣言したプロジェクトのコンテナを devbase down で止める |
| 2 | devbase を新しい版へ更新する |
| 3 | devbase project migrate-volume --to acme で devbase_home_default の中身を devbase_home_acme へ写す(--dry-run で先に確かめられる) |
| 4 | secrets/backend.yml の openbao.group_aliases から default: acme の行を消す |
| 5 | 各プロジェクトの projects/<name>/env に DEVBASE_ACCOUNT_GROUP=acme などを書く(plugin repo のプロジェクトは plugin repo の更新を devbase plugin で取り込む) |
| 6 | devbase build --no-cache でイメージを作り直してから、プロジェクトを devbase up し、claude のログイン・gh auth status・gcloud config get account・MCP のトークンが移行前と同じか確かめる |
migrate-volume は次のどれかに当たると、先へ何も書かずに止まります。
| 止まる理由 | 直し方 |
|---|---|
devbase_home_default が無い |
移すものはありません |
| 移し先が既にあって空でない | 挙げられたエントリを確かめ、要らなければ docker volume rm devbase_home_<group> で消して打ち直す |
| 元か先をマウントしたコンテナが動いている | 挙げられたコンテナのプロジェクトを devbase down で止めて打ち直す |
| Docker に届かない | Docker を起動して打ち直す |
写すのはファイル・ディレクトリ・持ち主・権限・シンボリックリンク(リンクのまま)で、
元の devbase_home_default は読み取り専用で付けて書き換えず、消しません。写した後に
元と先のエントリの数を照らし、合わなければ先を消して打ち直すよう示します。
新しい personal のグループは移行の対象ではありません。最初の devbase up で空の
devbase_home_personal が作られるため、claude・gh・gcloud などのログインを取り直し、
機密は devbase env init --group personal などで入れます。
ロールバック。 devbase を前の版へ戻し、secrets/backend.yml の openbao.group_aliases へ
default: acme を戻し、手順 5 で書いた宣言の行を外します。元の devbase_home_default が
残っているため、移行の前と同じ状態で起動します(宣言を残したまま前の版へ戻しても、宣言した
プロジェクトは写した devbase_home_acme を使って動きます)。devbase_home_default は、
ロールバックが要らないと判断した後に手で docker volume rm devbase_home_default で消します。
devbase_home_default のスナップショットの系列は残り、元のボリュームへだけ復元できます
(スナップショットガイド)。
devbase up 完了後、dev コンテナへ接続した VS Code を自動で開けます(VS Code の「Attach to Running Container」を CLI から起動)。
開く対象は project.yml から決まります。
- リポジトリが 1 件: primary リポジトリのフォルダ(
--folder-uri) - リポジトリが 2 件以上: 全リポジトリを含む multi-root ワークスペース
/work/<プロジェクト名>.code-workspace(--file-uri)
自動オープンの有無は project.yml の open_editor が最優先で、未指定なら以下の env に従います。このうち DEVBASE_OPEN_EDITOR だけは devbase env init の editor コレクターが対話収集し(対話の既定は 1 = 有効)、$DEVBASE_ROOT/.env に書き込まれます。残りは収集対象外で、$DEVBASE_ROOT/.env かプロジェクトの env に手書きする devbase 動作設定です。
| キー | 説明 |
|---|---|
DEVBASE_OPEN_EDITOR |
真(1/true/yes/on)で up 後にエディタを開く。devbase env init の対話既定は 1(有効)なので、init 済みの環境では通常 ON。キー自体が未設定のときのみ OFF に倒れる。project.yml の open_editor が指定されていればそちらが優先 |
DEVBASE_EDITOR |
起動コマンド(既定: code)。cursor / code-insiders 等も可 |
DEVBASE_WORKSPACE |
開く *.code-workspace ファイルのコンテナ内絶対パスを明示指定する(例 /home/ubuntu/share/work/myapp-doc.workspace)。効くのはリポジトリ 1 件の構成だけです。2 件以上の構成では devbase up が自動生成した /work/<プロジェクト名>.code-workspace を直接開くため、この env を設定しても上書きできません。~/share(= 全コンテナ共有ボリューム /persistent/ai/share への symlink)配下に置けば全コンテナで共用可 |
DEVBASE_OPEN_INDEX |
scale 時に開く dev インスタンス番号(既定: 1) |
DEVBASE_EDITOR_SSH_HOST |
Remote-SSH 跨ホスト構成での ssh-remote ホスト名(例 mac2)。通常は ~/.vscode-server から自動検出され不要。検出が外れる場合のみ明示。空文字(DEVBASE_EDITOR_SSH_HOST=)はネストのオプトアウトで、フラット URI を強制する。下記「リモート Docker」参照 |
DEVBASE_EDITOR_DOCKER_CONTEXT |
attach に使う docker context を手で決めたいときだけ明示する。未設定なら devbase が解決した context(--context / DEVBASE_DOCKER_CONTEXT / project.local.yml)、それも無ければ跨ホスト時にホストの docker context show |
DEVBASE_DOCKER_CONTEXT |
--context を受け付けるコマンド(一覧)が向ける docker context。project.local.yml の docker.context より優先し、CLI --context に負ける。グローバル .env に書くと全プロジェクトが同じホストへ向くため、通常は project.local.yml に書く。下記「リモート Docker」参照 |
DEVBASE_WINDOW_TITLE |
attach 先 VS Code の window.title テンプレート。{container} が実コンテナ名(例 myapp-dev-1)に置換される。既定は {container}${separator}${dirty}${activeEditorShort}。0 / false / off / 空文字で無効化。下記「ウィンドウタイトル」参照 |
都度の上書きは CLI フラグで行います: devbase up --open / --no-open / --open-index N(env より優先)。
閉じた窓を開き直すときは devbase open [name] [--open-index N] を使います。コンテナを再起動せず、DEVBASE_OPEN_EDITOR / open_editor の設定にかかわらず開きます(CLI リファレンス)。
VS Code の既定タイトルは編集中ファイル名が先頭に来るため、複数プロジェクトの窓を並べるとどれがどれか判別できません。devbase は up のたびに起動できた各 dev コンテナへ、scale では増やして起動できた dev コンテナへ コンテナ名始まりのタイトルを設定します。起動できなかったコンテナを起こし直した後は、devbase project post-start [name] で設定し直せます(CLI リファレンス)。
myapp-dev-1 - main.py
書き込み先はコンテナ内の Remote settings ~/.vscode-server/data/Machine/settings.json の window.title です(window.title は WINDOW スコープなのでリモート設定で有効)。クライアント側の attached container config ではなくコンテナ内へ書くのは、
imageConfigs/<image>.jsonはイメージ単位で、devbase-php:latestのような共有イメージではインスタンスを区別できないnameConfigs/<container>.jsonはコンテナ名単位だが、存在するとimageConfigsが読まれなくなり既存のworkspaceFolder/extensionsが失われる- クライアント側のパスは OS 依存で、跨ホスト構成では devbase の走るホストに無い
ため。エディタ自動オープン(DEVBASE_OPEN_EDITOR)の有無に関わらず設定されるので、手動で「コンテナーにアタッチ」した窓にも効きます。
既存の設定は保持し、値が同じなら書き込みません(無用な設定ファイル監視の発火を避けるため)。設定ファイルが JSON として読めない場合は上書きせず諦めます。
タイトルを変えたい / 止めたい場合は DEVBASE_WINDOW_TITLE を使います:
# コンテナ名だけにする
DEVBASE_WINDOW_TITLE={container}
# ブランチ名なども足す(VS Code のタイトル変数がそのまま使える)
DEVBASE_WINDOW_TITLE={container}${separator}${activeEditorShort}${separator}${rootName}
# 無効化(VS Code 既定のタイトルに戻す)
DEVBASE_WINDOW_TITLE=0無効化しても、既にコンテナへ書き込んだ
window.titleは消えません。戻すにはコンテナ内~/.vscode-server/data/Machine/settings.jsonからwindow.titleを削除してください。
| コンテキスト | 挙動 |
|---|---|
| ローカル端末(Mac/Linux) | ローカル VS Code が開く |
| WSL 端末 | Windows 側 VS Code が開く(code ラッパ経由) |
| VS Code の Remote-SSH 統合ターミナル(同一ホストの Docker) | クライアント側(手元)の VS Code が開く(code シムが委譲) |
| VS Code の Remote-SSH 統合ターミナル(跨ホスト: ssh 先の Docker にコンテナ) | ネスト URI で開く(DEVBASE_EDITOR_SSH_HOST は通常は自動検出。下記「リモート Docker」参照) |
| ローカル端末 / Remote-SSH 統合ターミナルで、コンテナが 別ホストの docker context 上にある | attach URI に settings.context を付け、Dev Containers 拡張にその context で attach させる(下記「リモート Docker」参照) |
| 手元から素の SSH(VS Code 外)で接続中 | クライアントへ自動で開く公式手段が無いため、手元で実行する code --folder-uri ... コマンドを提示 |
| tmux 経由のターミナル | VSCODE_IPC_HOOK_CLI が古くなっていても、tmux のセッション環境から生きた値を拾い直して開く。拾えなければ「コマンド提示」へ degrade(下記「tmux / screen 経由で使う場合」参照) |
CI / 非対話(非 TTY) / code 不在 |
理由を表示してスキップ(up 自体は成功) |
devbase up は既定で コマンドを実行した環境の Docker にコンテナを立てます。
projects/<name>/project.local.yml に docker context の名前を書くと、そのプロジェクトで
--context を受け付けるコマンド(一覧)を
別ホストの daemon へ向けられます。用途は、CUDA が使える Windows(WSL2)の GPU、負荷分散のための 3 台目の PC、
AWS EC2 の計算資源などです。
仕組みは「compose クライアントは手元、daemon はリモート」です。devbase・projects/・機密鍵を
リモートへ複製する必要はなく、リモートに要るのは docker CLI + dockerd + sshd だけです。
手元で復号した機密の値は、従来のローカル構成と同じく compose の変数展開を通じて接続先の
daemon とコンテナへ渡ります(鍵・.env・project.local.yml は手元に留まります)。
接続先は機密を預けてよいホストに限ってください。
接続先の実体(ホスト名・鍵)は docker context に持たせ、devbase には名前だけを書きます。 ssh 鍵・TLS・WSL / EC2 の違いは docker 側の問題として devbase から切り離せます。
# Windows の WSL2 内 dockerd(WSL 内で sshd を動かし、Docker Desktop の WSL 統合か
# WSL 内へ直接インストールした dockerd を使う。Windows 側 OpenSSH 経由にはしない)
docker context create gpu-wsl --docker "host=ssh://alice@winpc"
# EC2(ssh 経由なので TLS 証明書の配布は要らない)
docker context create ec2 --docker "host=ssh://ubuntu@ec2-host"
docker context ls # 名前を確認する。`docker context use` で切り替える必要は無いリモート側のユーザが docker グループに入っていること(docker ps が sudo 無しで通ること)を
確かめてください。
# projects/<name>/project.local.yml(gitignore 対象。個人・機材ごとの設定)
docker:
context: gpu-wsl
home: /home/alice # ~/.aws などを bind mount するプロジェクトだけ要る
# gid: 999 # 省略すると初回の up で自動取得して .cache/docker-gid/<context> に控えるキーの意味と優先順位は project.yml リファレンスに
あります。一時的に別の context へ向けるには devbase up <name> --context <ctx> か
env DEVBASE_DOCKER_CONTEXT を使います。
up の冒頭に docker context: gpu-wsl (project.local.yml, リモート扱い) と出ます。
「リモート扱い」は、解決した context が docker context show(現在の context)と異なる
状態です。同じ名前なら従来どおりローカル扱いで、gid の取得も ~ の展開も行いません。
リモート扱いの up で変わること:
| 項目 | 動き |
|---|---|
docker / docker compose の宛先 |
環境変数 DOCKER_CONTEXT で全呼び出し(フック、devbase build の自動実行を含む)へ渡す |
DOCKER_GID |
docker.gid の値。無ければ docker run --rm -v /var/run/docker.sock:/s alpine:3 stat -c %g /s で取得して控える。取得した値が 0 のときは警告する(socket が root 所有か rootless Docker。その場合は docker.gid を明示) |
bind mount の ~ |
docker.home で展開して生成物 .docker-compose.scale.yml に書く。docker.home が無ければ該当する mount を警告する(リモートでは空ディレクトリになる)。~user/... と ./ の相対パスは書き換えず警告する |
| イメージ | リモート側のイメージを見て、無ければリモート側でビルドする(buildx がビルド文脈を送る)。ホストごとに別物なので初回は時間がかかる |
| 自動スナップショット | 作らない(控えたいボリュームがリモートにある)。devbase snapshot 系は従来どおり手元の daemon を対象にする |
DOCKER_HOST |
設定されていれば警告して外す。docker は DOCKER_HOST を DOCKER_CONTEXT より優先するため、残すと context が効かない |
gid の控え $DEVBASE_ROOT/.cache/docker-gid/<context> は自動では消しません。リモート側の
gid が変わったらファイルを消すか docker.gid を書いてください。
devbase up が開く attach URI は、実行した場所とコンテナの場所で変わります。
devbase up を実行する場所 |
コンテナの場所 | 開き方 |
|---|---|---|
| ローカル端末(Mac / Linux / WSL) | 同じマシン(従来) | フラット URI |
| ローカル端末 | リモート context | フラット URI + settings.context=<ctx>。手元の Dev Containers 拡張がその context 経由で attach する |
| Remote-SSH 統合ターミナル(Windows VS Code → Mac) | Mac | ネスト URI …@ssh-remote+<host>(下記) |
| Remote-SSH 統合ターミナル | リモート context(WSL / EC2 など) | ネスト URI + settings.context=<ctx>。Mac の Dev Containers が context 経由で attach する。あわせて、手元の VS Code に同名の context があれば直接 attach できるフラット URI も表示する(Windows → Mac → WSL(Windows) の一周を避けたいとき)。毎回そのフラット URI で開きたければ DEVBASE_EDITOR_SSH_HOST=(空)を書く(下記「手元の context で直接開く」) |
settings.context は「DEVBASE_EDITOR_DOCKER_CONTEXT の明示 → devbase が解決した context →
(ssh 先のときだけ)docker context show」の順で決まります。
手元(例 Windows)の VS Code から Remote-SSH で別ホスト(例 Mac)へ入り、その統合ターミナルで devbase up を実行する構成では、コンテナは ssh 先(Mac)の Docker 上にあります。このとき code の開く要求はクライアント(Windows)へ委譲されるため、フラットな attach URI のままだと クライアント側の Docker を見に行きコンテナが見つかりません(「コンテナーにアタッチできません。すでに存在しません」)。
これを解決するには、ネスト URI vscode-remote://attached-container+<hex>@ssh-remote+<host>/work/... を使い、docker ルックアップを ssh 先(コンテナのある Mac)で行わせます。<host> は 手元 ~/.ssh/config の Host 別名(例 mac2)で、これは「今の VS Code 接続の authority ラベル」と完全一致する必要があります(ネスト attach は新規 ssh 接続を張らず既存接続を再利用するため。IP や user@IP は "Parent authority found without ExecServer" で不可)。
このラベルは VS Code が ssh 先の端末 env に渡さない(SSH_CONNECTION は IP のみ)ものの、devbase は ssh 先(Mac)の VS Code 系サーバーディレクトリ(~/.vscode-server / ~/.cursor-server / ~/.vscode-server-insiders 等)の File History から自動検出します(DEVBASE_EDITOR で cursor 等を使う場合も横断)。よって通常は設定不要です。
自動検出が外れる場合(複数 ssh-remote ホストを使い分けている等)のみ明示します:
# $DEVBASE_ROOT/env など(全プロジェクト共通にしたい場合)
DEVBASE_EDITOR_SSH_HOST=mac2
# attach に使う docker context を手で決めたい場合だけ
# DEVBASE_EDITOR_DOCKER_CONTEXT=desktop-linux解決順は DEVBASE_EDITOR_SSH_HOST 明示 → ~/.vscode-server 自動検出 → フラット URI。
同一ホスト構成(手元 Mac/Linux で直接、または ssh 先の Docker にコンテナが無い場合)では ssh-remote ホストは付かず、従来どおりフラット URI で開きます。
コンテナが ssh 先とも別のホスト(例 WSL2)にあり、手元の VS Code 側にも同名の docker context があるなら、ssh 先を経由するネスト URI ではなく、手元の Dev Containers 拡張にその context で直接 attach させられます。DEVBASE_EDITOR_SSH_HOST を空文字で明示すると自動検出を行わず、settings.context 付きのフラット URI で code を起動します:
# projects/<name>/env(その context を使うプロジェクトだけに効かせる)
DEVBASE_EDITOR_SSH_HOST=前提は 2 つです。1 つは、code の実行先(手元の VS Code が docker CLI を呼ぶ側)で docker --context <ctx> ps がコンテナを返すこと。もう 1 つは、settings.context が devbase の解決した context(project.local.yml / --context / DEVBASE_DOCKER_CONTEXT)か DEVBASE_EDITOR_DOCKER_CONTEXT の明示から来ていることです。ssh 先の docker context show の推測だけに頼っている構成では、空文字にすると推測も行われず settings.context が付かない(手元の既定 daemon へ繋ぎに行く)ため、devbase up はこの案内を出しません。Windows の VS Code で dev.containers.executeInWSL が true なら WSL 内の CLI が使われるので、WSL 内に docker context create <ctx> --docker host=unix:///var/run/docker.sock で同名 context を作れば足ります。行を消せば自動検出(ネスト URI)に戻ります。
docker context useで現在の context 自体をリモートへ向けた状態は、これまでどおりの 動き(gid・~・スナップショットの補正なし)です。プロジェクトごとの設定を使ってくださいdevbase statusは手元の daemon だけを見ます。プロジェクトごとに daemon が違う構成の集約は していません- リモートのボリュームのスナップショットは扱いません
- Docker Desktop for Windows への直結は前提にしていません(WSL2 内の dockerd を使う)
VS Code は統合ターミナルごとに $TMPDIR/vscode-ipc-<uuid>.sock を作り、VSCODE_IPC_HOOK_CLI でその場所を伝えます。code はこのソケット経由でクライアント側の VS Code に依頼するため、ソケットが死んでいると code は何もできません。
tmux / screen はサーバープロセスがセッション作成時の環境変数を保持し続けるため、ここが噛み合いません。VS Code のウィンドウをリロードしたり開き直したりするとソケットは作り直されますが、既存の tmux セッションに再アタッチした端末は古いパスを引き継いだままになります。
devbase は実際にソケットへ接続できるかを確認してから VS Code 統合ターミナルと判定します(変数の有無でも、ファイルの実在でも判定しません)。
死んでいた場合、tmux 内なら tmux show-environment を見に行きます。update-environment(後述)を設定していれば、tmux のセッション環境は attach のたびに更新されるので、ペインのシェルが古くても tmux 側には生きた値が入っています。拾えた場合はその値を使い、起動する code にも渡します(変数を差し替えないと code 自身が古いソケットへ繋ぎに行って失敗するため)。
SSH 越しかどうかの判定も、tmux 内ではセッション環境の SSH_CONNECTION を見ます。SSH から立てた tmux サーバーに手元の端末から attach し直すと、ペインのシェルには SSH_CONNECTION が残りますが、セッション環境は -SSH_CONNECTION(いまのクライアントは SSH でない)に更新されます。SSH_CONNECTION は tmux の update-environment に既定で入っているので、設定は要りません。セッション環境から分からないとき(tmux 外・tmux の失敗)は、ペインのシェルの SSH_CONNECTION / SSH_CLIENT / SSH_TTY で判定します。
セッション環境から分かるいまのクライアントの SSH 状態が、ペインのシェルの SSH 状態(SSH_* の有無)と食い違うときは、向きによらず、ペインのシェルに残る VSCODE_IPC_HOOK_CLI はペインを作った以前のクライアントのものとみなし、そのウィンドウが開いたままで接続できても使いません。SSH から立てた tmux に手元から attach し直したときは、ホスト上のコンテナを開く URI がリモートのクライアントへ届いて開けず、手元で立てた tmux に Remote-SSH から attach し直したときは、SSH 先を経由する URI が Remote-SSH の接続を持たない手元の VS Code へ届いて開けないためです。tmux のセッション環境にいまのクライアントの生きた値が入っていれば、そちらを使います。入っていなければ IPC 無しとして扱い、SSH なら手元で実行するコマンドを示し、手元なら手元の code を起動します。食い違わないとき・セッション環境から分からないときは、ペインの値をこれまでどおり使います。死んだソケットを指す VSCODE_IPC_HOOK_CLI も、起動する code に渡しません。VSCODE_IPC_HOOK_CLI を外すときは、PATH から Remote-SSH などの remote-cli(~/.vscode-server/bin/<commit>/bin/remote-cli・~/.cursor-server/... など)を除いて手元の code を探します。remote-cli の code は VSCODE_IPC_HOOK_CLI が無いと何も開かずに終わるためです。手元の code が見つからなければ、起動せずにスキップします。
拾えなかった場合は警告を出したうえで「手元で実行するコマンドの提示」へ degrade するので、黙って何も起きないという状態にはなりません。提示されたコマンドを手元で実行すれば開けます。
ソケットの死に方は 2 通りあります。
| 状態 | 起きる場面 | ファイルの実在 |
|---|---|---|
| ファイルごと消えている | VS Code のウィンドウを正常に閉じた(VS Code が削除する) | 無し |
| ファイルは残っているが listen していない | VS Code のクラッシュ・強制終了・OS 再起動で後始末されなかった | 有り |
後者は $TMPDIR に孤児ソケットとして溜まり、接続しようとすると ECONNREFUSED になります。ls でも test -S でも生きているものと見分けが付かないため、生死の判定には実際の接続が要ります。
自動で開く状態に戻すには、tmux 側に環境変数を追随させます。~/.tmux.conf に以下を追記してください。
set -ga update-environment " VSCODE_IPC_HOOK_CLI VSCODE_GIT_IPC_HANDLE VSCODE_GIT_ASKPASS_NODE VSCODE_GIT_ASKPASS_MAIN VSCODE_GIT_ASKPASS_EXTRA_ARGS VSCODE_NONCE GIT_ASKPASS BROWSER TERM_PROGRAM"これで attach のたびに接続してきたクライアントの値でセッション環境が更新されます。devbase up にはこの設定だけで十分です(devbase がセッション環境を直接読むため)。
ただし更新されるのはセッション環境であり、すでに起動しているペインのシェルには波及しません。code を手で叩く、git の askpass を使うなど devbase 以外でも追随させたい場合は、シェルの rc(~/.bash_profile 等)にプロンプトフックを置きます。なお rc を書き換えても、すでに動いているシェルには反映されません(起動時に一度読むだけのため)。そのペインで直ちに効かせたいときは source ~/.bash_profile するか、開き直してください。
if [ -n "${TMUX:-}" ]; then
_vscode_sync_env() {
# ソケットが生きている間は拾い直さない。生存確認は 2 段で行う。
# -S はファイルの種別しか見ないため、listen していない孤児ソケットも
# 通過してしまう(上表の 2 つめ)。実際に接続できるかまで確認する。
# -S を前段に置くことで、ファイルが無い一般ケースでは nc を起動しない。
# macOS の nc は -z を付けると Unix ソケットで誤判定するので付けないこと。
[ -n "${VSCODE_IPC_HOOK_CLI:-}" ] && [ -S "${VSCODE_IPC_HOOK_CLI}" ] \
&& nc -U -w 1 "${VSCODE_IPC_HOOK_CLI}" </dev/null >/dev/null 2>&1 && return 0
local line
while IFS= read -r line; do
case "$line" in
VSCODE_IPC_HOOK_CLI=*|VSCODE_GIT_IPC_HANDLE=*|GIT_ASKPASS=*|BROWSER=*)
export "${line%%=*}=${line#*=}" ;;
esac
done < <(tmux show-environment 2>/dev/null)
return 0
}
case ";${PROMPT_COMMAND:-};" in
*";_vscode_sync_env;"*) ;;
*) PROMPT_COMMAND="_vscode_sync_env;${PROMPT_COMMAND:-}" ;;
esac
fi反映するには tmux kill-server でサーバーを作り直してください(~/.tmux.conf はサーバー起動時にのみ読まれ、既存ペインのシェルも修正前の rc で起動しているため)。
VS Code のウィンドウが異常終了すると、VS Code サーバー側に pty が取り残され、tmux クライアントだけがセッションへ繋がったまま残ります。統合ターミナルの起動スクリプトは「クライアントが繋がっているセッション = 使用中」と判定するため、adminer-1 に戻れず adminer-2, adminer-3 … と新しいセッションが増えていきます。
このときは dev コンテナに同梱の tmux-first を実行してください。放置されたクライアントを切断したうえで、一番若い番号のセッションへ現在の端末を切り替えます。
接続しているというだけでは居座りとは判定しません。切断対象は最終操作から TMUX_FIRST_IDLE 秒(既定 300)以上経過したクライアントだけで、いま使われている別ウィンドウの端末は残します(-f で全件切断)。
TMUX_FIRST_IDLE に指定できるのは 0 以上の整数だけです。負数・数値以外・空文字を指定すると、すべてのクライアントが放置扱いになってしまうため tmux-first はエラー終了します(既定値 300 が使われるのは未設定のときだけです)。
実行元の端末は必ず切断対象から除外します。ただしペイン内のシェルには「どのクライアントから起動されたか」の情報がないため、tmux が持つ「最終操作が最も新しいクライアント」を実行元とみなしています。プロンプトへ打ち込んで起動した場合はそのキー入力で最終操作が更新されるため必ず実行元自身になりますが、hook や tmux send-keys 経由でキー入力を伴わずに起動された場合は実行元を特定できません。特定できなかった場合は -f を付けていても切断を行わず、セッションの切り替えも行いません(実行元が分からないまま切り替えると、直近に操作された別の利用者の端末を切り替えてしまうためです)。このときは手動で切り替えるための tmux switch-client コマンドを表示します。
tmux-first # 現在のセッション名からベース名を推定 (adminer-2 -> adminer)
tmux-first -n # 切り替えず、対象と切断予定のクライアントだけ表示する
tmux-first -f # 操作中のクライアントも含めて切断する
TMUX_FIRST_IDLE=60 tmux-first # 放置とみなす秒数を変える
tmux1 # tmux-first の短縮コマンド (/usr/local/bin の symlink)誰がいつから繋いでいるかは次で確認できます。
tmux list-clients -F '#{client_name} -> #{client_session} 最終操作 #{t:client_activity}'切り替わったあと、そのセッションのプロンプトで tmux-clean を実行すると置き去りのセッションを削除できます。安全側の既定として、keeper(tmux 内なら現在のセッション、tmux 外なら最小番号)、アタッチ中のセッション、シェル以外を実行中のセッション、& で起動したバックグラウンドジョブが残っているセッションは残します。加えて、アタッチ数や pane の一覧を tmux から取得できなかったセッションも、実行中かどうか判断できないため残します。
tmux-clean # 不要なセッションを削除
tmux-clean -n # 削除せず、削除対象と除外理由を表示する
tmux-clean -f # アタッチ中・実行中のセッションも削除する
tmuxc # tmux-clean の短縮コマンド (/usr/local/bin の symlink)tmux-first / tmux-clean は同じベース名のセッションをまとめて扱い、使用中の端末と実行中のセッションを守ります。1 つのセッションを狙って操作するときは、dev コンテナに同梱の tmux-session を使います。守りの既定は無く、指したセッションに強制的に効きます。
| コマンド | すること |
|---|---|
tmux-go <セッション> |
そのセッションへ移り、そのセッションに繋がっている他の端末を外す。tmux の外では attach し、tmux の中では今の端末を切り替える |
tmux-peek <セッション> |
attach せずに調べる。繋がっている端末と最終操作の時刻、pane ごとのコマンド・pid・作業ディレクトリ、pane のシェルの子孫のプロセス(& で起動したものも)、画面の直近 20 行を出す。tmux の状態は変えない |
tmux-kill <セッション>... |
attach 中・実行中を問わず落とす。無いセッションは飛ばして残りを続け、終了コード 1 で終わる |
tmux-go devbase-3 # devbase-3 へ移る (devbase-30 には当たらない。名前は完全一致)
tmux-peek devbase-2 # 何が動いているかを見る
tmux-peek -n 50 devbase-2 # 画面を 50 行出す (-n 0 で出さない)
tmux-kill devbase-4 devbase-5
tmux-kill -n devbase-4 # 落とさずに、落とす予定だけを出す
tmux-kill -f devbase-2 # 今いるセッションも落とす (-f が無ければ落とさない)
tmux-session go devbase-3 # 短縮名と同じ。tmux-session peek / kill も同様- セッションは名前の完全一致か、ID(
$3の形)で指します。 名前が$と数字だけでできているセッションは、コマンドからは名前で指せません(ID として引くため)。下のprefix Sの一覧からは選べます - tmux の中で
tmux-goを使うと、プロンプトへ打ち込んだ端末を実行元とみなします(tmux-firstと同じ規則)。キー入力を伴わずに起動されて実行元を特定できないときは、何も外さず切り替えもせず、手で切り替えるコマンドを出して終了コード 1 で終わります
tmux の中では prefix S(既定では Ctrl+b → Shift+s)で、セッションの一覧から選んで同じ 3 つを呼べます。一覧は tmux の choose-tree で、v でプレビューの切り替え、f で絞り込み、x で 1 つ落とす、t で印を付けて X でまとめて落とす、といった tmux の既定の操作も使えます。セッションを選んで Enter を押すとメニューが出ます。
| メニュー | キー | すること |
|---|---|---|
| 移る(他の端末を外す) | a |
tmux-go と同じ。今の端末をそのセッションへ切り替える |
| 中身を見る | p |
tmux-peek の出力を浮いた窓に出す。Enter で閉じる |
| 落とす | k |
確認(y/n)を挟んで落とす。今いるセッションも、同意すれば落とす |
キーを覚えていなくても、tmux-menu を打てば prefix S と同じ一覧とメニューが開きます(tmux-session menu と同じ)。
tmux-menu # tmux の中: 今の pane に一覧を出す
# tmux の外: attach して、attach した画面に一覧を出す- tmux の外での attach 先は tmux の既定に従います(端末の繋がっていないセッションを優先し、その中で直近に使ったもの)。一覧からどのセッションへも移れます。名前の決まったセッションへ直接行くなら
tmux-goを使います - tmux のサーバが動いていないときは、サーバもセッションも作らずに理由を出して終了コード 1 で終わります
prefix S の割り当ては /etc/tmux.conf にあります。~/.tmux.conf で S を別の操作に割り当てていれば、後から読むそちらが勝ちます(コマンドはそのまま使えます)。
ホストの tmux で使う場合は、devbase の checkout の中のファイルへ symlink を張り、~/.tmux.conf へ 1 行足します(devbase はホストのこれらのファイルへ書き込みません)。複写ではなく symlink にすると、devbase を git pull するだけで更新が届きます。~/.local/bin が PATH に入っている必要があります。
DEVBASE_DIR=~/devbase # devbase を clone した場所
for n in tmux-session tmux-go tmux-peek tmux-kill tmux-menu; do
ln -sf "$DEVBASE_DIR/containers/base/tmux-session" ~/.local/bin/$n
done# ~/.tmux.conf に足す (反映は tmux source-file ~/.tmux.conf か tmux kill-server)
bind-key S run-shell "TMUX_PANE=#{pane_id} tmux-menu"以前の手順で bind-key S choose-tree … の行を足した人は、そのままでも prefix S は動きます。tmux-menu を使うには symlink の 5 つ目(tmux-menu)を足します。行は上の新しい形へ差し替えると、一覧の定義が tmux-session の 1 か所にそろいます。
dev コンテナで使うには、base イメージの建て直し(devbase build base --no-cache)と、使っている派生イメージの建て直し、コンテナの作り直し(devbase down → devbase up)が要ります。
サブコマンドごとの引数・終了コード・peek の出力・prefix S のメニューの仕様は
tmux のセッションを名指しで扱うコマンド(tmux-session) にあります。
devbase はソースファイル(~/.aws/config 等)のハッシュを .env.sources.yml で管理しています。
sequenceDiagram
participant User
participant devbase
participant SourceFile as ソースファイル
participant EnvFile as .env
User->>devbase: devbase env sync
devbase->>SourceFile: ハッシュを計算
devbase->>devbase: .env.sources.yml と比較
alt 変更あり
devbase->>SourceFile: ファイルを読み込み
devbase->>devbase: エンコード処理
devbase->>EnvFile: 環境変数を更新
devbase->>devbase: .env.sources.yml を更新
else 変更なし
devbase->>User: 変更なしを通知
end
devbase env syncを実行- 各コレクターのソースファイルのハッシュを計算
.env.sources.ymlに保存された前回のハッシュと比較- 変更が検出されたファイルのみ再エンコードして
.envを更新
OpenBao の backend では、キーごとに個人共通とチーム共通のうち、そのキーがある方を更新します
(両方にあれば個人共通、どちらにも無ければ個人共通)。詳細は devbase env sync を参照してください。
Note:
devbase env initを実行すると、全コレクターが初回として処理されます。
# 対話式で全コレクターを設定
devbase env init
# 既存の設定をリセットして再設定
devbase env init --reset# ソースファイルの変更を検出して更新
devbase env syncAWS や GCP の認証情報をホストマシンで更新した後に実行してください。
# 全変数のキーを表示
devbase env list
# グローバル変数のみ、値付きで表示
devbase env list -g -r
# プロジェクト変数をキー名順で表示
devbase env list -p -k# 値の取得
devbase env get AWS_PROFILE
# 値の設定(グローバル)
devbase env set ANTHROPIC_API_KEY=sk-xxx
# 値の設定(プロジェクトレベル)
devbase env set GCP_ACTIVE_PROFILE=my-project -p
# 値の削除
devbase env delete OLD_API_KEY# デフォルトエディタで .env を開く
devbase env edit$EDITOR 環境変数に設定されたエディタが使用されます。
# プロジェクト固有の変数を対話式で設定
devbase env projectコンテナ起動時(devbase up)に、3レベルの .env / env ファイルが Docker Compose の env_file ディレクティブ経由でコンテナに注入されます。
# コンテナ内で環境変数を確認
env | grep AWS_
# Base64 エンコードされた認証情報はコンテナ起動時に自動デコードされる
ls ~/.aws/Warning: 環境変数を変更した後は
devbase upでコンテナを再起動してください。起動中のコンテナには反映されません。
複数プロジェクトの .env 群を 1 つのバンドルにまとめ、暗号化したまま転送・復元するには devbase env export / devbase env import を使います。詳細は 環境変数の export/import ガイド を参照してください。
# 既存マシンで export (~/.ssh/id_ed25519.pub があれば鍵指定省略可)
devbase env export ./bundle.dbenv
# 新マシンで import (既定は keep-existing マージ)
devbase env import ./bundle.dbenv- 機密情報は
.envに格納する -- Git 管理対象のenvファイルには機密情報を含めない - プロジェクト固有の設定は
-pフラグを使う -- グローバル設定を汚染しない env syncを定期的に実行する -- ホストマシンの認証情報更新後は必ず同期.env.sources.ymlを Git 管理しない -- 環境固有のハッシュ情報のため- 別マシンへの移行は
devbase env exportを使う --scp -rで個別コピーする代わりに、暗号化バンドル 1 ファイルで安全に移動できる (詳細)