コンテナーに非ルートユーザーを追加する
多くの 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.json
で remoteUser
プロパティを指定することで、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