🌊

Docker環境のファイル所有者・proccess 実行ユーザーを調べてみた@USER命令 / コンテナ実行 / マウント時の

2024/10/22に公開

はじめに

Docker環境のファイル所有者・proccess 実行ユーザーについて実験したことを取り留めなく調べたことを記述していきます。Dockerのことについては詳しく触れていきません。

構成

Nginxコンテナ -> Laravelコンテナ という2つのコンテナを起動します。

Dockerfile/docker-compose.ymlのベース部分

繰り返し表示することになってしまうので、ベース部分を先に表示します。
各Caseでは、差分のみを後述します

dockerfile

FROM php:8.2-fpm

COPY ./docker/env/local/api/php.ini /usr/local/etc/php/
COPY ./api /var/www/src

RUN apt-get update && apt-get -y upgrade
RUN apt-get install -y zip \ 
    unzip \
    vim \
    procps \
    && docker-php-ext-install pdo_mysql

# composerのインストール
RUN curl -sS https://getcomposer.org/installer | php \
  && mv composer.phar /usr/local/bin/composer \
  && chmod +x /usr/local/bin/composer

ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
ENV PATH $PATH:/composer/vendor/bin

WORKDIR /var/www/src

docker-compose.yml

  api:
    build:
      context: .
      dockerfile: ./docker/env/local/api/Dockerfile
    container_name: g-api
    volumes:
      - ./api/.env.local:/var/www/src/.env

Docker環境のファイル所有者・proccess 実行ユーザーを確認

Case1:rootユーザーでdockerImageビルド -> dockerConntainer起動

dockerfile

※ベース部分のまま

docker-compose.yml

※ベース部分のまま

ファイル所有者・proccess 実行ユーザー

コンテナ実行ユーザー:root
master process ユーザー:root
worker process ユーザー:www-data
ファイル所有者:root

※ dockerでUSERを指定していない場合は、defaultの状態だと、rootユーザーがコンテナ実行者
php-fpmのmasterプロセスはrootユーザー、workerプロセスはwww-dataも一般的です。 Dockerfileのベースとしている、php:8.2-fpmにwww-dataの設定処理も含まれています。

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2  82692 21820 ?        Ss   10:54   0:00 php-fpm: master process (/usr/local/etc/php-fpm.conf)
www-data     7  0.0  0.1  84740 15204 ?        S    10:54   0:00 php-fpm: pool www
www-data     8  0.0  0.1  84740 15204 ?        S    10:54   0:00 php-fpm: pool www
root         9  0.0  0.0   4060  3304 pts/0    Ss   10:54   0:00 bash
root        19  0.0  0.0   8048  3648 pts/0    R+   10:58   0:00 ps aux
// 一部省略
root@b9e1f52a8a18:/var/www/src# ls -la
drwxr-xr-x 12 root root   4096 Oct 13 06:53 .
drwxr-xr-x  1 root root   4096 Oct 22 03:44 ..
-rw-r--r--  1 root root   1213 Oct 13 06:53 .env
drwxr-xr-x  8 root root   4096 Jul 22 11:43 app
drwx------  3 root root   4096 Jul  8 10:30 bootstrap
drwxr-xr-x  2 root root   4096 Jul  8 10:30 public
drwxr-xr-x  2 root root   4096 Aug 30 10:52 routes
drwx------  5 root root   4096 Jul  8 10:30 storage

結果

※ php-fpmの[worker process]はwww-dataユーザー VS ファイル所有者がrootなのでstorage書き込み権限が存在せずにerrorとなる

Warning: require_once(/var/www/src/public/../bootstrap/app.php): Failed to open stream: Permission denied in /var/www/src/public/index.php on line 49

Fatal error: Uncaught Error: Failed opening required '/var/www/src/public/../bootstrap/app.php' (include_path='.:/usr/local/lib/php') in /var/www/src/public/index.php:49 Stack trace: #0 {main} thrown in /var/www/src/public/index.php on line 49

Case2:rootユーザーでdockerImageビルド -> dockerConntainer起動だが、ホスト環境からマウント

Dockerfileは変わらずにapplicationのソースコードをホスト環境からマウントします。

dockerfile

# COPY ./api /var/www/src -->> 削除

docker-compose.yml

ホスト環境からマウントします。

  api:
    build:
      context: .
      dockerfile: ./docker/env/local/api/Dockerfile
    container_name: g-api
    volumes:
      - ./api:/var/www/src
      # laravelの.envファイルをマウント
      - ./api/.env.local:/var/www/src/.env

