一般来说,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的专科项目了。