web-dev-qa-db-ja.com

転送PHPハンドラーとしてのProxyPassMatch経由のリクエスト、またはファイルが存在する場合のみ

Mod_phpの代わりにmod_proxy_fcgiとphp-fpmを使用するようにサーバーを移行しています。 Apacheは.phpリクエストをfcgiプロキシに転送することができ、PHPは正しく実行されます。

ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/$1

残念ながら、Apacheはファイルが存在しない場合でも、すべての.phpリクエストをプロキシに転送します。これはいくつかの問題を引き起こします。 ErrorDocumentルールが呼び出されず、DirectoryIndex index.php index.htmlはindex.htmlにフォールバックしません。

私はこれらの問題をmod_rewriteで修正することができました:

RewriteEngine On                                                           
RewriteCond %{REQUEST_FILENAME} ^/((.*\.php)(/.*)?)$                       
RewriteCond /var/www/html/%2 -f                                   
RewriteRule . fcgi://127.0.0.1:9000/var/www/html/%1 [P] 

ただし、Apacheのドキュメント RewriteRuleはお勧めしません :「これは、このフラグが、接続プールを処理しないデフォルトのワーカーの使用をトリガーするためです。」

理想的には、FilesMatchブロックでProxyPassを使用するか(現在はサポートされていません)、またはmod_phpと同様に、fcgiを介してプロキシし、.phpリクエストを処理するためにそれを使用する新しいハンドラーを定義したいと思います。

標準のmod_php設定をシミュレートするが、実際にはfcgiを介してプロキシするための提案はありますか?

8
ide

1つのオプションは、mod_proxy_handlerをインストールすることです: https://Gist.github.com/progandy/6ed4eeea60f6277c3e39

または、モジュールが含まれるはずのApache 2.4.10を待つこともできます。

基本的にモジュールはこれを可能にします:

#tcp
<FilesMatch \.php$>
SetHandler proxy:fcgi://localhost:9000
</FilesMatch>

#uds
<FilesMatch \.php$>
    SetHandler "proxy:unix:/path/to/socket.sock|fcgi://./"
</FilesMatch>
6
dmuir

同じ問題がありましたが、index.phpがない場合、ProxyPassMatchを使用するとApacheがindex.htmlにフォールバックしません。

私が代わりにしたことは私が使用したことです(Apache 2.4):

<FilesMatch "\.php$">
  SetHandler "proxy:unix:/usr/local/php73/var/run/mpelov-php-fpm.sock|fcgi://localhost/"
</FilesMatch>

Apache 2.2で動作するかどうかはわかりません。

これの問題は、ファイルへのパスがわからないことです。したがって、 http://example.com/file.php は/file.phpにマップされますが、これは通常は問題ありませんが、php-fpmがchrootphpの場合、ファイルは/file.phpであり、 http://example.com/file.html がある場合、Apacheがリクエストを処理し、パスは//file.htmlです

したがって、fpm + chrootでfilematchを使用することはできません。

0
NickSoft

私はideとまったく同じ問題を抱えており、これを解決しようと思ったよりもずっと長い時間を費やしていました。これは、問題を適切に解決するのに役立つ唯一の投稿または記事であることがわかったため、ソリューションをミックスに追加したいと考えました。

私の構成:

  • Ubuntu 14.04
  • Apache 2.4.20
  • PHP-FPM 5.5.9-1ubuntu4.17(fpm-fcgi)(ビルド:2016年5月19日19:08:26)

私はいくつかの追加の課題に遭遇しました:

  1. 私のErrorDocumentハンドラはPHPファイルです。
  2. ドキュメントルートの.htaccessファイルにRedirectPermanentディレクティブがたくさんあります。リダイレクトルールが評価される前にリクエストがPHP-FPMにプロキシされたため、これらは受け入れられませんでした。
  3. 私はWordpressと同様の方法でURL書き換えを使用しているため、FilesMatchでは不十分でした。例えば。 /mydir/mypath.htmlは/mydir/script.phpを指します。書き直されたURLに一致させることができませんでしたが、おそらく見落としがあったのでしょうか?
  4. 私はmisterichのアプローチを機能させることができましたが、Apacheの パフォーマンス警告 を読んだ後、さらに掘り下げることにしました。

