本記事は、intimatemerger Advent Calendar 2023 13 日目の記事です。
はじめに
こんにちは。
Intimate Merger のFukudaです。
今回は、コンテナ開発時に発生するファイルパーミッションの問題に関する記事です。
ローカルのディレクトリをコンテナのディレクトリにマウントして開発することがあると思います。
この時、ファイル編集時にパーミッションの問題により、ファイルを保存できないなどの問題が発生したことはありませんか?
Dockerを使ってまもない頃の私はよく悩まされていました。
本記事ではこの問題を解決していきます。
準備するファイル
directory
├── docker-compose.yml
├── src-1
│ ├── app/
│ └── Dockerfile
└── src-2
├── app/
└── Dockerfile
FROM ubuntu:22.04
COPY ./app /usr/src/app
FROM ubuntu:22.04
ARG UID=1000
ARG GID=1000
ARG USERNAME=app
ARG GROUPNAME=app
RUN groupadd -g $GID $GROUPNAME && \
useradd -m -u $UID -g $GID $USERNAME
COPY --chown=$UID:$GID ./app/ /usr/src/app
WORKDIR /usr/src/app
USER $USERNAME
version: '3'
services:
app-1:
build:
context: src-1
dockerfile: Dockerfile
volumes:
- ./src-1/app:/usr/src/app
tty: true
app-2:
build:
context: src-2
dockerfile: Dockerfile
args:
UID: 1000
GID: 1000
USERNAME: app
GROUPNAME: app
volumes:
- ./src-2/app:/usr/src/app
tty: true
検証
docker-composeを使ってコンテナを起動させておきます。
$ docker-compose up --build
コンテナが起動したか確認します。
$ docker-compose ps
NAME COMMAND SERVICE STATUS PORTS
advent-app-1-1 "/bin/bash" app-1 running
advent-app-2-1 "/bin/bash" app-2 running
パーミッションエラーを再現
app-1
でパーミッションエラーを再現することができます。
実際にやってみましょう!
コンテナ側でtext
というファイルを作成します。
$ docker-compose exec -it app-1 touch text
ボリュームを共有しているので、ローカル側の./src-1/app/
の中にもtext
というファイルが存在します。
$ tree src-1
src-1
├── app
│ └── text # 作成したファイル
└── Dockerfile
作成したtext
をローカル側から編集してみましょう。
"XXXXX"
という文字列の書き出すコマンドを実行します。
Permission denied
と出力されました。
$ echo "XXXXX" > ./src-1/app/text
bash: ./src-1/app/text: Permission denied
原因
ls -l
コマンドを使ってファイルのアクセス権を確認してみます。
$ ls -l ./src-1/app/text
-rw-r--r-- 1 root root 0 Dec 11 22:59 ./src-1/app/text
このファイルに書き込みできるのはファイルの所有者であるroot
のみのようです。
他のユーザーには読み取りのアクセス権のみ与えられています。
id
コマンドを使って、コンテナ側のユーザーとホスト側のユーザーID(UID)とグループID(GID)を見てみます。
# ホスト側
$ id
uid=1000(local-user) gid=1000(local-user) groups=1000(local-user)
# コンテナ側
$ id
uid=0(root) gid=0(root) groups=0(root)
- ホストのユーザー:
1000(local-user)
- コンテナのユーザー:
0(root)
ホスト側とコンテナ側でUID/GIDが異なるため、ファイルのPermissionエラーが発生しているということがわかります。
解決策
解決策は、ホストマシンとコンテナのユーザー権限を一致させることです。UID/GIDを同じにし、適切な権限を与えることで問題を解消できます。
ユーザー・グループを作成する
RUN groupadd -g $GID $GROUPNAME && \
useradd -m -u $UID -g $GID $USERNAME
作成したユーザーに権限を与える
COPY --chown=$UID:$GID ./app/ /usr/src/app
ファイルの編集ができるか確かめる
さきほどと同様にコンテナ側からファイルを作成します。
$ docker-compose exec -it app-2 touch text
ホスト側からファイルに書き込んでみます。
app-1
と違いファイルへの書き込みが成功しました。
$ echo "XXXXX" > ./src-2/app/text
まとめ
ローカルのディレクトリをコンテナのディレクトリにマウントして開発する際に生じるパーミッションの課題について取り上げました。
コンテナ内で作成したファイルをローカルで編集しようとすると、UID/GIDの不一致が原因でPermissonエラーが発生します。
ユーザーとグループを作成し、ファイルのアクセス権をローカルと合わせることでパーミッションの問題を解決できました。
あとがき
読んでいただきありがとうございました!
次回の記事はkeywordについてのようです。