nginx 使いまくり問題
docker やCDNとか使ってると、いくつのプロキシが挟まるんだよ。管理面倒くさいんだよ。って問題にぶち当たる。特にphp 関連。
browser → 企業・学校内プロキシ → CDN → docker ホスト nginx → dockerコンテナnginx → php-fpm
コレ全部が、SSLのデクリプトとエンクリプションや、TCPコネクションでsyn/ack してると思うとゾッとしない話ではない。そりゃhttp2でTCP節約が必要になるよねって感じる。
リバースプロキシから裏側はTCPを減らせるのでは。
docker ホスト nginx → dockerコンテナnginx → php-fpm
この部分がlocalhost:9000とかで待ち受けてるけど、全部unix ドメインソケットにしてしまえば、接続も管理も楽になるんじゃないかと。
nginx が unix sock で待ち受ける
ポートの管理とかTCPのコネクションが面倒くさいので、unix ソケットでnginx を動かしてみたらどうだろうか。 と思ったので試してみた。
nginx で設定してみる。
/etc/nginx/sites-enabled/default
server { #listen 80 default_server; #listen [::]:80 default_server; listen unix:/var/lib/nginx/backend.sock; access_log off; # SSL configuration # ##略 }
接続してみる
echo 'GET /' | nc -U /var/lib/nginx/backend.sock
nginx のunix:sock に応答する プロキシを 構成する。
リバースプロキシからバックエンドのnginxにunixソケットで接続できるようにする。
nginx:80 → nginx:sock に対応するものを作る。
upstream nginx-internal-sock { server unix:/usr/local/var/run/nginx-internal.sock; } server{ listen 80; server_name 'www'; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Accept-Encoding ""; proxy_pass http://nginx-internal-sock; } }
または次のように書く
server{ listen 80; server_name 'www'; location / { proxy_pass http://unix:/usr/local/var/run/nginx-internal.sock; ## ↑ http://unix:/ は記述ミスじゃなくて本当にこう書きます } }
パスが違うのは、docker の起動時にボリュームでマッピングしてるから
-v /usr/local/var/run/:/var/lib/nginx/
socket ファイルを直接ボリュームマッピングすると socket がすでに存在しますと言われて起動できないので注意
何に使うの?
ポートの管理が面倒くさい。
docker で localhost:8001 / localhost:8002 / localhost:8003 と次々とnginxが占拠していくので何がなんだかわからなくなる。
とくに、nginx→(nginx+phpfpm)
間のリバースプロキシをすると管理が面倒くさいし、docker-composeのYAMLもだんだん増えてしまうので、ファイル名で扱うほうが楽かなかって思ったりしてる。ポート被らないし、ファイル名で識別できるし。ドメインソケットのほうがちょっとだけ速いし。
nginx-fpm をワンペアで扱う
apache+mod_php を使うのであれば、Apacheのインスタンスを見ておけばいいが、 fastcgi+apache や fastcgi+nginx にすると管理が面倒くさいのでソケットを volumeで外に出そうかなと。
アプリ側の設定 sites-enabled/myapp-php.nginx
upstream my-app-php-fpm { server unix:/usr/local/var/run/php-fpm/php-fpm.sock; } server{ listen unix:/usr/local/var/run/my-app-nginx-internal.sock; root /var/www/html; location ~* \.php$ { fastcgi_pass my-app-php-fpm; } }
フロント側の設定。 sites-enabled/www.myapp.example.com.nginx
upstream nginx-internal-sock { server unix:/usr/local/var/run/my-app-nginx-internal.sock; } server{ listen 80; server_name www.myapp.example.com; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Accept-Encoding ""; proxy_pass http://nginx-internal-sock; } }
こうしておけば、unix socket でバックエンドにつながるので、マシン上に大量にのっけてもポート管理が煩雑にならない。
pull して実行したらcomposer.yaml でポート被った!あああぅっ。ってならなくて済むんじゃないかなと。