Open4

Docker Desktop+WSL2でのCodeBuildローカルビルド実行時のマウントポイントが稀に変わる謎

素人の戯言素人の戯言

ローカルでのCodeBuild内でさらにDockerコンテナを起動する(Docker out of Docker)際にソースをマウントするには、ホスト側のパスをマウントしなければならない。

ビルドコンテナであるagent-resources_build_1のinspectを見ると、ソースがマウントされているボリューム名はagent-resources_user_volumeのようである。

inspect
"Mounts": [
    {
        "Type": "volume",
        "Name": "agent-resources_user_volume",
        "Source": "/var/lib/docker/volumes/agent-resources_user_volume/_data",
        "Destination": "/codebuild/output",
        "Driver": "local",
        "Mode": "rw",
        "RW": true,
        "Propagation": ""
    },

しかしDocker Desktop+WSL2の場合、この実体であるはずの/var/lib/docker/volumes/agent-resources_user_volume/_dataは実際にはWSL上に存在しておらずどこか別に配置されているようで、この辺りはDocker DesktopがWSLでバインドマウントするための仕組みによるものと思われるが詳細未確認。

素人の戯言素人の戯言

純粋なLinuxで動かした場合は/var/lib/docker/volumes/agent-resources_user_volume/_data以下にソースがコピーされる。

ls -al /var/lib/docker/volumes/agent-resources_user_volume/_data/srcDownload/src
合計 **
drwxrwxr-x ** **** **** ****  **月 ** **:** .
drwxr-xr-x ** **** **** ****  **月 ** **:** ..
-rw-rw-r-- ** **** **** ****  **月 ** **:** buildspec.yml

これであればこのディレクトリをCodeBuild内でのDockerコンテナでのマウントボリュームとして指定すればソースを参照できるが、Docker Desktop+WSLでは上記の通りできない。

似たような問題として以下で報告されているが結局これ以上の改善策はなく、下記記事以外で同一問題についての議論を見かけなかったので、おそらくDocker Desktop等の環境を考慮した仕組みには需要もなく直す気もないなっていないように思われる。

素人の戯言素人の戯言

エージェント側のコンテナagent-resources_build_1を見ると、/run/desktop/mnt/host/wsl/docker-desktop-bind-mounts/以下にソースの実体をマウントしていると思われる情報がある。

inspect
"Mounts": [
    {
        "Type": "bind",
        "Source": "/run/desktop/mnt/host/wsl/docker-desktop-bind-mounts/Ubuntu/****",
        "Destination": "/codebuild/local/src",
        "Mode": "ro",
        "RW": false,
        "Propagation": "rprivate"
    },

しかしこのSourceのパスもまた存在しないが、先頭の/run/desktop/mnt/host/を/mnt/に置き換えてみるとソースがあることが確認できる。

ls -al /mnt/wsl/docker-desktop-bind-mounts/Ubuntu/****
合計 **
drwxrwxr-x ** **** **** ****  **月 ** **:** .
drwxr-xr-x ** **** **** ****  **月 ** **:** ..
-rw-rw-r-- ** **** **** ****  **月 ** **:** buildspec.yml

やや乱暴になるがdocker inspectと正規表現置換などを組み合わせれば、エージェントの情報からバインドマウントのパスを取り出せるように見える。

素人の戯言素人の戯言

しかし、何度か実行していると稀にエージェント側で/run/desktop/mnt/host/wsl/docker-desktop-bind-mounts/ではなく、オリジナルのソースコードがあるパスがSourceに指定されることがある(version 4.27.2 (137060))。

inspect
"Mounts": [
    {
        "Type": "bind",
        "Source": "/***/src",
        "Destination": "/codebuild/local/src",
        "Mode": "ro",
        "RW": false,
        "Propagation": "rprivate"
    },

発現条件は全く分からず完全にランダムなタイミングでこのようになるあたり、おそらくDocker Desktop側の何らかの内部エラーで/mnt以下にマウントポイントを作ることができず、代替手段としてオリジナルのパスが実体として呼ばれているように思えるが、なぜこのようになるか不明。

もしこの状態の時にコンテナでこのパスをマウントしてしまうと、オリジナルのファイルを操作できてしまったりファイルを作成できたりしてしまうので、たとえマウントができたとしてもあまり望ましくない。

現状回避策不明。