Installing WordPress + W3TotalCache with LEMP on CentOS for Maximum Performance

Nginx is free high performance HTTP web server c, open source, which, unlike some other web servers, does not rely on streaming requests, instead it uses a much more scalable event driven (asynchronous) architecture.

This uses a very small and predictable amount of memory under heavy load. Nginx combined with a simple and very robust FastCGI Process for PHP ( PHP-FPM ) and the most popular database server MySQL can give you a lot of performance using a small amount of memory.

The article is divided into the following sections:

  • Initial setup
  • Installing and configuring Nginx
  • Installing and Configuring MySQL
  • Installing and configuring PHP-FPM
  • Install and configure WordPress
  • Tuning caching for best performance

Before proceeding with the installation, start a session by running:

                      screen -U -S lemp-stack
                    

Once you are in a screen session, make sure your CentOS is fully up to date by running:

                      yum update
                    

if you have Apache installed on your VPS, stop it and uninstall it by running the following command:

                      /etc/init.d/httpd stop
yum remove httpd
                    

STEP 1) Installing and Configuring Nginx

Enable the EPEL repository by running:

You can find out your VPS architecture by running

                      uname -m
                    

– 32-bit VPS:

                      wget -P /tmp https://mirror.pnl.gov/epel/6/i386/epel-release-6-8.noarch.rpm
rpm -Uvh /tmp/epel-release-6-8.noarch.rpm
rm -f /tmp/epel-release-6-8.noarch.rpm
                    

– 64-bit VPS:

                      wget -P /tmp https://mirror.itc.virginia.edu/fedora-epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -Uvh /tmp/epel-release-6-8.noarch.rpm
rm -f /tmp/epel-release-6-8.noarch.rpm
                    

Install Nginx  using the yum command:

                      yum install nginx
                    

Go to the nginx config directory /etc/nginx/  and edit nginx.conf text editor:

                      cd /etc/nginx/
vim nginx.conf
                    

                      user              nginx;
worker_processes  2;

