public

Wordpress Optimization: Setting Up a Web Server

Welcome to part 3 of 8 on Kick-Ass WordPress Optimization [https://webofmike.com/kick-ass-wordpress-optimization/]: Setting Up a Web Server!  In this segment we'll be covering the implementation of a web

9 years ago

Latest Post Maximizing DevOps Efficiency: Best Practices, KPIs, and Realtime Feedback by Mike Moore public

Welcome to part 3 of 8 on Kick-Ass WordPress Optimization: Setting Up a Web Server!  In this segment we'll be covering the implementation of a web server on your virtual (or regular) server that we set up in the previous segment or part 2 of 8: Setting Up a Virtual Server.  If you haven't already done this... you may want to go back and get this going before you end up here.

Wordpress Optimization: Web Server Set Up

This segment will cover the following topics:

  1. nginx Web Server – Because I won’t be covering Apache.
  2. Installing PHP
    1. Installing PHP-FPM and Tuning It
    2. Installing PHP Modules
  3. Basic nginx Configuration
  4. Configuring Your Website on Nginx
    1. Generic Configuration Files
    2. Your Main Domain Configuration

So without further ado, we're gonna dive right in and get you started setting up your very first web server!

nginx Web Server – Because I won’t be covering Apache.

Many of you may have heard of the Apache web server.  This is because it powers more websites than any other web server in the world and has been around since about 1995.  I won't lie, it's a great platform with loads of modules and history.  But to this I say: Who cares?  Certainly not us because we're going with an alternative called nginx (pronounced "Engine X") and there's a simple reason why: We're in this for performance and nginx is an open source web server written to address some of the performance and scalability issues associated with Apache.  So why wouldn't we do this!?

Alright, first things first: Let's install nginx!  Go back to your command line as your (not root) user and type the following:

mike@webofmike:~$ sudo apt-get -y install nginx-extras

This installs the nginx package plus some nice-to-have extras that I like to use and because you're here following my tutorial... you're going to use it too! But guess what my friends... that's it! You have an absolutely basic bare-bones nginx web server running on your machine.  Don't believe me? Go back to that e-mail or your Digital Ocean dashboard and get the IPV4 address that looks something like this 103.236.85.188.  Copy that into your web browser (I use chrome because that's what the cool kids are doing these days) and past the address into your address bar and hit enter.  You should see a big fat title that says: Welcome to nginx!

Tada!  That's all for the basic install folks!  Now, onto some general (but important!) configuration prior to defining your website.

Installing PHP

If you didn't already know it, WordPress is written in the PHP scripting language, most specifically, PHP5.  If you'd like to read more about PHP, check out the php.net website as I will not be going into detail about what this is.  Knowing that WordPress is written in PHP5, we need to first enable nginx to serve up PHP!  So let's get started on that.

Installing PHP-FPM:

In order to use PHP5 with nginx, there are a variety of methods.  I, and many others, would say php-fpm (PHP FastCGI Process Manager) is one of the best methods of doing this.  Nice low overhead and it's fast. So let's get started.  Go back to your terminal and type:

mike@webofmike:~# sudo apt-get -y install php5-fpm

This will get very basic and unoptimized php5 and php-fpm installed. So let's tune it up a little bit to take advantage of the speed potential.  We're going to have to edit the configuration files a little bit, so go back to your command line and type the following:

mike@webofmike:~# sudo nano /etc/php5/fpm/pool.d/www.conf

This will open up the PHP-FPM pool configuration file.  The pool is going to be a collection of "listeners" waiting to run WordPress (and other) PHP code that gets sent to it by nginx.  Scroll up or down in the file (Page Up / Page Down) to find the following lines and make sure they match.  If they don't, change them!  When you're done, use Ctrl+O, check the file name, press Enter, and then Ctrl+X to close.

...
listen = /var/run/php5-fpm.sock
...
listen.allowed_clients = 127.0.0.1
...
pm = ondemand
...
pm.max_children = 10
...
pm.start_servers = 2
...
pm.min_spare_servers = 2
...
pm.max_spare_servers = 10
...
pm.max_requests = 100
...

These values will allow your PHP-FPM instances to run quickly, on-demand, and securely!

Installing PHP Modules

Just about the only "extra" you absolutely bare-bones need for php is the MySQL module; however, we'll cover this particular module later on.  What I'd recommend is typing the following into your console:

mike@webofmike:~# sudo apt-get install php5-cli php5-dev php5-xmlrpc php5-curl php5-gd php-apc php-pear php5-imap php5-mcrypt php5-pspell

This will ensure you get the a good foundation of php modules for future use.  Trust me, you'll want them.  Now that this is done, type the following to restart php-fpm and let's move on!

mike@webofmike:~# sudo service php-fpm restart

Basic nginx Configuration

Here's where we really get to get down into the weeds.  Lucky you.  We're going to tune this monster to be a lean and mean blog-serving machine.  The first thing we're going to do is put together some common files for all of your Wordpress hosting needs.  Firs things first, let's create a standard file to include in any websites (WordPress or other!).  Let's go back to your command line and type the following to open a new file in the /etc/nginx/global/ directory.

mike@webofmike:~# sudo mkdir -p /etc/nginx/global
mike@webofmike:~# sudo nano /etc/nginx/global/common.conf

This will do two things, create the /etc/nginx/global directory and open nano for editing our common.conf configuration file.  Type (or copy and paste this) into nano.  You can right click to paste in Terminal or PuTTY.

# Global configuration file.
# ESSENTIAL : Configure Nginx Listening Port
listen 127.0.0.1:8080;
listen [::1]:8080;

index index.php index.html index.htm;

# ESSENTIAL : no favicon logs
location = /favicon.ico {
    log_not_found off;
    access_log off;
}

# ESSENTIAL : Handle your 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/www;
        }

# 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;
}

