一般来说,WordPress都是被部署到一个LAMP环境的,不过为了追求分流、负载均衡,或者其他的具体需求,我们可能并不真的直接暴露Apache2给访问者,而是借助一个前端服务器(甚至是集群,话说谁的Blog还在写而且有百万千万级访问吗?)来转置。
然而,使用Nginx前端的情况下,大概百分百会遇到“Too many redirect loop”错误,究其原因,一个是WordPress内核的filter可能导致该问题,一个是不恰当的WordPress插件可能会间接引发该问题。
第一个原因,也是通常必然需要后处理的问题,就是在你的当前WordPress主题文件夹中修改functions.php文件,引入一句去除filter的指令,具体可以参考 解决WordPress前端nginx时无限重定向问题。
第二个原因,我已经遇到过的是Nextgen Gallary插件会引发问题,最终禁用掉后改用其他Gallery插件解决了,这类状况一般靠逐个插件禁用来尝试找到原因。
除了上面提到的错误外,如何让nginx正确转发用户请求也是一个问题。我们在这里提供一套配置来解释我们是怎么做的。
首先,我们在Apache2的站点配置文件中进行WordPress的配置,并且Apache2的服务端口被修改为10080以及10443(通常是修改/etc/apache2/ports.conf):
# blog.hedzr.com.conf # kate: hl apache configuration; space-indent off; indent-width 4; tab-width 4; mixedindent off; indent-mode cstyle; eol lf; <VirtualHost blog.hedzr.com:10080> ServerAdmin webmaster@hedzr.com ServerName blog.hedzr.com DocumentRoot /var/www/sites/blog.hedzr.com <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /opt/sites/blog.hedzr.com/> Options -Indexes +FollowSymLinks +MultiViews AllowOverride All Require all granted </Directory> ErrorLog ${APACHE_LOG_DIR}/blog.hedzr.com-error.log CustomLog ${APACHE_LOG_DIR}/blog.hedzr.com-access.log combined # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn </VirtualHost> # kate: hl apache configuration; space-indent off; indent-width 4; tab-width 4; mixedindent off; indent-mode cstyle; eol lf; <IfModule mod_ssl.c> <VirtualHost blog.hedzr.com:10443> ServerAdmin webmaster@hedzr.com ServerName blog.hedzr.com DocumentRoot /var/www/sites/blog.hedzr.com <Directory /var/www/sites/blog.hedzr.com/> Options -Indexes +FollowSymLinks +MultiViews AllowOverride All Require all granted </Directory> #LogLevel info ssl:warn ErrorLog ${APACHE_LOG_DIR}/blog.hedzr.com-ssl-error.log CustomLog ${APACHE_LOG_DIR}/blog.hedzr.com-ssl-access.log combined SSLEngine on SSLCertificateFile /data/apache2/ssl.certs/blog.hedzr.com.chained.crt SSLCertificateKeyFile /data/apache2/ssl.certs/blog.hedzr.com.key #SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> <Directory /usr/lib/cgi-bin> SSLOptions +StdEnvVars </Directory> BrowserMatch "MSIE [2-6]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 # MSIE 7 and newer should be able to use keepalive BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown </VirtualHost> </IfModule> # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
其次,我们需要配置nginx的对应站点,并进行恰当的转发,通常应该是/etc/nginx/sites-available/blog.hedzr.com文件,其内容为:
# /etc/nginx/sites-available/blog.hedzr.com server { listen 80; root /var/www/sites/blog.hedzr.com; index index.html index.htm index.php; server_name blog.hedzr.com; rewrite ^/(.*) https://$server_name/$1 permanent; #跳转到Https charset utf-8; location / { try_files $uri $uri/ @apache; # =404; } #error_page 404 /404.html; location @apache { internal; proxy_redirect off; proxy_pass http://blog.hedzr.com:10080; include proxy_apache; } location ~ \.php$ { try_files $uri /index.php; fastcgi_split_path_info ^(.+\.php)(/.+)$; proxy_pass http://blog.hedzr.com:10080; include proxy_apache; } location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { access_log off; log_not_found off; expires max; # or: expires 30d; } location ~ /\.ht { deny all; } } # HTTPS server server { listen 443; server_name blog.hedzr.com; #root html; root /var/www/sites/blog.hedzr.com; index index.html index.htm index.php; ssl on; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; ssl_certificate /data/ssl.certs/blog.hedzr.com.chained.crt; ssl_certificate_key /data/ssl.certs/blog.hedzr.com.key; ssl_session_timeout 5m; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; ssl_prefer_server_ciphers on; error_page 497 "https://$host/$uri?$args"; #这是跳转Http请求到Https location / { try_files $uri $uri/ @apache; # =404; } location @apache { internal; proxy_redirect off; proxy_pass https://blog.hedzr.com:10443; include proxy_apache; } location ~ \.php$ { #internal; proxy_pass https://blog.hedzr.com:10443; include proxy_apache; } location ~* \.(jpg|jpeg|gif|png|bmp|flv|mpg|mp4|avi)$ { access_log off; expires 30d; } location ~* \.(js|css)$ { access_log off; expires 1d; } location ~* \.(htm|html)$ { expires 1d; } location ~ /\.ht { deny all; } }
也可以稍微调整一点:不必再apache配置文件中定义和启用SSL网站,而nginx配置文件中转发到10443的代码此时直接转发给10080即可。
如上展示的是如何给LAMP WordPress部署添加一个Nginx前置服务器,这里暂时不再解释如何抽取Apache2后端为upstream,如何负载均衡,如何配置权重等问题,那些都属于nginx的专科项目了。