ファイル所有者・proccess 実行ユーザー

コンテナ実行ユーザー:root
master process ユーザー:root
worker process ユーザー:www-data
ファイル所有者:root

root@c9b354ea8736:/var/www/src# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2  82692 21820 ?        Ss   11:09   0:00 php-fpm: master process (/usr/local/etc/php-fpm.conf)
www-data     7  0.0  0.3  91544 24756 ?        S    11:09   0:00 php-fpm: pool www
www-data     8  0.0  0.3  91544 24760 ?        S    11:09   0:00 php-fpm: pool www
root        17  0.5  0.0   4060  3288 pts/0    Ss   11:24   0:00 bash
root        23  0.0  0.0   8048  3648 pts/0    R+   11:24   0:00 ps aux

ファイルの所有者もrootになりました。

// 一部省略
root@b9e1f52a8a18:/var/www/src# ls -la
drwxr-xr-x 12 root root   4096 Oct 13 06:53 .
drwxr-xr-x  1 root root   4096 Oct 22 03:44 ..
-rw-r--r--  1 root root   1213 Oct 13 06:53 .env
drwxr-xr-x  8 root root   4096 Jul 22 11:43 app
drwx------  3 root root   4096 Jul  8 10:30 bootstrap
drwxr-xr-x  2 root root   4096 Jul  8 10:30 public
drwxr-xr-x  2 root root   4096 Aug 30 10:52 routes
drwx------  5 root root   4096 Jul  8 10:30 storage

Case3:rootユーザーでdockerImageビルド  + ファイル所有者をwww-dataへ変更 -> dockerConntainer起動

ファイルの所有者を www-dataに変えてみます。

dockerfile

RUN chown -R www-data:www-data /var/www/src

docker-compose.yml

※ベース部分のまま
マウントは削除します。

ファイル所有者・proccess 実行ユーザー

コンテナ実行ユーザー:root
master process ユーザー:root
worker process ユーザー:www-data
ファイル所有者:root / www-data

変わらずです。

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2  82692 21820 ?        Ss   11:31   0:00 php-fpm: master process (/usr/local/etc/php-fpm.conf)
www-data     7  0.0  0.3  95640 28872 ?        S    11:31   0:00 php-fpm: pool www
www-data     8  0.0  0.3  95640 28872 ?        S    11:31   0:00 php-fpm: pool www
root         9  0.0  0.0   4060  3300 pts/0    Ss   11:31   0:00 bash
root        16  0.0  0.0   8048  3636 pts/0    R+   11:35   0:00 ps aux

ファイル所有者が www-dataになっていることが分かります。※ envはホストされているので、rootです。

// 一部省略
www-data@b9e1f52a8a18:/var/www/src# ls -la
drwxr-xr-x 12 www-data www-data   4096 Oct 13 06:53 .
drwxr-xr-x  1 www-data www-data   4096 Oct 22 03:44 ..
-rw-r--r--  1 root root   1213 Oct 13 06:53 .env
drwxr-xr-x  8 www-data www-data   4096 Jul 22 11:43 app
drwx------  3 www-data www-data   4096 Jul  8 10:30 bootstrap
drwxr-xr-x  2 www-data www-data   4096 Jul  8 10:30 public
drwxr-xr-x  2 www-data www-data   4096 Aug 30 10:52 routes
drwx------  5 www-data www-data   4096 Jul  8 10:30 storage

結果

※ php-fpmの[worker process]はwww-dataユーザーで、アクセス・書き込み権限が必要なファイル所有者がwww-dataなので、ファイルが操作可能

Case4:rootユーザーでdockerImageビルド -> USERを変更(user名:depolyer)して、dockerConntainer起動

dockerfile

userを作成して、USER命令を実行します。

RUN addgroup deployer && \
    adduser --disabled-password --gecos "" --ingroup deployer deployer
USER deployer

docker-compose.yml

※ベース部分のまま
マウントは削除します。

ファイル所有者・proccess 実行ユーザー

コンテナ実行ユーザー:depolyer
master process ユーザー:depolyer
worker process ユーザー:depolyer
ファイル所有者:root

master process、worker processの実行者がdeployerとなりました。

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
deployer     1  0.3  0.2  82692 21816 ?        Ss   11:41   0:00 php-fpm: master process (/usr/local/etc/php-fpm.conf)
deployer     7  0.0  0.0  82692  7436 ?        S    11:41   0:00 php-fpm: pool www
deployer     8  0.0  0.0  82692  7436 ?        S    11:41   0:00 php-fpm: pool www
deployer     9  0.0  0.0   4060  3212 pts/0    Ss   11:41   0:00 bash
deployer    16  0.0  0.0   8048  3656 pts/0    R+   11:41   0:00 ps aux

