VS Codeのエージェントモードを拡張するには、を試してください!

コンテナーに非ルートユーザーを追加する

多くの Docker イメージでは root が既定のユーザーとして使用されますが、代わりに非ルート ユーザーを使用したい場合もあります。そうする場合は、ローカル ファイルシステム (バインド) マウントにはいくつかの注意点があります。具体的には

  • Docker Desktop for Mac: コンテナー内では、マウントされたファイル/フォルダーは、指定したコンテナー ユーザーが所有しているかのように動作します。ローカルでは、すべてのファイルシステム操作はローカル ユーザーのアクセス許可を使用します。

  • Docker Desktop for Windows: コンテナー内では、マウントされたファイル/フォルダーは root が所有しているかのように見えますが、指定したユーザーはそれらを読み書きでき、すべてのファイルは実行可能になります。ローカルでは、すべてのファイルシステム操作はローカル ユーザーのアクセス許可を使用します。これは、Windows スタイルのファイルアクセス許可を Linux に直接マッピングする方法が根本的にないためです。

  • Linux 上の Docker CE/EE: コンテナー内では、マウントされたファイル/フォルダーは、所有者ユーザー ID (UID) およびグループ ID (GID) を含め、コンテナーの外部とまったく同じアクセス許可を持ちます。このため、コンテナー ユーザーは同じ UID を持つか、同じ GID を持つグループに属している必要があります。ユーザー/グループの実際の名前は関係ありません。通常、マシンの最初のユーザーは UID 1000 を取得するため、ほとんどのコンテナーはこの問題を回避するためにユーザーの ID としてこれを使用します。

VS Code のユーザーを指定する

使用しているイメージまたは Dockerfile が既にオプションの非ルート ユーザーを提供している (node イメージなど) が、まだ root が既定である場合は、devcontainer.jsonremoteUser プロパティを指定することで、Visual Studio Code (サーバー) とすべてのサブプロセス (ターミナル、タスク、デバッグ) がそれを使用するように選択できます。

"remoteUser": "user-name-goes-here"

Linux で devcontainer.json 内でDockerfile、イメージ、または Docker Compose を参照している場合、この設定により、コンテナー ユーザーの UID/GID がローカル ユーザーと一致するように自動的に更新され、この環境に存在するバインド マウントのアクセス許可の問題が回避されます ("updateRemoteUserUID": false に設定しない限り)。

この設定は VS Code と関連するサブプロセスにのみ影響するため、変更を有効にするには VS Code を再起動 (またはウィンドウを再読み込み) する必要があります。ただし、UID/GID の更新はコンテナーの作成時にのみ適用され、変更するにはリビルドが必要です。

既定のコンテナー ユーザーを指定する

場合によっては、VS Code だけでなく、コンテナー内のすべてのプロセスを別のユーザーとして実行する必要がある場合があります (たとえば、起動要件のため)。これを行う方法は、Docker Compose を使用しているかどうかによって若干異なります。

  • Dockerfile とイメージ: 同じファイルに containerUser プロパティを追加します。

    "containerUser": "user-name-goes-here"
    

    Linux では、remoteUser と同様に、コンテナー ユーザーの UID/GID がローカル ユーザーと一致するように自動的に更新され、この環境に存在するバインド マウントのアクセス許可の問題が回避されます ("updateRemoteUserUID": false に設定しない限り)。

  • Docker Compose: 適切なサービスに対して、docker-compose.yml を次のように更新 (または拡張) します。

    user: user-name-or-UID-goes-here
    

非ルート ユーザーを作成する

Dev Containers 拡張機能から提供されるイメージまたは Dockerfile には、UID/GID が 1000 の非ルート ユーザー (通常は vscode または node と呼ばれる) が含まれますが、多くのベース イメージと Dockerfile には含まれません。幸いなことに、Dockerfile を更新または作成して、コンテナーに非ルート ユーザーを追加できます。

アプリケーションを非ルート ユーザーとして実行することは、運用環境でも推奨されます (より安全であるため)。そのため、既存の Dockerfile を再利用している場合でも良いアイデアです。たとえば、Debian/Ubuntu コンテナーのこのスニペットは、user-name-goes-here というユーザーを作成し、sudo を使用する機能を与え、既定として設定します。

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

# ********************************************************
# * Anything else you want to do like clean up goes here *
# ********************************************************

# [Optional] Set the default user. Omit if you want to keep the default as root.
USER $USERNAME

ヒント: ビルド時に GID または UID が既に存在するというエラーが発生した場合、選択したイメージには、直接利用できる非ルート ユーザーが既に存在する可能性が高いです。

いずれの場合も、コンテナーを既にビルドして接続している場合は、コマンド パレット (F1) からDev Containers: コンテナーをリビルド を実行して変更を適用します。そうでない場合は、Dev Containers: コンテナーでフォルダーを開く... を実行してコンテナーに接続します。

既存のコンテナー ユーザーの UID/GID を変更する

remoteUser プロパティは、Linux でDockerfile またはイメージを使用している場合に、必要に応じて UID/GID を自動的に更新しようとしますが、このスニペットを Dockerfile で使用して、ユーザーの UID/GID を手動で変更することもできます。ARG の値を適切に更新してください。

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

RUN groupmod --gid $USER_GID $USERNAME \
    && usermod --uid $USER_UID --gid $USER_GID $USERNAME \
    && chown -R $USER_UID:$USER_GID /home/$USERNAME

Alpine Linux では、最初に shadow パッケージをインストールする必要があることに注意してください。

RUN apk add --no-cache shadow