phpへのアクセスをApacheへ投げるだけのnginxの設定
フロントにnginxを置き、裏にApacheを置く
www -> nginx -> apache
- phpへのアクセスはapacheへ流し、それ以外はnginxで返す。
- とりあえずキャッシュをしない。
- nginx.confの中身はてきとー。
とりあえず、動くものを用意する。
php以外の動的に動くものはひとまず考えない。
前提
- OS : CentOS6系
- 同一サーバ上に構築
- php/nginx/apacheインストール済み
- apacheでphp動作確認済み (LoadModule php5_module modules/libphp5.so)
nginx config
user nginx nginx;
worker_processes auto;
error_log /usr/local/nginx/logs/error.log;
pid /usr/local/nginx/logs/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
use epoll;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 20;
keepalive_requests 2000;
client_header_timeout 20;
client_body_timeout 20;
gzip on;
gzip_proxied any;
gzip_min_length 256;
gzip_comp_level 4;
server_tokens off;
include /usr/local/nginx/conf.d/*.conf;
error_page 500 502 503 504 /50x.html;
}
upstream apache {
server 127.0.0.1:8080;
}
server {
listen 80 default_server;
server_name example.com;
client_max_body_size 100M;
access_log /usr/local/nginx/logs/access.log main;
location / {
auth_basic "Restricted";
auth_basic_user_file /usr/local/nginx/html/.htpasswd;
try_files $uri $uri/ /index.html;
}
location ~ \.php$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://apache;
}
location = /50x.html {
root html;
}
}
include /usr/local/nginx/conf.d/*.conf;
上記の設定で default.confを読み込んでる。
※nginx.confの諸々の設定は調べてません。てきとーです。
upstream apache {
server 127.0.0.1:8080;
}
location ~ \.php$ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://apache;
}
.phpへのアクセスはApacheへ流す設定。
upstreamへ他サーバを記載したり、サーバを増やしたりすると負荷分散とかできる。
httpd.conf
LoadModule php5_module modules/libphp5.so
Listen 127.0.0.1:8080
User nginx
Group nginx
DocumentRoot "/usr/local/nginx/html/"
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
デフォルトのhttpd.confなのでやたら長くなったので変更したところだけ。
外からアクセスが来る必要はないので 127.0.0.1 のみをListen。
同一サーバでなければ、フロント(nginx)から接続ができるIPでListenする事。
LogFormatはnginxのIPアドレスがアクセスログに記載されるので役に立たないので設定。
これで.phpのコンテンツはApacheが返却し、それ以外のファイルはnginxが返却する。
.php以外の接続ではApacheのaccess_logは伸びないところまで確認。
余談
Apacheを127.0.0.1だけでListenするならUnix domain socket使ってもいいかも知れないが、そんな設定みたことない。
そもそも調べてもいないがそんな動作するのか。
Apacheがevent/workerで動作しているとphpが動かない場合がある。
event -> スレッド駆動
worker -> マルチプロセスとスレッドのハイブリッド
LoadModule mpm_event_module modules/mod_mpm_event.so
上記の記述をコメントアウトし、下記を追加する事で解決するかもしれない。
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
この辺りはApacheのページにも書いてあったような気がする。
location ~ \.php$ {
proxy_pass http://apache/;
}
こう書くとエラーになる。
# /usr/local/nginx/sbin/nginx -t
nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /usr/local/nginx/conf.d/default.conf:26
nginx: configuration file /usr/local/nginx/etc/nginx.conf test failed
が、しかし、下記なら通る。
location / {
proxy_pass http://apache/;
}