私の環境
- Ubuntu 20.04 on WSL2
- Docker 23.0.2(↑のUbuntuにインストール)
- docker-compose 2.17.2
はじめにやったこと
シンプルに公式のnodeイメージをpullして使うだけのDockerfileで、ホスト側(ubuntu)のディレクトリをコンテナにvolumeとしてマウントしようとしました。
FROM node:19.8
WORKDIR /app
version: '3'
services:
node-dev:
build:
context: .
dockerfile: Dockerfile
tty: true
volumes:
- .:/app
ホスト側のカレントディレクトリをコンテナ側のappディレクトリとしてマウントは問題なくできましたが、コンテナ側で作成したファイルをホスト側で編集しようとすると、Permission Deniedで保存ができませんでした。
原因
コンテナ実行時のuserを指定していなかったため、ホスト側(UID=1000)とコンテナ側(UID=0)で別ユーザーとなってしまっていた。
ホスト(Ubuntu)側
$ id
uid=1000(hayato) gid=1000(hayato) groups=1000(hayato),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),116(netdev),1001(docker)
コンテナ側
root@e424e34aa8ce:/app# id
uid=0(root) gid=0(root) groups=0(root)
コンテナ側で作成したファイルのownerはUID=0で、
ホスト側だとrootユーザーになる。
$ ls -la
total 16
drwxr-xr-x 2 hayato hayato 4096 Apr 6 21:30 .
drwxr-xr-x 5 hayato hayato 4096 Apr 4 21:51 ..
-rw-r--r-- 1 root root 0 Apr 6 21:30 CreatedInContainer.txt
-rw-r--r-- 1 hayato hayato 28 Apr 6 21:29 Dockerfile
-rw-r--r-- 1 hayato hayato 133 Apr 6 21:28 docker-compose.yml
一般ユーザーにrootが作ったファイルの更新権限はないのでPermission Deniedとなる。
対策
コンテナにログインするときのデフォルトユーザーをホスト側と合わせる
- .envファイルを作ってホスト側のUID・GID・USERNAMEをdocker-compose.ymlに渡す
- docker-composeのuserオプションで↑を指定する
$ ls -la
total 20
drwxr-xr-x 2 hayato hayato 4096 Apr 6 21:44 .
drwxr-xr-x 5 hayato hayato 4096 Apr 4 21:51 ..
-rw-r--r-- 1 hayato hayato 34 Apr 6 21:43 .env
-rw-r--r-- 1 hayato hayato 28 Apr 6 21:29 Dockerfile
-rw-r--r-- 1 hayato hayato 133 Apr 6 21:28 docker-compose.yml
UID=1000
GID=1000
USERNAME=hayato
version: '3'
services:
node-dev:
user: $UID:$GID
build:
context: .
args:
UID: $UID
GID: $GID
USERNAME: $USERNAME
dockerfile: Dockerfile
tty: true
volumes:
- .:/app
コンテナ側に同じUIDがいない場合はこれもやる
- DockerfileにARGコマンドでUID・GID・USERNAMEを渡す
- DockerfileでRUNコマンドを実施してgroupadd、useraddして同じUID/GIDのユーザーを作る
# 同じUIDが存在しないイメージ
FROM ubuntu
WORKDIR /app
ARG UID
ARG GID
ARG USERNAME
ENV UID ${UID}
ENV GID ${GID}
ENV USERNAME ${USERNAME}
RUN groupadd -g ${GID} ${USERNAME}
RUN useradd -u ${UID} -g ${USERNAME} -m ${USERNAME}
結果
無事に、ユーザーを合わせられました。
ホスト(Ubuntu)側
$ id
uid=1000(hayato) gid=1000(hayato) groups=1000(hayato),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),116(netdev),1001(docker)
コンテナ側
hayato@bd07b1769196:/app$ id
uid=1000(hayato) gid=1000(hayato) groups=1000(hayato)
コンテナで作ったファイルのowner
$ ls -la CreatedInContainer2.txt
-rw-r--r-- 1 hayato hayato 0 Apr 6 22:11 CreatedInContainer2.txt
参考
https://docs.docker.jp/compose/environment-variables.html
https://zenn.dev/takitakit/articles/a929a4f64aaae4