WordPress Nginx 配置指南

这篇文章大部分来自对wordpress.org官网的翻译。满意之后会提交给官方。
https://codex.wordpress.org/Nginx

LAMP(Linux + Apache + MySQL + PHP)现在是建立WordPress最流行的技术栈,但也可以使用Nginx。WordPress支持Nginx,类似WordPress.com的大型WordPress网站,就是基于Nginx的。

有很多方法实施Nginx。可以做为Aach的前置reverse-proxy(反向代理),可以同时使用Apache的特性、功能,又获得Nginx高速的优点。很多使用nginx的网站实际上都是运行着Apache,Nginx做为reverse proxy。

这篇指南主要用于独立的Nginx setup配置,Nginx代替Apache做为主服务器。请注意,Nginx并不是Apache的完全替代品。关于WordPress的部署启动,动手之前请注意这些关键点:

  • Nginx没有目录级配置文件(类似Apache的.htaccess 或IIS的web.config文件)。所有的配置都在管理员处理server level时完成,所有WordPress无法修正配置。
  • 当使用Nginx的时候,仿固定链接功能(Pretty Permalinks functionality)有些不同
  • 因为Nginx没有.htaccess-type 能力,所以WordPress无法为你自动修正服务器配置。(不能自动产生rewrite rules)
  • 如果你没有修改install, "index.php"将被添加到你的固定链接。(通过插件或者在子主题"child theme"的functions.php中添加自定义代码)
  • 最后,如果你一定要使用一些.htaccess 的某些功能,技术上来说,可以通过安装htscanner PECL extension for PHP实现。 (请注意,这不是一个完美的解决方案,所以在网站上线使用之前,请对其进行充分的测试和Debug)

这篇指南并不包括安装和配置Nginx,建议你已经安装了Nginx,并了解Nginx的基本工作调试知识后再进行阅读。

通用多站点支持(Generic and Multi-Site Support)

WordPress要与Nginx一起工作,必须先配置后端php-cgi,可选择 FastCGI 或 PHP - FPM 。因为 PHP 5.3 中php-fpm已经直接安装,所以我们就用它了。

Nginx 配置已分成 5 个不同文件 , 为了便于理解,对每个设置都已经详细注释。笔者尽量尝试做 Nginx 配置的“最佳实践”。

主启动文件(通用)

此文件就是 /etc/nginx/nginx.conf (或者 /etc/nginx/conf/nginx.conf 如用的是 Arch Linux).

# Generic startup file.
user {user} {group};

#一般等于你的CPU数。执行命令 "grep processor /proc/cpuinfo | wc -l" 可获得
worker_processes  2;

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

# Keeps the logs free of messages about not being able to bind().
#daemon     off;

events {
    worker_connections  1024;
}

