nginxとphp-fpmの通信設定について
はじめに
この記事はプログラミング初学者による備忘録用の記事であり、少しでも他の初学者のお役に立てればと思い書いています。
今回はDockerでのnginxコンテナとphp-fpm(php)コンテナの通信設定(unixドメインソケット)に関することを調べてみました。
間違いなどがございましたら、ご指摘のほどよろしくお願い致します。
nginxとphp-fpm間のイメージ図
このようなイメージになるかと思います。(間違っていればご指摘ください)
通信設定の流れ(ざっくりと説明)
大まかな流れ
1.docker-compose.yml
で名前付きボリュームをマウントする。
unixドメインソケット(php-fpm-socket)のボリュームは app コンテナと web コンテナで共用したいのでマウントします。
2.php-fpm側でphp-fpm.d/zzz-www.conf
、nginx側でnginx/default.conf
、nginx/nginx.conf
を使い設定を行います。
接続方法
TCPかUNIXドメインソケットのどちらかを選択して接続します。
UNIXドメインソケットは、TCPソケット(INETドメインソケット)よりもスループット
が優れてるらしい。
下記の記事は参考になります。是非、読んでみてください。
順を追って、もう少し詳しく説明したいと思います。
docker-compose.ymlでの設定
version: "3.8"
volumes:
php-fpm-socket: #unixドメインソケットを使う為に名前付きボリュームを設定
db-store:
services:
# php
app:
container_name: php
build: ./infra/docker/php
volumes:
- php-fpm-socket:/var/run/php-fpm
#unixドメインソケット(php-fpm-socket)のボリュームはwebコンテナと共用するのでマウントする
- ./backend:/work/backend
# nginx
web:
container_name: nginx
build: ./infra/docker/nginx
ports:
- 80:80
volumes:
- php-fpm-socket:/var/run/php-fpm
#unixドメインソケット(php-fpm-socket)のボリュームはappコンテナと共用するのでマウントする
- ./backend:/work/backend
#略
後ほど、/var/run/php-fpmをphp-fpm.d/zzz-www.conf
、nginx/default.conf
で使うことになります。
Dockerfile(php)
#略
RUN mkdir /var/run/php-fpm && \
#略
COPY ./php-fpm.d/zzz-www.conf /usr/local/etc/php-fpm.d/zzz-www.conf
COPY命令のディレクトリは構造により異なります。
コンテナ内のファイルシステム上を指すパスは一定です。
Dockerfile(nginx)
#略
# nginx config file
COPY ./default.conf /etc/nginx/conf.d/default.conf
COPY ./nginx.conf:/etc/nginx/nginx.conf
#略
COPY命令のディレクトリは構造により異なります。
コンテナ内のファイルシステム上を指すパスは一定です。
接続の設定(nginx)
nginxでは、nginx/default.conf
、nginx/nginx.conf
を使い設定を行います。
・nginx/nginx.conf
は、php-fpmとunixドメインソケットで通信するために、初期状態から実行ユーザをwww-dataに変更するために用意します。
・ nginx/default.conf
はdefault.conf内でphp-fpm.sockのpathを指定する為に用意します。pathを指定することでphp-fpm
との通信が成立します。
# user nginx;
user www-data; #デフォルトからこの箇所のみ変更
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
#略
nginx/nginx.conf
では、php-fpmとunixドメインソケットで通信するために、初期状態から実行ユーザをwww-dataを追記します。
変更する理由
nginx+php-fpm環境でphpの処理にUNIXドメインソケットを使っている場合、DebianでPHPをアップグレードすると、「502 Bad Gateway」となって502エラーでハマるのを防ぐ為です。
詳しくは下記リンク先をお読みください。
https://setting-tool.net/nginx-php-fpm-socket-permission
#略
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
#/var/run/php-fpm/ に php-fpm.sock が作られてphpコンテナと通信が成立
}
unixドメインソケットで接続する場合
nginx/default.conf
で、fastcgi_pass unix: /var/run/php-fpm/php-fpm.sock;
とpathを指定します。php-fpm.d/zzz-www.conf
と同じpath指定することで、nginxとphp-fpmでunixドメインメソットを使い通信できるようになります。
接続の設定(php-fpm)
php-fpmでは、php-fpm.d/zzz-www.conf
を使い設定を行います。
・php-fpm.d/zzz-www.conf
は、php-fpm.sockのpathを指定する為と、実行ユーザーをnginx側の実行ユーザーと一致させる為に用意します。
listen = /var/run/php-fpm/php-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0666
listen
FastCGIリクエストを受け入れるアドレスを設定、nginxと通信(接続)するためのUNIXドメインソケットのpathを指定します。fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;と同じpathを指定をすることで通信できるようになります。このオプションは、必須であり、 'ip.add.re.ss:port', 'port', '/path/to/unix/socket' 形式の構文が使えます。
listen.owner = www-data
unix ソケットを使う場合に、そのパーミッションを設定します。 読み書きアクセス権限(ユーザー)をnginxの実行ユーザーと同一設定しないとウェブサーバーからの接続を受け付けることができません。
listen.group = www-data
同様にnginxの実行ユーザーと統一させる。
注意
listen.ownerとlisten.groupで、nginxの実行ユーザーと別のユーザーを指定した場合
例
listen.owner = nginx
listen.group = nginx
下記のように、存在していないユーザーが設置されてますよとエラーがでます。
$ docker-compose logs
php | [12-Mar-2021 11:57:31] ERROR: [pool www] cannot get uid for user 'nginx': Success (0)
php | [12-Mar-2021 11:57:31] ERROR: [pool www] cannot get uid for user 'nginx': Success (0)
php | [12-Mar-2021 11:57:31] ERROR: FPM initialization failed
php | [12-Mar-2021 11:57:31] ERROR: FPM initialization failed
listen.mode = 0666
これがないとphp側でエラーが出ます。
$ docker-compose logs
php | [14-Mar-2021 09:54:34] ERROR: [/usr/local/etc/php-fpm.d/zzz-www.conf:5] unknown entry '# listen.mode'
php | [14-Mar-2021 09:54:34] ERROR: Unable to include /usr/local/etc/php-fpm.d/zzz-www.conf from /usr/local/etc/php-fpm.conf at line 5
php | [14-Mar-2021 09:54:34] ERROR: failed to load configuration file '/usr/local/etc/php-fpm.conf'
php | [14-Mar-2021 09:54:34] ERROR: FPM initialization failed
パーミッションの設定
WEBサイトなどを見ているユーザは、第三者です。
WEBページとして公開するHTML文書などは、「読み取り」 を許可する必要がありますが、CGIのファイルなど直接呼び出されるプログラムには、「書き込み」を許可しなければならない場合があります。
従って、各ユーザーにどこまで権限を与えるのかを考え、パーミッションを変更する必要があります。
今回のように0666とする場合、
用途としてはデータ記録など読み書き可能なファイルで、具体例として掲示板のようなものが該当します。
パーミッションに関することは下記記事が分かりやすかったです。
zzz-www.conf
というファイル名の理由
これは 公式イメージがzz-docker.conf
でlisten設定を破棄していることに対抗するためらしいです。後に読ませることでlisten設定が残るので、辞書順で後ろに来るようにzzz-www.conf
というファイル名にするらしいです。
詳しくは下記記事を読んでみてください。
fpm の設定ファイルを
zzz-www.conf
としていますが、これは 公式イメージが zz-docker.conf で listen 設定をぶっ潰しているのに対抗するためです。
後に読まれたものが勝つので。どう見ても暫定回避のような構造ですが仕方ありません。
おわりに
次はTCPやUNIXドメインソケットについて、もう少し詳しく学習してみようかなと思います。
最後まで読んでくださり誠にありがとうございました。
Author And Source
この問題について(nginxとphp-fpmの通信設定について), 我々は、より多くの情報をここで見つけました https://qiita.com/susuz/items/113002580945e94b1456著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .