
現在サーバー上で実行中の nginx をコンテナ化しようとしています。このために、次の docker compose ファイルを作成しました。
version: "3.8"
services:
nginx:
image: nginx:stable-alpine
container_name: nginx
restart: unless-stopped
group_add: ["33"]
volumes:
- "/etc/nginx-docker:/etc/nginx/conf.d:ro"
- "/run/php:/run/php"
- "/var/www:/var/www:ro"
ports:
- "8111:80"
- "8443:443"
すべて正常に動作しますが、問題は、ホスト システム上で php-fpm がまだ「ネイティブに」(docker 化されていない) 実行されており、そのソケットを nginx コンテナーに使用したいことです (そのため、行volumes: - "/run/php:/run/php"
)。
ソケットの権限は ですsrw-rw---- www-data:www-data
。したがって、コンテナ ユーザーをグループ 33 (ホスト システム上の www-data -> group_add: ["33"]
) に追加しました。コンテナでグループ ID を確認すると、ID は33
現在ログインしているユーザーに追加されています。
/ # id -G
0 1 2 3 4 6 10 11 20 26 27 33
/ # id -u
0
/ # whoami
root
それでも、PHP で動作する Web サイトを呼び出すと、nginx ログに次のエラー メッセージが表示されます。
2024/01/21 08:58:53 [crit] 21#21: *1 connect() to unix:/run/php/php8.2-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.192.68, server: _, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock:", host: "op---s:8111"
それを機能させるために何が欠けているのか、ヒントや解決策はありますか?
答え1
少し調べてみました:)
nginx イメージを実行しているコンテナに入ると、いくつかの nginx プロセスが実行されていることがわかります。
docker exec -it 43b5b971c433 /bin/sh
/ # ps -ef |grep nginx
1 root 0:00 nginx: master process nginx -g daemon off;
21 nginx 0:00 nginx: worker process
22 nginx 0:00 nginx: worker process
23 nginx 0:00 nginx: worker process
24 nginx 0:00 nginx: worker process
42 root 0:00 grep nginx
一部は として実行されroot
、一部はnginx
ユーザー として実行されます。
root
docker-compose ファイル内のグループにユーザーを追加しましたがwww-data
、これを行わなくても、root ユーザーには PHP Unix ソケットにアクセスするために必要なすべての権限が付与されているはずです。
コマンドを使用して権限をテストできますtest
。コマンドが成功したかどうかを確認するには、終了コードを出力します。ご覧のとおり、root ユーザーはソケット ファイルを読み取ることはできますが、実行することはできません。
/run/php # whoami
root
/run/php # test -r php8.1-fpm.sock; echo $?
0
/run/php # test -x php8.1-fpm.sock; echo $?
1
したがって、エラーはおそらく、ユーザーとして実行されるプロセスpermission denied
から発生します。nginx worker
nginx
まず、docker コンテナ内のファイルの権限を確認しましょう...
ls -al
次のような出力が得られます。
srw-rw---- 1 xfs xfs 0 Jan 25 08:58 php8.1-fpm.sock
/etc/group
ソケット ファイルは "xfs" によって所有されていることを示しています。コンテナー内のファイルをざっと見ると、グループの IDがホスト マシン上のグループの ID と同じでxfs
あることがわかります。33
www-data
コンテナ内で、nginx ユーザーを xfs グループに追加できます。
addgroup nginx xfs
問題はこれで解決されるはずです。
これを Compose ファイルに直接追加する方法はわかりません (グループに追加するユーザーをどのように指定するのでしょうか)。ただし、新しいイメージを作成できる場合は、Dockerfile で実行できます。
ただし、コンテナを再起動した後も権限は保持されるようです。
答え2
ホスト上で PHP-FPM が実行しているユーザーとグループを決定します。通常、この情報は PHP-FPM 構成ファイル (通常は /etc/php/7.x/fpm/pool.d/www.conf にあります) にあります。
次にdocker-composeを更新してこれを追加します
user: "your_php_user:your_php_group"
答え3
すべて正常に動作しますが、問題は、ホスト システム上で php-fpm がまだ「ネイティブ」(docker 化されていない) で実行されており、そのソケットを nginx コンテナーに使用したいことです (そのため、行 volumes: -
"/run/php:/run/php"
)。
これは不可能であり、賢明でもありません。
Docker は独自のネットワーク名前空間を生成するため、独自のファイアウォール スタック、IP スタック、Unix ネットワーク スタックが提供されます。
権限の問題を修正したとしても、たとえば、ソケット ファイル 666 を使用してコンテナーに手動でログインしdocker exec
、chmod
簡潔にするためにユーザー名前空間も存在しないと仮定します。
あなたが求めているのは、次のことと同等です:
- Unixソケットで
php-fpm
インスタンスを実行するsystem1
/var/run/php-fpm.sock
/var/run
上の NFS 経由でパスをエクスポートしますsystem1
。system1:/var/run
に取り付けますsystem2
。完全に独立したシステムです。connect()
前述の Unix ソケットをソケットオンにしようとしておりsystem2
、system1
応答を期待していますphp-fpm
。
これを実際に行うべき方法(実際には欲しいこれを行うには、別の問題ですが、IP を使用してインスタンスをリッスンしphp-fpm
、たとえば にバインドしますhost_system:12345
。次に、nginx
を使用してcontainer
に接続しますhost_system:12345
。
これはすべて間違っています。私の言うことを聞かないでください。どちらかの名前空間で公開され、パスが両方の名前空間で共有されている、適切に名前付けされた UNIX ソケットを作成すると、その UNIX ソケットに接続すると、もう一方の名前空間に接続されます。
https://lore.kernel.org/all/[メールアドレス]/T/
このパッチは特にこれに対処します。明らかに、私がこれをテストしたのはかなり昔のことです! :)
これが当てはまらない唯一のケースは、匿名の Unix ソケットの作成の場合ですが、これは Linux に特有のものであり、Unix ソケットの機能としてはあまり使用されません。