error_log  /var/log/nginx/error.log;
#error_log  /var/log/nginx/error.log  notice;
#error_log  /var/log/nginx/error.log  info;

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  0;
    keepalive_timeout  30;
    server_tokens off;

    gzip on;
    gzip_disable "MSIE [1-6].(?!.*SV1)";
    gzip_http_version 1.1;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript text/x-js;

    # enabled sites
    include /etc/nginx/sites-enabled/*;

}
                    

Create directories sites-enabled  and sites-available  inside directory /etc/nginx :

                      mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled
                    

Configure the default Nginx virtual host directive by adding the following line to the file /etc/nginx/sites-available/default.conf

                      server {
    listen       80 default_server;
    server_name  _;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    error_page  404              /404.html;
    location = /404.html {
        root   /usr/share/nginx/html;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
                    

Enable the default nginx virtual host directive by creating a symbolic link to the default config in /etc/nginx/sites-enabled/

                      cd /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/default.conf
                    

Test Nginx configuration, add it to system startup, and finally start it with:

                      nginx -t
/etc/init.d/nginx restart
chkconfig nginx on
                    

STEP 2) Installing and Configuring MySQL

Install MySQL database server, start and add it to system startup by running the following commands:

                      yum install mysql mysql-server
service mysqld restart
chkconfig mysqld on
                    

Then run below command for MySQL to secure installation

                      ## mysql_secure_installation
                    

                      Enter current password for root (enter for none):
Set root password? [Y/n] y
Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y
                    

Make sure your MySQL is not being eavesdropped on your server’s public IP by adding the following /etc/my.cnf

                      vim /etc/my.cnf

[mysqld]
bind-address = 127.0.0.1
...
                    

Restart the database server for the changes to take effect with:

                      /etc/init.d/mysqld restart
                    

STEP 3) Install and configure PHP-FPM

Install PHP-FPM  and some useful PHP extensions by running below command:

                      yum install php-fpm php-mysql php-gd php-mcrypt
                    

Edit /etc/php.ini  and change / uncomment the following:

                      cgi.fix_pathinfo=0
date.timezone = "your timezone"
memory_limit = 64M
expose_php = Off
                    

Next, edit the config file /etc/php-fpm.conf  in your editor and uncomment the following:

                      emergency_restart_threshold = 10
emergency_restart_interval = 1m
process_control_timeout = 10
                    

PHP-FPM pool created in /etc/php-fpm.d/www.conf :

                      mv /etc/php-fpm.d/www.conf /root/
## vim /etc/php-fpm.d/www.conf
                    

                      [wordpress]
;listen = 127.0.0.1:9001
listen = /var/run/php-wordpress.socket
user = nginx
group = nginx
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/blogcms.log
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 400
listen.backlog = -1
pm.status_path = /status
request_terminate_timeout = 120s
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session
php_admin_value[error_log] = /var/log/php-fpm/wordpress-error.log
php_admin_flag[log_errors] = on
                    

Reload PHP-FPM and add it at system startup:

                      /etc/init.d/php-fpm restart
chkconfig php-fpm on
                    

At this point, you must have Nginx , MySQL and PHP-FPM running on the server. Let’s continue creating the directive for your application virtual host WordPress :

                      vim /etc/nginx/sites-available/my-wordpress.ru.conf
                    

                      server {
        listen 80;
        server_name my-wordpress.ru;
        rewrite ^(.*) https://www.my-wordpress.ru$1 permanent;
}

server {
        listen 80;
        server_name www.my-wordpress.ru;

        client_max_body_size 5m;
        client_body_timeout 60;

        access_log /var/log/nginx/my-wordpress.ru-access;
        error_log /var/log/nginx/my-wordpress.ru-error error;

        root /var/www/html/my-wordpress.ru/;
        index  index.html index.php;

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

        ### security ###
        error_page 403 =404;
        location ~ /. { access_log off; log_not_found off; deny all; }
        location ~ ~$ { access_log off; log_not_found off; deny all; }
        location ~* wp-admin/includes { deny all; }
        location ~* wp-includes/theme-compat/ { deny all; }
        location ~* wp-includes/js/tinymce/langs/.*.php { deny all; }
        location /wp-includes/ { internal; }
        #location ~* wp-config.php { deny all; }
        location ~* ^/wp-content/uploads/.*.(html|htm|shtml|php)$ {
                types { }
                default_type text/plain;
        }

        #  location ~* wp-admin {
        #      allow <YOUR_IP>;
        #      allow 127.0.0.1;
        #      deny all;
        #  }

        ### disable logging ###
        location = /robots.txt { access_log off; log_not_found off; }
        location = /favicon.ico { access_log off; log_not_found off; }

        ### caches ###
        location ~* .(jpg|jpeg|gif|css|png|js|ico|html)$ { access_log off; expires max; }
        location ~* .(woff|svg)$ { access_log off; log_not_found off; expires 30d; }
        location ~* .(js)$ { access_log off; log_not_found off; expires 7d; }

        ### php block ###
        location ~ .php?$ {
                try_files $uri =404;
                include fastcgi_params;
                #fastcgi_pass 127.0.0.1:9001;
                fastcgi_pass unix:/var/run/php-wordpress.socket;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_intercept_errors on;
                fastcgi_split_path_info ^(.+.php)(.*)$;
                #Prevent version info leakage
                fastcgi_hide_header X-Powered-By;
        }
}
                    

Enable the virtual host directive and restart Nginx by running the following commands:

                      cd /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/my-wordpress.tld.conf
nginx -t
/etc/init.d/nginx restart
                    

Testing PHP-FPM by creating a PHP script info.php  in document /var/www/html/my-wordpress.ru/ :

                      mkdir -p /var/www/html/my-wordpress.ru/
cd /var/www/html/my-wordpress.ru/
echo -e "<?phpntphpinfo();n" > info.php
                    

access to test your PHP-FPM: https://my-wordpress.ru/info.php

STEP 4) WordPress setup

The next step is to install WordPress inside the document root at /var/www/html/my-wordpress.ru/.  Before installing WordPress, let’s first create a MySQL database by doing the following:

                      mysql -u root -p
                    

                      mysql> create database wordpressDB;
mysql> grant all on wordpressDB.* to [email protected] identified by 'YOUR_PASS';
mysql> quit
                    

                      cd /var/www/html/my-wordpress.ru/
wget https://wordpress.org/latest.zip
unzip latest.zip
mv wordpress/* .
rm -rf latest.zip wordpress/
                    

Next, copy the sample WordPress configuration and MySQL database configuration information:

                      cp wp-config-sample.php wp-config.php
vim wp-config.php
                    

                      define('DB_NAME', 'wordpressDB');
define('DB_USER', 'wpUser');
define('DB_PASSWORD', 'YOUR_PASS');
                    

                      chown nginx: -R /var/www/html/my-wordpress.ru/
                    

open https://my-wordpress.ru and complete the WordPress installation

STEP 5) Configure caching for best performance

Install PHP-APC (Alternative PHP Cache) by running:

                      yum install php-pecl-apc
                    

After installing APC, add the following lines to /etc/php.d/apc.ini

                      cat > /etc/php.d/apc.ini
                    

                      extension = apc.so
apc.enabled=1
apc.shm_segments=1
apc.shm_size=128M
apc.num_files_hint=1024
apc.user_entries_hint=4096
apc.ttl=7200
apc.use_request_time=1
apc.user_ttl=7200
apc.gc_ttl=3600
apc.cache_by_default=1
apc.filters
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.file_update_protection=2
apc.enable_cli=0
apc.max_file_size=1M
apc.stat=1
apc.stat_ctime=0
apc.canonicalize=0
apc.write_lock=1
apc.report_autofilter=0
apc.rfc1867=0
apc.rfc1867_prefix =upload_
apc.rfc1867_name=APC_UPLOAD_PROGRESS
apc.rfc1867_freq=0
apc.rfc1867_ttl=3600
apc.include_once_override=0
apc.lazy_classes=0
apc.lazy_functions=0
apc.coredump_unmap=0
apc.file_md5=0
apc.preload_path
                    

and restart PHP-FPM for the changes to take effect.

                      /etc/init.d/php-fpm restart
                    

check APC boot with command:

                      php -m | grep -w apc
                    

or by opening the script info.php  at the root of the document.

The next thing to do is log into your WordPress admin area and install the W3 Total Cache plugin. For the W3 Total Cache plugin to work, you must first enable SEO дружественную структуру Url.

Настройки->Постоянные ссылки->Произвольно :

                      https://my-wordpress.tld/%postname%/
                    

and then proceed with the installation W3 Total Cache … After installation, go

Performance->General Settings

and enable / disable the following options:

                      Page cache: enabled
Page cache method: Disk: Enhaced

Minify: disabled

Database Cache: enabled
Database Cache Method: Opcode: Alternative PHP Cache (APC)

Object Cache: enbabled
Object Cache Method: Opcode: Alternative PHP Cache (APC)

Browser Cache: disabled

CDN: this is up to you.
                    

Click, Save all settings  to save your changes.

Add the following line to /var/www/html/my-wordpress.tld/nginx.conf

                      cat > /var/www/html/my-wordpress.ru/nginx.conf
                    

                      # BEGIN W3TC Page Cache cache
location ~ /wp-content/cache/page_enhanced.*html$ {
    add_header Vary Cookie;
}
# END W3TC Page Cache cache
# 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 ($request_uri !~ /$) {
    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 (!-f "$document_root/wp-content/cache/page_enhanced/$http_host/$request_uri/_index.html") {
  set $w3tc_rewrite 0;
}
if ($w3tc_rewrite = 1) {
    rewrite .* "/wp-content/cache/page_enhanced/$http_host/$request_uri/_index.html" last;
}
# END W3TC Page Cache core
                    

make sure the ownership of the document root is in order by:

                      chown nginx: -R /var/www/html/my-wordpress.ru/
                    

In the next step, we have to tell Nginx to use a config file. Let’s edit the file /etc/nginx/sites-enabled/my-wordpress.ru.conf  and add / uncomment the following:

                      include /var/www/html/my-wordpress.ru/nginx.conf;
...
location ~* wp-config.php { deny all; }
                    

Let’s test the Nginx configuration file and restart it for the changes to take effect by running:

                      nginx -t
/etc/init.d/nginx restart
                    

You can also edit the WordPress config file /var/www/html/my-wordpress.ru/wp-config.php  and define the following parameters, WordPress will not query the database for the site url:

                      define('WP_HOME', 'https://my-wordpress.ru');
define('WP_SITEURL', 'https://my-wordpress.ru');
                    

Related Posts