🐳

Docker実行時に"Permission denied"といわれたらチェックすべき項目5つ

2024/02/16に公開

Dockerで docker compose up, docker compose build, makemigrations, migrateなど行う際 Permission deniedというエラーが発生する場合があります。
単に権限がないわけではなく、複数の理由が考えられるので、一例を下記に記してみます。

1.そもそもディレクトリ or ファイルがDockerイメージ内に生成されていない

Dockerfileに対象のディレクトリやファイルを生成するコードが含まれていないかもしれません。
ビルド時にディレクトリやファイルを生成するにはDockerfileに下記のような命令を加えます。

# ディレクトリを生成
RUN mkdir 対象のディレクトリ

# ファイルを生成
RUN touch 対象のファイル

2.パスが間違っている

ディレクトリやファイルはあるが、パスが間違っている...という場合にもこのエラーが生じるようです。
例えば下記は/usr/src/appをプロジェクトディレクトリとし、直下にtestというディレクトリおよびファイルをコンテナ内に生成することを期待するコードの一部です。これらが完全一致していないとエラーになる可能性があります。

ENV APP_HOME=/usr/src/app

RUN mkdir $APP_HOME/test
services:
  サービス名:
    build: ./
    working_dir: /usr/src/app/
    volumes:
        - .:/usr/src/app

3.権限がない

ディレクトリやファイルを生成されている、パスも間違っていない、けれどPermission deniedと出る場合はそのディレクトリやファイルへのアクセス権限がない可能性があります。
アクセス権限はDockerfile内で例えば下記のように定義できます。

...中略...

RUN addgroup -S myuser && \
    adduser -S myuser -G myuser && \
    chown -R myuser:myuser $APP_HOME
USER myuser

このコマンドはざっと説明すると1行ずつ下記の操作を行っています。

  1. myuserという名前のグループを作り、
  2. そこにmyuserという名前のユーザーを作成・追加し、
  3. myuserグループおよびmyuserユーザーに$APP_HOMEディレクトリの読み書きの権限を与える
  4. myuserユーザーとして一連の操作を実行する

上記はユーザーに権限を与えてディレクトリやファイルを操作するアプローチですが、下記はディレクトリやファイルのアクセス権限を直接操作するアプローチです。

RUN chmod u+w $APP_HOME/test

chmodコマンドはコマンドラインで操作するLinuxコマンドと同じ文法で使います。

権限が付与できないケース

残念ながらこれらの操作を行ってもアクセス権が得られない場合があるようです。
仮想サーバー(例えばAmazon EC2インスタンス)上でDockerコンテナを実行する場合、Dockerの操作と仮想サーバーのセキュリティ設定は異なるレイヤーに位置します。
それらの仮想サーバーの設定(ネットワークアクセス設定、セキュリティグループ、ファイアウォール設定など)が、Dockerコンテナのアクセス可能性に影響を与えている場合は、Dockerからは操作できません。
その場合はサーバーの管理者に話して権限をもらう必要があります。

4.それ必要?

「そもそもそのディレクトリ・ファイルに書き込みを行う処理は本当に必要?」と考えてみるのも選択肢の一つです。
必要ないのであれば書き込みを行う処理を排除するのもありです。

5.その他

変更した設定が反映されていない可能性があります。
例えばdocker compose buildにはオプションをつけてdocker compose build --no-cacheとするとキャッシュをクリアして実行できます。

Discussion