How to Setup WordPress on Nginx, PHP-FPM and MySQL

WordPress website can be served using Apache or NGINX. Apache is the most popular Web server and most widely used for WordPress blogging platform. Apache is a great option and has served many of the world’s largest Web sites. Alternate web server for Apache is Nginx, pronounced “Engine X”. Nginx is an open source web server and a reverse proxy server for HTTP, SMTP, POP3 and IMAP protocols. Many websites and the web developer have moved to NGINX because it’s scalable, low resources, can handle many users concurrency and good website performance. For largest and busiest website, i would suggest you to host you websites and blog on Virtual Private Server (VPS) or dedicated server and run NGINX as a web server. Assumed that MySQL has been prepared and configured for WordPress and was tested on CentOS 6.5.

1. Prepared Nginx Repository :

[root@vps ~]# vi /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

2. Install NGINX, PHP, php-fpm amd MySQL server :

[root@vps ~]# yum install nginx php php-cli php-mysql php-gd php-xml php-fpm mysql mysql-server -y

3. Open /etc/php.ini and set cgi.fix_pathinfo=0:

[root@vps ~]# vi /etc/php.ini
..
..
; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI.  PHP's
; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is.  For more information on PATH_INFO, see the cgi specs.  Setting
; this to 1 will cause PHP CGI to fix its paths to conform to the spec.  A setting
; of zero causes PHP to behave as before.  Default is 1.  You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
; http://www.php.net/manual/en/ini.core.php#ini.cgi.fix-pathinfo
cgi.fix_pathinfo=0
..
..

4. Set date.timezone in /etc/php.ini :

[Date]
; Defines the default timezone used by the date functions
; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone
date.timezone = "Asia/Kuala_Lumpur"

5. This server configuration was setup for PHP-FPM use a UNIX Socket.

[root@vps ~]# vim /etc/php-fpm.d/www.conf

Specify .sock path :

..
listen = /var/run/php-fpm.sock
..

Change user to run php-fpm :

..
user = nginx
..
..
group = nginx
..

6. Backup NGINX config file :

[root@vps ~]# cp -p /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak

7. Create sites-available folder under /etc/nginx :

[root@vps ~]# mkdir /etc/nginx/sites-available

8. Adjust NGINX Worker Processes & Connections. NGINX workers equal the number of processors :

See also  9 Steps to Setup Dedicated Server for your Website

Check Number CPU on your VPS server :

[root@vps ~]# lscpu | grep '^CPU(s)'
CPU(s):                1

or

[root@vps ~]# cat /proc/cpuinfo | grep processor
processor       : 0
..
worker_processes  1;
..
..
worker_connections  1024;
..

Configure nginx.conf as below :