ファイル所有者はrootで変わらず。

// 一部省略
root@b9e1f52a8a18:/var/www/src# ls -la
drwxr-xr-x 12 root root   4096 Oct 13 06:53 .
drwxr-xr-x  1 root root   4096 Oct 22 03:44 ..
-rw-r--r--  1 root root   1213 Oct 13 06:53 .env
drwxr-xr-x  8 root root   4096 Jul 22 11:43 app
drwx------  3 root root   4096 Jul  8 10:30 bootstrap
drwxr-xr-x  2 root root   4096 Jul  8 10:30 public
drwxr-xr-x  2 root root   4096 Aug 30 10:52 routes
drwx------  5 root root   4096 Jul  8 10:30 storage

結果

※ DockerコンテナでUSER命令を実施するとその後のコマンド含めて指定したUSERが実行することになる。 なので、master processも、worker processも指定したUSERが実行者となる。

※ master process、worker processの実行者がdeployerとなったのは、dockerのUSER命令が下記のような影響を及ぼすからです。

The USER instruction sets the user name (or UID) and optionally the user group (or GID) to use as the default user and group for the remainder of the current stage. The specified user is used for RUN instructions and at runtime, runs the relevant ENTRYPOINT and CMD commands.
> USER 命令は、現在のステージの残りの部分でデフォルトのユーザーおよびグループとして使用するユーザー名 (または UID) と、オプションでユーザー グループ (または GID) を設定します。指定されたユーザーは RUN 命令に使用され、実行時に関連する ENTRYPOINT および CMD コマンドを実行します。

https://docs.docker.com/reference/dockerfile/#user

https://www.docker.com/ja-jp/blog/understanding-the-docker-user-instruction/

Case5:rootユーザーでdockerImageビルド -> USERを変更(user名:depolyer)して、dockerConntainer起動だが、ホスト環境からマウント

dockerfile

userを作成して、USER命令を実行します。

RUN addgroup deployer && \
    adduser --disabled-password --gecos "" --ingroup deployer deployer
USER deployer

docker-compose.yml

ホスト環境からマウントします。

  api:
    build:
      context: .
      dockerfile: ./docker/env/local/api/Dockerfile
    container_name: g-api
    volumes:
      - ./api:/var/www/src
      # laravelの.envファイルをマウント
      - ./api/.env.local:/var/www/src/.env

ファイル所有者・proccess 実行ユーザー

コンテナ実行ユーザー:depolyer
master process ユーザー:depolyer
worker process ユーザー:depolyer
ファイル所有者:depolyer

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
deployer     1  0.3  0.2  82692 21816 ?        Ss   11:41   0:00 php-fpm: master process (/usr/local/etc/php-fpm.conf)
deployer     7  0.0  0.0  82692  7436 ?        S    11:41   0:00 php-fpm: pool www
deployer     8  0.0  0.0  82692  7436 ?        S    11:41   0:00 php-fpm: pool www
deployer     9  0.0  0.0   4060  3212 pts/0    Ss   11:41   0:00 bash
deployer    16  0.0  0.0   8048  3656 pts/0    R+   11:41   0:00 ps aux

ファイルの所有者も、deployerとなりました。マウント時にコンテナ実行者のdeployerが所有者となったようです。

// 一部省略
deployer@b9e1f52a8a18:/var/www/src# ls -la
drwxr-xr-x 12 deployer deployer   4096 Oct 13 06:53 .
drwxr-xr-x  1 deployer deployer   4096 Oct 22 03:44 ..
-rw-r--r--  1 deployer deployer   1213 Oct 13 06:53 .env
drwxr-xr-x  8 deployer deployer   4096 Jul 22 11:43 app
drwx------  3 deployer deployer   4096 Jul  8 10:30 bootstrap
drwxr-xr-x  2 deployer deployer   4096 Jul  8 10:30 public
drwxr-xr-x  2 deployer deployer   4096 Aug 30 10:52 routes
drwx------  5 deployer deployer   4096 Jul  8 10:30 storage

結果

ファイル所有者もWorkerプロセスユーザーもdeployerなので、アクセス・書き込み権限が必要なファイル所有者がwww-dataなので、ファイルが操作可能

まとめ

どういう変化があるのかを色々と実験してみました。
正しいユーザー選定をしていくことは大事なので、参考にしていきたいです。

Discussion