# 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 php5-fpm;
 fastcgi_keep_conn on;
 fastcgi_index index.php;
 include fastcgi_params;
}

Once this is copied into nano, press Ctrl+O, double-check the filename in nano and hit Enter. This will save our file. Then press Ctrl+X to exit nano.  This file is done!   To break this down, this configuration file will be included later on when you define your website for nginx.  This does some minor performance tweaks and security checks.  Most importantly, this will set up PHP to run the files that make up WordPress.

Next, we'll want to setup a basic WordPress configuration file for nginx.  This will set up nginx to handle the URL structure and permalinks so search engines can find you better once we've gone through some basic optimization configurations later in the tutorial.  Go to your terminal and type the following to edit your WordPress configuration file:

mike@webofmike:~# sudo nano /etc/nginx/global/wordpress.conf

Paste the following into your configuration file:

# SECURITY : Deny all attempts to access PHP Files in the uploads directory
location ~* /(?:uploads|files)/.*\.php$ {
    deny all;
}

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

# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;

# 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;

Then follow up with our save and close maneuver by pressing Ctrl+O, then Enter, then Ctrl+X. This will save the file and exit nano.

Finally, we're going to setup the core nginx configuration to recognize your website.  Go to your terminal and type:

mike@webofmike:~# sudo rm /etc/nginx/nginx.conf
mike@webofmike:~# sudo nano /etc/nginx/nginx.conf

This will remove the default configuration and we'll replace it with the following text.  Make sure you paste this exactly:

user www-data;
worker_processes 1;
pid /run/nginx.pid;

events {
        worker_connections 768;
        multi_accept on;
        use epoll;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        server_tokens on;

        server_names_hash_bucket_size 64;
        server_name_in_redirect on;

        client_max_body_size 20m;

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

        ##
        # Logging Settings
        ##

        access_log off;
        error_log /var/log/nginx/error.log crit;

        ##
        # Gzip Settings
        ##

        gzip on;
        gzip_disable "msie6";

        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
        gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

         # PHP5-FPM Upstream
        upstream php5-fpm {
                keepalive 8;
                server unix:/var/run/php5-fpm.sock;
        }

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}

Again, follow up with our save and close maneuver by pressing Ctrl+O, then Enter, then Ctrl+X.  Save the core nginx file.

Now, go back to your terminal to apply our changes.  Go ahead and type:

mike@webofmike:~# sudo service nginx restart

Configuring Your Website on Nginx

Now that we've applied our configuration and great start to optimizing our web server, we're going to use our basic configuration and extend it to run your website.

First, we'll go ahead and assume you will replace any text in this section labelled "yourwebsite.com" with your actual domain name.  This is important as your website will not be recognized if you don't do this.

So, let's go back to your command line and type the following (don't forget to replace yourwebsite.com with your website name!):

mike@webofmike:~# sudo nano /etc/nginx/sites-enabled/yourwebsite.com

Then paste the following code into nano (again don't forget to replace yourwebsite.com with your website name!):

server {
        server_name yourwebsite.com www.yourwebsite.com;
        root /var/www/yourwebsite.com/;
        access_log off;
        error_log /var/log/nginx-yourwebsite.com.log crit;

        include global/common.conf;
        include global/wordpress.conf;

        # Sitemap XML Files for SEO
        rewrite ^/sitemap_index\.xml$ /index.php?sitemap=1 last;
        rewrite ^/([^/]+?)-sitemap([0-9]+)?\.xml$ /index.php?sitemap=$1&sitemap$
}

Follow up with Ctrl+X, Enter, Ctrl+O to save and exit nano.  Then reload your nginx configuration by typing the following:

mike@webofmike:~# sudo nginx -s reload

This will reload your web server's configuration and then we're onto the next section on Setting Up CloudFlare as Your DNS Provider.

Mike Moore

Published 9 years ago