http {
#   rewrite_log on;
    include mime.types;
    default_type       application/octet-stream;
    access_log         /var/log/nginx/access.log;
    sendfile           on;
#   tcp_nopush         on;
    keepalive_timeout  3;
#   tcp_nodelay        on;
#   gzip               on;
#php max upload limit cannot be larger than this 此参数译者设置后测试失败      
    client_max_body_size 13m;
    index              index.php index.html index.htm;

    # Upstream to abstract backend connection(s) for PHP.
    upstream php {
        #this should match value of "listen" directive in php-fpm pool
        server unix:/tmp/php-fpm.sock;
#       server 127.0.0.1:9000;
    }

    include sites-enabled/*;
}

与标准的 nginx.conf 文件稍微有点不同,此配置遵循 Ubuntu / Debian 声明的最大弹性启动站点(enabled sites)法- - 用“sites-available”存储一个配置, 然后链接到"sites-enabled"中的配置文件 。

单站点配置(Per Site Configuration)

# Redirect everything to the main site. We use a separate server statement and NOT an if statement - see http://wiki.nginx.org/IfIsEvil

server {
        server_name  _;
        return 302 $scheme://example.com$request_uri;
}

server {
    server_name example.com;
    root /var/www/example.com;

    index index.php;

    include global/restrictions.conf;

    #附加规则可以写在这里

    # 下面的文件只能包含一个
    include global/wordpress.conf;
#   include global/wordpress-ms-subdir.conf;
#   include global/wordpress-ms-subdomain.conf;
}

将配置分成多个片段放在多个文件中,可以允许同样的逻辑复用。'global'子目录可用于添加额外功能配置(通用功能)。(基于Nginx的安装设置情况,目录可能是 /etc/nginx/conf/global/ 也可能是 /etc/nginx/global/)

全局限制文件

# Global restrictions configuration file.
# Designed to be included in any server {} block.
location = /favicon.ico {
    log_not_found off;
    access_log off;
}

location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}

# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~ /\. {
    deny all;
}

# Deny access to any files with a .php extension in the uploads directory
# Works in sub-directory installs and also in multisite network
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~* /(?:uploads|files)/.*\.php$ {
    deny all;
}

General WordPress rules

对于单个站点安装情况来说,这就是 'global/wordpress.conf'文件:

# WordPress single site rules.
# Designed to be included in any server {} block.
# Upstream to abstract backend connection(s) for php
upstream php {
        server unix:/tmp/php-cgi.socket;
        server 127.0.0.1:9000;
}

server {
        ## Your website name goes here.
        server_name domain.tld;
        ## Your only path reference.
        root /var/www/wordpress;
        ## This should be in your http block and if it is, it's not needed here.
        index index.php;

        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }

        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }

        location / {
                # This is cool because no php is touched for static content.
                # include the "?$args" part so non-default permalinks doesn't break when using query string
                try_files $uri $uri/ /index.php?$args;
        }

        location ~ \.php$ {
                #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
                include fastcgi.conf;
                fastcgi_intercept_errors on;
                fastcgi_pass php;
                fastcgi_buffers 16 16k;
                fastcgi_buffer_size 32k;
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;
        }
}

nginxv.10及之后版本的最新例子,请Ref: https://www.nginx.com/resources/wiki/start/topics/recipes/wordpress/

WordPress Multisite Subdirectory rules

多网站子目录安装,对应的 'global/wordpress.conf'文件如下:

# WordPress multisite subdirectory rules.
# Designed to be included in any server {} block.
map $uri $blogname{
    ~^(?P<blogpath>/[^/]+/)files/(.*)       $blogpath ;
}

map $blogname $blogid{
    default -999;

    #Ref: http://wordpress.org/extend/plugins/nginx-helper/
    #include /var/www/wordpress/wp-content/plugins/nginx-helper/map.conf ;
}

server {
    server_name example.com ;

    root /var/www/example.com/htdocs;
    index index.php;

    location ~ ^(/[^/]+/)?files/(.+) {
        try_files /wp-content/blogs.dir/$blogid/files/$2 /wp-includes/ms-files.php?file=$2 ;
        access_log off;     log_not_found off; expires max;
    }

    #avoid php readfile()
    location ^~ /blogs.dir {
        internal;
        alias /var/www/example.com/htdocs/wp-content/blogs.dir ;
        access_log off;     log_not_found off; expires max;
    }

    if (!-e $request_filename) {
        rewrite /wp-admin$ $scheme://$host$uri/ permanent;
        rewrite ^(/[^/]+)?(/wp-.*) $2 last;
        rewrite ^(/[^/]+)?(/.*\.php) $2 last;
    }

    location / {
        try_files $uri $uri/ /index.php?$args ;
    }

    location ~ \.php$ {
        try_files $uri =404;
        include fastcgi_params;
        fastcgi_pass php;
    }

    #add some rules for static content expiry-headers here
}

Ref: https://www.nginx.com/resources/wiki/start/topics/recipes/wordpress/

HTTPS in Nginx

在Nginx中打开HTTPS非常简单(译者:确实简单,但是WordPress要跑正确可不容易,大家记得要保留http的入口,另外后台设置的地址记得修改)

server {
    # 同时监听 IPv4 and IPv6 on 443 ,并且打开and enables HTTPS and HTTP/2 support.
    # HTTP/2 is available in nginx 1.9.5 and above.
    listen *:443 ssl http2;
    listen [::]:443 ssl http2;

    # indicate locations of SSL key files.
    ssl_certificate /srv/www/ssl/ssl.crt;
    ssl_certificate_key /srv/www/ssl/ssl.key;
    ssl_dhparam /srv/www/master/ssl/dhparam.pem;
    
    # indicate the server name
    server_name example.com *.example.com;

    # Enable HSTS. This forces SSL on clients that respect it, most modern browsers. The includeSubDomains flag is optional.
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

    # Set caches, protocols, and accepted ciphers. 
    # This config will merit an A+ SSL Labs score as of Sept 2015.
    ssl_session_cache shared:SSL:20m;
    ssl_session_timeout 10m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:CAMELLIA256-SHA:CAMELLIA128-SHA256;
}

Mozilla 提供了一个非常棒的 SSL 配置生成工具

PS:下面是关于引用和缓存的一些东西。待续:

WP Super Cache Rules

W3Total Cache Rules

Nginx fastcgi_cache

Better Performance for Static Files in Multisite

Notes

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容