user  nginx;
worker_processes  1;

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


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    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;

    
    include /etc/nginx/sites-available/*.conf;
}

9. Create common.conf and wordpress.conf under /etc/nginx/conf.d/ folder :

[root@vps ~]# vim /etc/nginx/conf.d/common.conf
[root@vps ~]# vim /etc/nginx/conf.d/wordpress.conf
[root@vps ~]# vim /etc/nginx/conf.d/common.conf

Add the following :

# Global configuration file.
# ESSENTIAL : Configure Nginx Listening Port
listen 80;
# ESSENTIAL : Default file to serve. If the first file isn't found,
index index.php index.html index.htm;
# ESSENTIAL : no favicon logs
location = /favicon.ico {
    log_not_found off;
    access_log off;
}
# ESSENTIAL : robots.txt
location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}
# ESSENTIAL : Configure 404 Pages
error_page 404 /404.html;
# ESSENTIAL : Configure 50x Pages
error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }
# SECURITY : Deny all attempts to access hidden files .abcde
location ~ /\. {
    deny all;
}
# PERFORMANCE : Set expires headers for static files and turn off logging.
location ~* ^.+\.(js|css|swf|xml|txt|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 30d;

Explanation :

listen 80; 

-Specifies the listening port of the server.

index index.php index.html index.htm;

-Specifies the default file to serve (WordPress index.php). For HTML sites, please include index.html & index.htm;.

location = /robots.txt {allow all;} 

-Allows the access to robots.txt

See also  How to Check or Test Reverse DNS on Linux and Windows

Create wordpress.conf :

[root@vps ~]# vim /etc/nginx/conf.d/wordpress.conf

Add the following :

# WORDPRESS : Rewrite rules, sends everything through index.php and keeps the appended query string intact
location / {
    try_files $uri $uri/ /index.php?q=$uri&$args;
}

# SECURITY : Deny all attempts to access PHP Files in the uploads directory
location ~* /(?:uploads|files)/.*\.php$ {
    deny all;
}
# REQUIREMENTS : Enable PHP Support
location ~ \.php$ {
    # SECURITY : Zero day Exploit Protection
    try_files $uri =404;
    # ENABLE : Enable PHP, listen fpm sock
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# PLUGINS : Enable Rewrite Rules for Yoast SEO SiteMap
rewrite ^/sitemap_index\.xml$ /index.php?sitemap=1 last;
rewrite ^/([^/]+?)-sitemap([0-9]+)?\.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;

Explanation :

try_files $uri $uri/ /index.php?q=$uri&$args 

-rewrite rule required to allow you to choose your custom permalink structure on WordPress.

location ~* /(?:uploads|files)/.*\.php$ {deny all;} 

-this will prevent malicious code from being uploaded and executed from the WordPress media directory.

location ~ \.php$ {...}

-since WordPress is a php site, we need to tell NGINX how to a pass our php scripts to PHP5.

try_files $uri =404; 

-this is a security rule, you only want to either serve a determined php file or go to a 404 error.

See also  How to Install "setup" Command on Fedora 16

10. Create a virtual server under /etc/nginx/sites-available/ directory :

[root@vps ~]# vi /etc/nginx/sites-available/ehowstuff.local.conf

Assumed that you want to configure a WordPress site with www.ehowstuff.local domain, please setup as below :

server {
    server_name ehowstuff.local;
    rewrite ^/(.*)$ http://www.ehowstuff.local/$1 permanent;
}

server {
        server_name www.ehowstuff.local;
        root /var/www/html/wordpress;
        access_log /var/log/nginx/www.ehowstuff.local.access.log;
        error_log /var/log/nginx/www.ehowstuff.local.error.log;
        include conf.d/common.conf;
        include conf.d/wordpress.conf;
}

Please change the following for virtual server ehowstuff.local.conf :

server_name: Define the server block for the URL.
root: Where you keep your website file
access log & error log: Paths for your logs

11. Start php-fpm and nginx :

[root@vps ~]# /etc/init.d/php-fpm start
Starting php-fpm:                                          [  OK  ]
[root@vps ~]# /etc/init.d/nginx start
Starting nginx:                                            [  OK  ]

12. Make php-fpm and nginx start at boot :

[root@vps ~]# chkconfig php-fpm on
[root@vps ~]# chkconfig nginx on

13. Verify that the required port already present.

[root@vps ~]# netstat -plunt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name
tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LISTEN      1042/rpcbind
tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      3174/nginx
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      1096/sshd
tcp        0      0 0.0.0.0:3306                0.0.0.0:*                   LISTEN      3394/mysqld
tcp        0      0 :::111                      :::*                        LISTEN      1042/rpcbind
tcp        0      0 :::22                       :::*                        LISTEN      1096/sshd
udp        0      0 0.0.0.0:111                 0.0.0.0:*                               1042/rpcbind
udp        0      0 0.0.0.0:793                 0.0.0.0:*                               1042/rpcbind
udp        0      0 :::111                      :::*                                    1042/rpcbind
udp        0      0 :::793                      :::*                                    1042/rpcbind

How to Reset the Directory Manager Password on RHEL 7 / CentOS 7
How to Reset the Directory Manager Password on RHEL 7 / CentOS 7

It is best practice to remember passwords, but because too many passwords, sometimes we forget. We are not encouraged to write the password on any paper or share the password...

How to Find Big Files Size on Linux RHEL/CentOS
How to Find Big Files Size on Linux RHEL/CentOS

As the linux administrator, sometimes we have to identify which files are most take much space in the linux server resulting in low free space. Low disk space can also...

Why Linux users should worry about malware and what they can do about it
Why Linux users should worry about malware and what they can do about it

Don’t drop your guard just because you’re running Linux. Preventing the spread of malware and/or dealing with the consequences of infection are a fact of life when using computers. If...

How to Reset Forgotten Root Password on Linux RHEL 7/CentOS 7
How to Reset Forgotten Root Password on Linux RHEL 7/CentOS 7

This article will explain the steps to reset a lost root password or to reset forgotten root password on Linux RHEL 7 or CentOS 7. Basically, the steps will adding...

How to Update CentOS or Upgrade CentOS to the Latest Version
How to Update CentOS or Upgrade CentOS to the Latest Version

Recently, the latest version of CentOS 7.3 was released. All users of CentOS 7.0, 7.1 and 7.2 can upgrade their system to the most recent. This quick guide will explain...

How to Change your WordPress Username, Nickname and Display Name in MySQL
How to Change your WordPress Username, Nickname and Display Name in MySQL

After you create an account log in WordPress, you may want to change your WordPress username, as appropriate or due to security reason. However, you can not do this from...

How to Enable SSH Root Login on Ubuntu 16.04
How to Enable SSH Root Login on Ubuntu 16.04

As what we wrote in the previous article on how to allow SSH root on Ubuntu 14.04, after installing a fresh new copy of Ubuntu 16.04 LTS, we find that...

How to Change UUID of Linux Partition on CentOS 7
How to Change UUID of Linux Partition on CentOS 7

UUID (Universally Unique IDentifier) should be unique and it is used to identify storage devices on a linux system. If you cloned a virtual machine from vCenter, the metadata containing...

Leave a Reply

Your email address will not be published. Required fields are marked *