8
4

Dockerコンテナで開発時のパーミッションエラーについて

Last updated at Posted at 2023-12-12

本記事は、intimatemerger Advent Calendar 2023 13 日目の記事です。

はじめに

こんにちは。
Intimate Merger のFukudaです。

今回は、コンテナ開発時に発生するファイルパーミッションの問題に関する記事です。
ローカルのディレクトリをコンテナのディレクトリにマウントして開発することがあると思います。
この時、ファイル編集時にパーミッションの問題により、ファイルを保存できないなどの問題が発生したことはありませんか?

Dockerを使ってまもない頃の私はよく悩まされていました。
本記事ではこの問題を解決していきます。

準備するファイル

directory
├── docker-compose.yml
├── src-1
│   ├── app/
│   └── Dockerfile
└── src-2
    ├── app/
    └── Dockerfile
./src-1/Dockerfile
FROM ubuntu:22.04

COPY ./app /usr/src/app
./src-2/Dockerfile
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
docker-compose.yml
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についてのようです。

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4