ツー

日常の記録

devcontainerでホスト側のファイル権限がrootになる問題の対処

結果、Dockerのコンテナ作成にだけ気を付ければよかった。

気を付けるべきことは1点

devcontainerで使うコンテナは root ではなく何かしらのユーザーを作成して設定しておけば、あとはdevcontainerが空気を読んでホスト側とコンテナ内のファイルの橋渡しをしてくれる。

具体的には DockerfileUSER を設定すればよく、devcontainer.json は修正しないでよい。

以下はメモ。

調べたこと色々

ホストのファイル所有者がrootになる

devcontainerを使うと、ホスト側は一般ユーザ、コンテナ側は root なので、コンテナ側からファイルを書き込みに行くとホスト側で root で書き込まれることになり、ホスト側に戻ってファイルの編集しようとすると書き込めない事象が発生する。

なんで??と思ったけれど色々な黒魔術があってそうなってるっぽい。

公式による対処法

このことは既知の問題で公式ページにもちゃんと対処法が書いてある。 code.visualstudio.com

対処法はコンテナにユーザを作ってそれを使うようにするだけ。Dockerfile に下記を加えればよい。

上記サイトより抜粋。

ARG USERNAME=user-name-goes-here
ARG USER_UID=1000
ARG USER_GID=$USER_UID

# Create the user
RUN groupadd --gid $USER_GID $USERNAME \
    && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
    #
    # [Optional] Add sudo support. Omit if you don't need to install software after connecting.
    && apt-get update \
    && apt-get install -y sudo \
    && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
    && chmod 0440 /etc/sudoers.d/$USERNAME

USER $USERNAME

注意点が一つあって、ホスト側のUIDとコンテナ側のUIDが被らないようにすること。UIDが被っていなければホスト側とコンテナ側でファイル書き込み時によしなにしてくれるが、UIDが被っているとよしなにしてくれずにrootの時と同様の問題が起こる。

ohayoyogi.hatenablog.com

調べたところ、MacOSのユーザはUID=500, WSLのユーザはUID=1000で作成されるらしいので、被らないようにUID=1234としておいた。被っても変えればいいだけだけど。

ファイルの書き込みで変な動作をしたときはここも疑うようにしよう。

useraddがない

今回コンテナ内OSはAmazon Linuxを使っていたが、Dockerfile 内でユーザ作成の時に useraddgroupadd が無いと言われる。

ただ無いだけなのでインストールすればよい。shadow-utils というパッケージ内にある。

yum install -y shadow-utils

remoteUserの指定は不要

上記の設定と共に devcontainer.jsonremoteUser を設定したり、 updateRemoteUserUIDtrue にしろと書いてある記事が多いが、結果として devcontainer.json は変更しないでよかった。

どうやら updateRemoteUserUID のデフォルトは true なので、ファイル書き込み時によしなにするのは勝手に設定を読んで勝手にやってくれているっぽい。

つまりはコンテナ内にユーザさえ作っておけば後はユーザで動くようになるという感じ。

まとめ

devcontainer便利だけど、この先使っていってトラブったときがめんどくさそうだな。

参考

containers.dev zenn.dev blog.pinkumohikan.com