先说结论:
第一需要使用Alias
指定文件夹,第二由于try_files
的bug,需要手写rewrite
。
Nginx简直就是个智障。妈的花了我一个下午,翻了几十个stackoverflow和google才找到这么一个无人问津的小帖子。
需求:
主域名example.com
下已经挂了静态站点,文件在/home/html/portal
。现在要在example.com/blog
目录下挂一个Wordpress博客,文件在/home/html/wordpress
。
过程:
这么简单的一个小问题,竟然让人大费周章了半天时间,Nginx大概是我见过的这方面最垃圾的东西。要不是看在你性能高的份上,谁™会屌你。
- 坑1:root指定的文件夹会与location前缀进行组合。
于是不论你怎么改root,只要物理路径不和url进行匹配,只要wordpress不放在根目录,那么Nginx只会在/physical/path/+/virtual/dir/
的组合路径下查找wordpress文件(妈的智障,我为什么非要把wordpress文件夹改成和url一样?)
- 坑2:经过一番google,你发现了alias命令,结果alias的路径末尾如果没有斜线就会404。
是不是想起了proxy_pass时候的斜线和location里的斜线?
- 坑3:之前google到的很多例子,包括官方例子都写给你:
try_files uri uri/ /virtual/dir/index.php?$args;
结果怎么不能用啊?
又经过一番google,你发现因为一个远古bug导致alias和try_files共用时出错了。于是你还得自己重写url。
- 坑4:配置文件已经写得乱成一团了,我想把Wordpress的配置放在一起行不行?于是写成了nested location,这父级和子location是怎么个匹配法啊?
不知道为什么,没什么人用nested location。官方也没做什么解释,google了一番之后获得了一个提示,location向下传递的时候不会变化,仍然是完整匹配。于是又给所有的子location加了前缀正则匹配。
总算搞定了。。感觉好厉害啊,完全不懂怎么做到的。。。
参考配置例子:
location /blog {
return 301 $scheme://$host/blog/;
}
location @blog {
rewrite ^/blog/(.*)$ /blog/index.php?$1;
}
location /blog/ {
index index.php;
alias /home/html/wordpress/;
try_files $uri $uri/ @blog;
# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
# Directives to send expires headers and turn off 404 error logging.
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;
}
location ~* ^/blog/(?:uploads|files)/.*\.php$ {
deny all;
}
# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ ^/blog/(.+\.php)$ {
alias /home/html/wordpress/$1;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_index index.php;
fastcgi_pass php;
}
}
参考链接
http://www.netz39.de/2014/installation-of-wordpress-in-a-subdirectory-with-nginx/