Dockerコンテナで「Permission denied」エラーを解決する方法

Dockerは、アプリケーションをコンテナ化して効率的に管理するための強力なツールですが、コンテナ内で「Permission denied」エラーに遭遇することはよくあります。このエラーは、ファイルやディレクトリへのアクセス権限が不足している場合に発生します。

この記事では、Dockerコンテナでの「Permission denied」エラーの原因とその解決策について詳しく解説します。

1. Permission Deniedエラーの基本理解

「Permission denied」エラーは、Dockerコンテナがホストマシンのファイルシステムにアクセスしようとしたときに、適切な権限がないために発生します。このエラーは、特にボリュームマウントやファイルコピーの際に一般的です。

1.1. エラーの発生例

以下は、Dockerコンテナ内でファイルを作成しようとした際に発生するエラーの一例です。

$ docker-compose up
Creating network "default" with the default driver
Creating container ... done
Attaching to container
container | touch /usr/src/app/test.txt
container | bash: /usr/src/app/test.txt: Permission denied

このエラーは、コンテナが/usr/src/appディレクトリに書き込む権限を持っていないことを示しています。

2. Permission Deniedエラーの原因

2.1. UID/GIDの不一致

ホストマシンとコンテナ内のユーザーID(UID)やグループID(GID)が異なる場合、ファイルのアクセス権限に問題が生じることがあります。例えば、ホスト側のユーザーがUID 1000で、コンテナ内のユーザーがUID 0(root)の場合、ホスト側で作成したファイルに対してコンテナがアクセスできないことがあります。

# ホスト側のユーザー情報
$ id
uid=1000(local-user) gid=1000(local-user) groups=1000(local-user)

# コンテナ側のユーザー情報
# コンテナはデフォルトでrootユーザーで実行される
# uid=0(root) gid=0(root)

2.2. ボリュームマウントの権限

ボリュームをマウントする際、ホスト側のディレクトリやファイルの権限がコンテナ内でのアクセスに影響を与えます。ホスト側のファイルがrootユーザーによって所有されている場合、コンテナ内の非特権ユーザーはそのファイルにアクセスできません。

3. Permission Deniedエラーの解決策

3.1. UID/GIDを一致させる

ホストとコンテナのUID/GIDを一致させることで、権限の問題を解決できます。以下の手順で、Dockerfileを修正してユーザーを作成し、ファイルの所有権を変更します。

# Dockerfile
FROM ubuntu:22.04

# ユーザーとグループを作成
ARG UID=1000
ARG GID=1000
RUN groupadd -g $GID appgroup && \
    useradd -m -u $UID -g appgroup appuser

# 作成したユーザーで実行
USER appuser

# アプリケーションのコピー
COPY --chown=appuser:appgroup ./app /usr/src/app

このDockerfileでは、ホスト側のユーザーと同じUID/GIDを持つappuserを作成し、アプリケーションをそのユーザーの権限でコピーしています。

3.2. ボリュームの権限を変更する

ボリュームマウントを使用する場合、ホスト側のディレクトリの権限を変更することも重要です。以下のコマンドを使用して、ホスト側のディレクトリの所有者を変更します。

# ホスト側でのコマンド
sudo chown -R 1000:1000 ./src/app

これにより、ホスト側の./src/appディレクトリがUID 1000のユーザーに所有され、コンテナ内のユーザーがアクセスできるようになります。

3.3. Docker Composeの設定

Docker Composeを使用している場合、docker-compose.ymlファイルでボリュームの設定を行います。以下は、ボリュームをマウントする際の設定例です。

version: '3'
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./src/app:/usr/src/app
    tty: true

この設定により、ホスト側の./src/appがコンテナ内の/usr/src/appにマウントされます。

4. 具体的なエラー解決の手順

以下に、実際に「Permission denied」エラーを解決するための具体的な手順を示します。

4.1. Dockerfileの作成

まず、Dockerfileを作成し、ユーザーを設定します。

# Dockerfile
FROM ubuntu:22.04

ARG UID=1000
ARG GID=1000

RUN groupadd -g $GID appgroup && \
    useradd -m -u $UID -g appgroup appuser

COPY --chown=appuser:appgroup ./app /usr/src/app

USER appuser

4.2. Docker Composeファイルの作成

次に、docker-compose.ymlファイルを作成します。

version: '3'
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./src/app:/usr/src/app
    tty: true

4.3. ホスト側の権限を変更

ホスト側のディレクトリの権限を変更します。

sudo chown -R 1000:1000 ./src/app

4.4. コンテナの起動

最後に、Docker Composeを使用してコンテナを起動します。

docker-compose up --build

これで、コンテナ内での「Permission denied」エラーが解消されるはずです。

5. まとめ

Dockerコンテナでの「Permission denied」エラーは、主にUID/GIDの不一致やボリュームマウントの権限に起因します。これらの問題を解決するためには、ホストとコンテナのユーザー権限を一致させ、適切な権限を設定することが重要です。以下のポイントを再確認しましょう。

  • UID/GIDの一致: ホストとコンテナのユーザーIDを一致させる。
  • ボリュームの権限変更: ホスト側のディレクトリの権限を適切に設定する。
  • DockerfileとDocker Composeの設定: ユーザー権限を考慮した設定を行う。

これらの対策を講じることで、Dockerコンテナでの「Permission denied」エラーを効果的に解決できます。

参考

タイトルとURLをコピーしました