

devcontainerのremoteEnvでプロジェクト内の.devcontainer/binにPATHを通す
この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。
やりたかったこと
プロジェクト専用のちょっとしたスクリプトを .devcontainer/bin にまとめて置いておき、コンテナ内のターミナルからフルパスなしで叩けるようにしたかった。
Dockerfile で /usr/local/bin にコピーする手もあるけど、スクリプトを書き換えるたびにリビルドするのは面倒。ワークスペースをそのまま PATH に入れてしまえば、編集が即反映される。
結論
devcontainer.json の remoteEnv にこう書くだけで動いた。
{ "remoteEnv": { "PATH": "${containerWorkspaceFolder}/.devcontainer/bin:${containerEnv:PATH}" }}${containerWorkspaceFolder}はコンテナ内でのワークスペースのパスに展開される${containerEnv:PATH}はコンテナにもともと設定されている PATH に展開される
既存の PATH を後ろに残しつつ、.devcontainer/bin を先頭に足す形になる。先頭に置いているので、同名コマンドがあればこっちが優先される。
containerEnv ではなく remoteEnv を使う理由
devcontainer.json には環境変数の置き場が containerEnv と remoteEnv の2つある。
containerEnv:コンテナ作成時に設定される。コンテナ全体に効くが、この時点ではまだコンテナがないので${containerEnv:...}で既存の値を参照できないremoteEnv:ツール(VS Code など)がコンテナに接続してからプロセスを起動するときに設定される。コンテナ側の既存の環境変数を${containerEnv:...}で参照できる
既存の PATH に追記したいなら、参照ができる remoteEnv 一択になる。
remoteEnv が効く範囲
remoteEnv はツール経由で起動されたプロセスにだけ適用される。
flowchart LR
subgraph applied["remoteEnv が効く"]
T[VS Code ターミナル]
E[拡張機能]
L[postCreateCommand などのライフサイクルコマンド]
end
subgraph notApplied["remoteEnv が効かない"]
D[docker exec で直接入ったシェル]
C[ENTRYPOINT / CMD のプロセス]
end
普段の作業は VS Code のターミナルなので困らなかった。ただ、ホスト側から docker exec で入ったときに「コマンドが見つからない」となるのはこれが原因なので、そこは割り切る。
ハマりそうなところ
実行権限
.devcontainer/bin 配下のスクリプトには実行権限が必要。ローカルで chmod +x しただけだと、ほかの人の環境や Windows ホスト経由で権限が落ちることがあるので、Git に権限ごと記録しておくと安心。
git update-index --chmod=+x .devcontainer/bin/example-scriptログインシェルでの PATH 上書き
ターミナルをログインシェル(bash -l など)で起動する設定にしていると、ベースイメージによっては /etc/profile が PATH を組み立て直して、追加した分が消えることがあるらしい。自分の環境では起きなかったので実機未確認。PATH が効いていないときは、まずシェルの起動方法を疑うといい。