私の解決策は基本的にこれです:

  1. 存在しないディレクトリとファイルへのリクエストをインターセプトしてリダイレクトし、エラーハンドラPHPファイルに書き換えます。
  2. 別の書き換えルールを使用して、書き換えたエラー要求をPHP-FPMにルーティングします。
  3. ProxyPassMatchを使用して、他のすべてのリクエストをPHP-FPMにルーティングします。

301リダイレクト(#2)を解決するには、エラーハンドラーを利用してリダイレクトを発行します。

RewriteEngine On

RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^.*\.php$ /error.php?error=404&requestUri=$1

RewriteCond %{REQUEST_FILENAME} ^/(error.php)$
RewriteCond %{DOCUMENT_ROOT}/%1 -f
RewriteRule . fcgi://127.0.0.1:9000%{DOCUMENT_ROOT}/%1   [P]

# PHP-FPM
ProxyPassMatch ^/(.*\.php(/.*)?)$ "fcgi://127.0.0.1:9000/var/www/mysite.com"
0
Erich Musick

ファイルが存在しないときにも「ファイルが見つかりません」と表示されるのと同じ問題がありました。メッセージ、これは私の問題を修正し、404ページを設定することを可能にしました:

<VirtualHost *:80>

---------- content --------

DocumentRoot /home/user/public_html/domain.tld

#this disables php execution if you wish to show only html files
#ProxyPass /errors !

ProxyErrorOverride On
# /errors folder is located in public_html
ErrorDocument 404 /errors/404.php


</VirtualHost>
0
Alin Razvan

OPに同上。

  • また、Apache VHOST設定を取得して、検索不可能なリクエストを404にルーティングする方法もわかりませんでした。
  • 同様に、拡張子なしのURLをマッピングしてProxyPassMatch
    • 確かに... php-fpmプロキシを介してすべてをルーティングできましたが、JavaScriptとCSSファイルが強制終了されました。

理論的ソリューション

私の推測では、カスタム404.phpプロセッサを作成し、すべてのリクエストを、リクエストされたファイルをクエリ文字列として追加することでルーティングする必要があります。

例えば:

RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} !-s
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI} !-l
RewriteRule ^.*$   fcgi://127.0.0.1:9000%{DOCUMENT_ROOT}/404.php?no_comprende=%{REQUEST_URI} [P]
...
ProxyPassMatch ^/(.*\.php(/.*)?)$    fcgi://127.0.0.1:9000%{DOCUMENT_ROOT}/$1
...

理論的には-そして、それらがリストされている順序が通常どおり適用されると仮定します:

404されたファイルはすべてキャッチされますbeforeProxyPassMatchディレクティブに到達しました

私の解決策

  • php5-fpm(5.4.23)
  • Apache 2.4.2
  • Ubuntu 12.04/3.8.0-34 x86_64

php-fpmで拡張なしのURLを処理するために、VHOST構成で拡張なしのURLを探すように上記を適合させました。

...
# Extensionless URL's
RewriteCond %{REQUEST_FILENAME} ^/((.*)(/.*)?)$
RewriteCond %{DOCUMENT_ROOT}/%2.php -f
RewriteRule !.*\.php$   fcgi://127.0.0.1:9000%{DOCUMENT_ROOT}/%1.php   [P]

# files w/ .php extensions
RewriteCond %{REQUEST_FILENAME} ^/((.*\.php)(/.*)?)$
RewriteCond %{DOCUMENT_ROOT}/%2 -f
RewriteRule . fcgi://127.0.0.1:9000%{DOCUMENT_ROOT}/%1 [P]
...

きれいではありませんが、仕事は終わりです:-(

0
misterich

念のため、ワンライナーとして:

AddHandler "proxy:unix:/path/to/socket.sock|fcgi://./" .php

最新のApache 2.4が必要です(RedHatはそれを2.4.6に移植しました)。

オリバー

0
Oliver