
Наскоро забелязахме, че много хора преминават от Apache към Nginx, за да захранват своя WordPress сайт. В предишна статия говорихме за предимствата на Nginx, а сега ще ви дадем няколко съвета как да преминете към Nginx от Apache.
Преди да започнем, трябва да ви информираме, че това е тествано на:
- Arch Linux 64 bit (Nginx 0.8.54)
- Mac OSX Server Leopard и OSX Server Snow Leopard чрез MacPorts (Nginx 0.8.54, поддръжката на php-fpm изисква модифициране на PHP 5.3 „Portfile“)
- Ubuntu Server 10.04 LTS (Nginx 0.8.54 с php-fpm)
В момента конфигурацията на WordPress е в голяма степен обвързана с Apache, така че настройките и поддръжката за Nginx са ограничени.
Следователно, ако искате WordPress да работи с Nginx, трябва да го конфигурирате по този начин. За целта са налични опциите: fastcgi или php-fpm.
Ще ви покажем как да конфигурирате с втората опция – php-fpm, защото е по-лесна. За да бъде по-разбираемо, сме разделили конфигурацията на пет файла:
Main (generic) startup file
Тази конфигурация работи, ако използвате Arch Linux. Това, което ще покажем, е еквивалентно на:
/etc/nginx/nginx.conf (или /etc/nginx/conf/nginx.conf
# Generic startup file. user {user} {group};
#ususally equal to number of CPU’s you have. run command „grep processor /proc/cpuinfo | wc -l“ to find it
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 конфигурации и е малко трудно. Но с малко усилия можем да го направим.
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 _;
rewrite ^ $scheme://mysite.com$request_uri redirect;
}server {
server_name mysite.com;
root /var/www/mysite.com;index index.php;
include global/restrictions.conf;
Additional rules go here.
Only include one of the files below.include global/wordpress.conf;
include global/wordpress-ms-subdir.conf;
include global/wordpress-ms-subdomain.conf;}
Global restrictions file
# Global restrictions configuration file. # Designed to be included in any server {} block.</p> 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
Това е за инсталация на единични блогове:
# WordPress single blog rules. # Designed to be included in any server {} block.
This order might seem weird – this is attempted to match last if rules below fail.location / {
try_files $uri $uri/ /index.php?$args;
}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;
}Uncomment one of the lines below for the appropriate caching plugin (if used).
#include global/wordpress-wp-super-cache.conf;
#include global/wordpress-w3-total-cache.conf;Pass all .php files onto a php-fpm/php-fcgi server.
location ~ [^/].php(/|$) {
fastcgi_split_path_info ^(.+?.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}This is a robust solution for path info security issue and works with „cgi.fix_pathinfo = 1“ in /etc/php.ini (default)
include fastcgi.conf;
fastcgi_index index.php;fastcgi_intercept_errors on;
fastcgi_pass php;
}
URL Rewrites / Permalinks
В момента WordPress има проверка за Apache, но ако сте решили да използвате nginx, трябва да използвате версия на WordPress по-висока от 3.7.
Можете да използвате плъгина Nginx Helper или да въведете това в плъгин:
add_filter( ‘got_rewrite’, ‘__return_true’ );
Също така този код „/wp-content/mu-plugins/nginx.php“ няма да бъде деактивиран. За да имате филтър ‘__return_true’, ще трябва да използвате версия на WordPress по-висока от 3.0.
WordPress Multisite Subdirectory rules
‘global/wordpress.conf’
# WordPress multisite subdirectory rules. # Designed to be included in any server {} block.
This order might seem weird – this is attempted to match last if rules below fail.location / {
try_files $uri $uri/ /index.php?$args;
}Directives to send expires headers and turn off 404 error logging.
location ~* .(js|css|png|jpg|jpeg|gif|ico)$ {
expires 24h;
log_not_found off;
}location ~ ^/[_0-9a-zA-Z-]+/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;
}Uncomment one of the lines below for the appropriate caching plugin (if used).
#include global/wordpress-ms-subdir-wp-super-cache.conf;
#include global/wordpress-ms-subdir-w3-total-cache.conf;Rewrite multisite ‘…/wp-.’ and ‘…/.php’.
if (!-e $request_filename) {
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
rewrite ^/[_0-9a-zA-Z-]+(/wp-.) $1 last;
rewrite ^/[_0-9a-zA-Z-]+(/..php)$ $1 last;
}Pass all .php files onto a php-fpm/php-fcgi server.
location ~ .php$ {
Zero-day exploit defense.
http://forum.nginx.org/read.php?2,88845,page=3
Won’t work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
Comment the ‘try_files’ line out if you set up php-fpm/php-fcgi on another machine. And then cross your fingers that you won’t get hacked.try_files $uri =404;
fastcgi_split_path_info ^(.+.php)(/.+)$;
#NOTE: You should have „cgi.fix_pathinfo = 0;“ in php.iniinclude fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;fastcgi_intercept_errors on;
fastcgi_pass php;
}
WP Super Cache Rules
# WP Super Cache rules. # Designed to be included from a ‘wordpress-ms-…’ configuration file.
set $cache_uri $request_uri;
POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
set $cache_uri ‘null cache’;
}if ($query_string != „“) {
set $cache_uri ‘null cache’;
}Don’t cache uris containing the following segments
if ($request_uri ~* „(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(index)?.xml|[a-z0-9-]+-sitemap([0-9]+)?.xml)“) {
set $cache_uri ‘null cache’;
}Don’t use the cache for logged in users or recent commenters
if ($http_cookie ~* „comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in“) {
set $cache_uri ‘null cache’;
}START MOBILE
Mobile browsers section to server them non-cached version. COMMENTED by default as most modern wordpress themes including twenty-eleven are responsive. Uncomment config lines in this section if you want to use a plugin like WP-Touch
if ($http_x_wap_profile) {
set $cache_uri ‘null cache’;#}
#if ($http_profile) {
set $cache_uri ‘null cache’;
#}
#if ($http_user_agent ~* (2.0\ MMP|240×320|400X240|AvantGo|BlackBerry|Blazer|Cellphone|Danger|DoCoMo|Elaine/3.0|EudoraWeb|Googlebot-Mobile|hiptop|IEMobile|KYOCERA/WX310K|LG/U990|MIDP-2.|MMEF20|MOT-V|NetFront|Newt|Nintendo\ Wii|Nitro|Nokia|Opera\ Mini|Palm|PlayStation\ Portable|portalmmm|Proxinet|ProxiNet|SHARP-TQ-GX10|SHG-i900|Small|SonyEricsson|Symbian\ OS|SymbianOS|TS21i-10|UP.Browser|UP.Link|webOS|Windows\ CE|WinWAP|YahooSeeker/M1A1-R2D2|iPhone|iPod|Android|BlackBerry9530|LG-TU915\ Obigo|LGE\ VX|webOS|Nokia5800)) {
set $cache_uri ‘null cache’;
#}
#if ($http_user_agent ~* (w3c\ |w3c-|acs-|alav|alca|amoi|audi|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-|dang|doco|eric|hipt|htc_|inno|ipaq|ipod|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-|lg/u|maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|palm|pana|pant|phil|play|port|prox|qwap|sage|sams|sany|sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo|teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|wap-|wapa|wapi|wapp|wapr|webc|winw|winw|xda\ |xda-)) {
set $cache_uri ‘null cache’;
#}
#END MOBILEUse cached or actual file if they exists, otherwise pass request to WordPress
location / {
try_files /wp-content/cache/supercache/$http_host/$cache_uri/index.html $uri $uri/ /index.php?$args ;
}
Ако използвате HTTPS, WordPress Super Cache може да използва различна директория, за да прави разлика между HTTP и HTTPS.
location / { try_files /wp-content/cache/supercache/$http_host/$scheme$cache_uri/index.html $uri $uri/ /index.php?$args ; }
W3 Total Cache Rules
Третата версия на WordPress използва различна структура на директориите само за кеширане на диска. Това също зависи от конфигурацията, която сте направили.
#W3 TOTAL CACHE CHECK set $cache_uri $request_uri;
POST requests and urls with a query string should always go to PHPif ($request_method = POST) {
set $cache_uri ‘null cache’;
}
if ($query_string != „“) {
set $cache_uri ‘null cache’;
}Don’t cache uris containing the following segments
if ($request_uri ~* „(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(index)?.xml|[a-z0-9-]+-sitemap([0-9]+)?.xml)“) {
set $cache_uri ‘null cache’;
}Don’t use the cache for logged in users or recent commenters
if ($http_cookie ~* „comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in“) {
set $cache_uri ‘null cache’;
}
#ADD mobile rules from WP SUPER CACHE section above#APPEND A CODE BLOCK FROM BELOW…
FOR Normal WordPress (without Multisite)
# Use cached or actual file if they exists, otherwise pass request to WordPress location / { try_files /wp-content/w3tc/pgcache/$cache_uri/_index.html $uri $uri/ /index.php?$args ; }
FOR Multisite with subdirectories
if ($request_uri ~* „^/([_0-9a-zA-Z-]+)/.*“ ){ set $blog $1; }
set $blog „${blog}.“;
if ( $blog = „blog.“ ){
set $blog „“;
}Use cached or actual file if they exists, otherwise pass request to WordPress
location / {
try_files /wp-content/w3tc-$blog$host/pgcache$cache_uri/_index.html $uri $uri/ /index.php?$args ;
}
FOR Multisite with Subdomains/Domain-mapping
location / { try_files /wp-content/w3tc-$host/pgcache/$cache_uri/_index.html $uri $uri/ /index.php?$args; }
Важно е да знаете следното:
Nginx може автоматично да обработва gzip и кеширането в браузъра, така че е по-добре да оставите тази част на nginx.
Minify правилата на W3 Total Cache ще работят с горната конфигурация без никакви проблеми.
Nginx fastcgi_cache
Nginx извършва кеширане самостоятелно. Но когато използвате вградения fastcgi_cache на Nginx, трябва да компилирате Nginx с fastcgi_cache_purge.
Ето как ще изглежда тази конфигурация.
Дефинирайте Nginx cache зона в блока http{…}, извън блока server{…}
#move next 3 lines to /etc/nginx/nginx.conf if you want to use fastcgi_cache across many sites fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=WORDPRESS:500m inactive=60m; fastcgi_cache_key „$scheme$request_method$host$request_uri“; fastcgi_cache_use_stale error timeout invalid_header http_500;
или в конфигурацията на WordPress сайта, в блока server{..} добавете проверка за кеш, както следва
#fastcgi_cache start set $no_cache 0;
POST requests and urls with a query string should always go to PHPif ($request_method = POST) {
set $no_cache 1;
}
if ($query_string != „“) {
set $no_cache 1;
}Don’t cache uris containing the following segments
if ($request_uri ~* „(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(index)?.xml|[a-z0-9-]+-sitemap([0-9]+)?.xml)“) {
set $no_cache 1;
}Don’t use the cache for logged in users or recent commenters
if ($http_cookie ~* „comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in“) {
set $no_cache 1;
}
След това направете промени в блока за обработка на PHP
fastcgi_cache_bypass $no_cache; fastcgi_no_cache $no_cache;
fastcgi_cache WORDPRESS;
fastcgi_cache_valid 200 60m;
За да стане нещо подобно на това
location ~ [^/]\.php(/|$) { fastcgi_split_path_info ^(.+?\.php)(/.*)$; if (!-f $document_root$fastcgi_script_name) { return 404; } # This is a robust solution for path info security issue and works with „cgi.fix_pathinfo = 1“ in /etc/php.ini (default)
include fastcgi.conf;
fastcgi_index index.php;fastcgi_intercept_errors on;
fastcgi_pass php;
fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;fastcgi_cache WORDPRESS;
fastcgi_cache_valid 200 60m;
}
Накрая добавете location за условно изчистване (purge)
location ~ /purge(/.*) { # Uncomment the following two lines to allow purge only from the webserver #allow 127.0.0.1; #deny all;
fastcgi_cache_purge WORDPRESS „$scheme$request_method$host$1“;
}
По-добра производителност за статични файлове в Multisite
За по-добра производителност на Nginx конфигурирайте
Това:
map $http_host $blogid { default 0;
example.com 1;
site1.example.com 2;
site1.com 2;
}
Към това:
map $http_host $blogid { default 0;
include /path/to/map.conf ;
}
И създайте:
location ~ ^/files/(.*)$ { try_files /wp-content/blogs.dir/$blogid/$uri /wp-includes/ms-files.php?file=$1 ; access_log off; log_not_found off; expires max; }
Бележки:
- Nginx автоматично ще картографира при всяко изтриване или добавяне на сайт.
- С този метод няма да има проблеми със случайни изтривания.
- Идеално за по-големи мрежи.
Тази конфигурация се използва, когато коренът на сайта е блог. Ако поставите този блог в различна директория, ще трябва да промените правилата.
Използвайки това:
set $wp_subdir „/blog“;
Предупреждение За да тествате дали директорията „uploads“ е наистина защитена, създайте PHP файл с някакво съдържание (пример: <?php phpinfo(); ?>), качете го в директорията „uploads“ (или някоя от нейните поддиректории), след което се опитайте да го достъпите (изпълните) през браузъра.
Resource: https://codex.wordpress.org/Nginx


