If you follow my last two tutorials How to install LEMP web server with Nginx, PHP-FPM 5.5, MySQL 5.5 on Centos Linux and How To Install WordPress with nginx on Centos 6. You should have your WordPress website running with LEMP nginx, php-fpm and mysql stack. WordPress works perfectly fine with Apache, but you will run into some minor problems with WordPress and nginx
To install WordPress theme without ftp logins
We have not installed ftp server to our LEMP web server with Nginx, PHP-FPM 5.5, MySQL 5.5 on Centos Linux, You can install vsftpd server on centos 6 if you want to. For me, I don’t need an extra ftp server since I don’t need to upload/download anything from web server, you can install/delete WordPress themes/plugins without a ftp server by Force Direct Filewrites For install and upgrades.
edit wp-config.php file
# nano /usr/share/nginx/html/wp-config.php
and add
define('FS_METHOD', 'direct');
Next you have to give write permission to wp-content themes and plugins directory
# chmod 777 /usr/share/nginx/html/wp-content # chmod 777 /usr/share/nginx/html/wp-content/themes # chmod 777 /usr/share/nginx/html/wp-content/plugins # chmod 777 /usr/share/nginx/html/wp-content/uploads
WordPress pretty/fancy permalinks with Nginx
Default WordPress Permalink Settings is http://yourdomain.com/?p=123 which somewhat … not fancy. If you want to change your WordPress Permalink Settings to something else like /%post_id%/%postname%/ you will have to add try_files option under the / location to nginx configure file or else you will get error 404 page not found.
# nano /etc/nginx/conf.d/default.conf
Search for
location / { root /usr/share/nginx/html; index index.html index.htm index.php; }
try_files $uri $uri/ /index.php?q=$uri&$args;
You should have something like this
location / { root /usr/share/nginx/html; index index.html index.htm index.php; try_files $uri $uri/ /index.php?q=$uri&$args; }
You will have to restart nginx after modified nginx configure file.
# service nginx restart
Adjust nginx worker_processes
nginx worker_processes value should be the number of your vps or dedicated server’s cpu cores since nginx uses a fixed number of workers to handles incoming requests.
To check the number of CPU core:
$ grep ^processor /proc/cpuinfo | wc -l
Then set nginx_processes accordingly
# nano /etc/nginx/nginx.conf
In my case my vps only has 1 vcpu core, I set nginx_processes to 1
worker_processes 1;
Gzip Compression
Gzip is disabled by default in nginx, we should always use gzip compression to reduce the size of transmitted data.
# nano /etc/nginx/nginx.conf
Search for
# gzip on
and replace with
gzip on; gzip_comp_level 3; gzip_buffers 16 8k; gzip_vary on; gzip_proxied any; gzip_min_length 1000; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; gzip_disable "MSIE [1-6]\.(?!.*SV1)";
# service nginx restart
php-fpm user/group
If you won’t want to deal with files/directories permission problem with php-fpm processes, you can change user/group for php-fpm. By default php-fpm will use apache user/group. In centos 6, you can change user/group for php-fpm in www.conf file.
# nano /etc/php-fpm.d/www.conf
Search for
; Unix user/group of processes ; Note: The user is mandatory. If the group is not set, the default user's group ; will be used. ; RPM: apache Choosed to be able to access some dir as httpd user = apache ; RPM: Keep a group allowed to write in log dir. group = apache
; Unix user/group of processes ; Note: The user is mandatory. If the group is not set, the default user's group ; will be used. ; RPM: apache Choosed to be able to access some dir as httpd user = namhuy ; RPM: Keep a group allowed to write in log dir. group = namhuy
Moving nginx $document_root to different location
If you want to store your www or public_html directory in your /home/user directory, you may run into File not found error because PHP files are not readable by the PHP process. To solve this problem, you have to make the files/directories world readable.
chmod a+x /home/user/ chmod a+x /home/user/public_html
phpmyadmin and nginx
If you downloaded phpmyadmin and it gives you blank page when you try to access phpmyadmin directory with your web browser. The first place to look is nginx error log.
# cat /var/log/nginx/error.log
This is the error for phpmyadmin
2014/04/30 16:39:04 [crit] 5408#0: *28 open() "/var/lib/nginx/tmp/fastcgi/3/00/0000000003" failed (13: Permission denied) while reading upstream .... referrer: "http://www.namhuy.net/phpmyadmin/
To give nginx or your user to have access to /var/lib/nginx directory, use this command (change the directory and user according to your error and your username)
# chmod 777 /var/lib/nginx/
or
# chown user:user /var/lib/nginx/
nginx redirect www to non-www
WordPress depends on .htaccess file to redirect www to non-www or another way. Since nginx does not support .htaccess, if you want to redirect www to non-www domain, you have to modify nginx conf file. Depends on your nginx setup, I will use default.conf for our sample
# nano /etc/nginx/conf.d
and add to the top of the file
server { listen 80; server_name www.domain.com; return 301 $scheme://domain.com$request_uri; }
server { listen 80; server_name www.domain.com; rewrite ^(.*) http://domain.com$1 permanent; }
nginx redirect non-www to www
server { listen 80; server_name domain.com; return 301 $scheme://www.domain.com$request_uri; }
server { listen 80; server_name domain.com; rewrite ^(.*) http://www.domain.com$1 permanent; }
Port 8080 url error with varnish and nginx
Varnish plays nice with Apache but not with nginx. If you are running nginx backend and varnish frontend, you will eventually get domain.com:8080 and your web browser won’t load it since port 8080 is backend for varnish and nginx to communicate with each other. The problem occurs if the URL without a tailing slash “/”, the URL will redirect to port 8080 instead of regular port 80 for http. To solve that problem, you will have to add “port_in_redirect off” to the directives which cause the problem. By default nginx set port_in_redirect value is on. We will turn if off.
For example, every time i login to wordpress, wp-admin WordPress Admin Panel will redirect the url to port 80. If you only have one nginx config file in /etc/nginx/conf.d , for example default.conf, edit your nginx website config file
# nano /etc/nginx/conf.d/default.conf
and add
port_in_redirect off;
to the main nginx directive
Your default wordpress nginx config file should look like
location / { root /home/user/public_html/domain.com; index index.html index.htm index.php; try_files $uri $uri/ /index.php?q=$uri&$args; port_in_redirect off; }
W3 Total Cache and nginx
W3 Total Cache or w3tc is a great WordPress caching plugin, there are several caching plugins for WordPress out there but W3TC is still my favorite all time. Anyway, back to our business, w3tc plays nicely with Apache since Apache supports .htaccess file. The story is quite different with nginx which does no support .htaccess file. As if you are reading this you might have run into some sort of problem with w3tc and nginx. In order to use w3tc with nginx, w3tc requires you to create nginx.conf file under your website root directory. You can find the content of w3tc nginx.conf file from your WordPress Admin Panel, Performance, and Install on the left tab.
This is the sample nginx.conf file from w3tc
# BEGIN W3TC Page Cache cache location ~ /wp-content/cache/page_enhanced.*html$ { expires modified 3600s; add_header X-Powered-By "W3 Total Cache/0.9.4"; add_header Vary "Accept-Encoding, Cookie"; add_header Pragma "public"; add_header Cache-Control "max-age=3600, public"; } location ~ /wp-content/cache/page_enhanced.*gzip$ { gzip off; types {} default_type text/html; expires modified 3600s; add_header X-Powered-By "W3 Total Cache/0.9.4"; add_header Vary "Accept-Encoding, Cookie"; add_header Pragma "public"; add_header Cache-Control "max-age=3600, public"; add_header Content-Encoding gzip; } # END W3TC Page Cache cache # BEGIN W3TC Browser Cache gzip on; gzip_types text/css text/x-component application/x-javascript application/javascript text/javascript text/x-js text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon; location ~ \.(css|htc|less|js|js2|js3|js4)$ { expires 31536000s; add_header Pragma "public"; add_header Cache-Control "max-age=31536000, public"; add_header X-Powered-By "W3 Total Cache/0.9.4"; } location ~ \.(htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml)$ { expires 3600s; add_header Pragma "public"; add_header Cache-Control "max-age=3600, public"; add_header X-Powered-By "W3 Total Cache/0.9.4"; } location ~ \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|json|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|woff|xla|xls|xlsx|xlt|xlw|zip)$ { expires 31536000s; add_header Pragma "public"; add_header Cache-Control "max-age=31536000, public"; add_header Link "; rel=\"canonical\""; add_header X-Powered-By "W3 Total Cache/0.9.4"; } # END W3TC Browser Cache # BEGIN W3TC CDN location ~ \.(ttf|ttc|otf|eot|woff|font.css)$ { add_header Access-Control-Allow-Origin "*"; } # END W3TC CDN # BEGIN W3TC Minify core rewrite ^/wp-content/cache/minify.*/w3tc_rewrite_test$ /wp-content/plugins/w3-total-cache/pub/minify.php?w3tc_rewrite_test=1 last; rewrite ^/wp-content/cache/minify/(.+/[X]+\.css)$ /wp-content/plugins/w3-total-cache/pub/minify.php?test_file=$1 last; rewrite ^/wp-content/cache/minify/(.+\.(css|js))$ /wp-content/plugins/w3-total-cache/pub/minify.php?file=$1 last; # END W3TC Minify core # BEGIN W3TC Page Cache core set $w3tc_rewrite 1; if ($request_method = POST) { set $w3tc_rewrite 0; } if ($query_string != "") { set $w3tc_rewrite 0; } if ($http_cookie ~* "(comment_author|wp\-postpass|w3tc_logged_out|wordpress_logged_in|wptouch_switch_toggle)") { set $w3tc_rewrite 0; } if ($http_cookie ~* "(w3tc_preview)") { set $w3tc_rewrite _preview; } set $w3tc_enc ""; if ($http_accept_encoding ~ gzip) { set $w3tc_enc _gzip; } set $w3tc_ext ""; if (-f "$document_root/wp-content/cache/page_enhanced/$http_host/$request_uri/_index$w3tc_rewrite.html$w3tc_enc") { set $w3tc_ext .html; } if (-f "$document_root/wp-content/cache/page_enhanced/$http_host/$request_uri/_index$w3tc_rewrite.xml$w3tc_enc") { set $w3tc_ext .xml; } if ($w3tc_ext = "") { set $w3tc_rewrite 0; } if ($w3tc_rewrite = 1) { rewrite .* "/wp-content/cache/page_enhanced/$http_host/$request_uri/_index$w3tc_rewrite$w3tc_ext$w3tc_enc" last; } # END W3TC Page Cache core
You are supported to create nginx.conf file under your website root directory. From How to install LEMP web server with Nginx, PHP-FPM 5.5, MySQL 5.5 on Centos Linux nginx default root document is /usr/share/nginx/html/ . Depends on how you setup your nginx document_root may be different.
w3tc wants you to create nginx.conf under your website root directory, but nginx itself does not read that nginx.conf file from w3tc by default. There are two ways to make nginx read the w3tc nginx.conf file, the first way is to use “include” to link w3tc nginx.conf file to the main nginx configure file. Depends on how you configure your nginx, edit the .conf file for your website/domain
# nano /etc/nginx/conf.d/default.conf
or
# nano /etc/nginx/conf.d/domain.com.conf
add the link to w3tc nginx.conf file wherever you store it in server { your website/domain config here }
server { listen 80; server_name namhuy.net; root /var/www/namhuy.net; index index.php; # your other nginx config, add include link before you close server loop # include /var/www/namhuy.net/nginx.conf; }
# nano /etc/nginx/conf.d/default.conf
# nano /etc/nginx/conf.d/domain.com.conf
server { listen 80; server_name namhuy.net; root /var/www/namhuy.net; index index.php; # your other nginx config, add full w3tc nginx.conf content before you close server loop # full w3tc nginx.conf's content goes here }
If you are using shared hosting and you don’t have access to nginx configure files, ask your hosting provider to use “include” to link to the nginx.conf under your website/domain root directory.
Disable Nginx access log
Generally you don’t need nginx access log, if you have a busy website, nginx access log will be easily increased in GB daily which will waste your hosting disk space. By default nginx access log is on, you can find and adjust nginx access log in nginx.conf file
# nano /etc/nginx/nginx.conf
You should see something like this
access_log /var/log/nginx/access.log;
You can’t just comment that line out with hash sign #, that won’t turn access_log off. You have to change nginx access_log to off to turn it off
access_log off;