WordPress, Nginx and PHP-FPM

X @urre
This is a post written originally back in 2012, a lot of things is out of date.

This is my notes for setting up a VPS optimized for WordPress, with Nginx and PHP5-FPM. I’m setting up MySQL, W3 Total Cache, Git and a few other things. I assume that you already have a VPS with has an allocated a ip adress. Also, you must have a domain.

Nginx?

NGINX is the world’s most popular open source web server for high traffic sites, powering over 100 million properties. Nginx works differently than Apache, mainly with regard to how it handles threads. Nginx has grown in popularity since its release due to its light-weight resource utilization and its ability to scale easily on minimal hardware. Nginx excels at serving static content quickly and is designed to pass dynamic requests off to other software that is better suited for those purposes.

Read more

Configure and update your VPS

sudo apt-get install python-software-properties
sudo apt-get update
sudo apt-get upgrade

Install the Nano editor (or just use Vim)

sudo apt-get install nano

Configure hostname

nano /etc/hosts

127.0.0.1 localhost.localdomain localhost
127.0.0.1 myserver

hostname = the name on your VPS

Install Nginx, PHP and PHP5-FPM

sudo apt-get install nginx
sudo apt-get install php5-cli php5-common php5-mysql php5-imagick php5-gd php5-dev
sudo apt-get install php5-fpm php5-cgi php-pear php5-memcache php-apc

Start PHP-FPM

sudo service php5-fpm start
cd /etc/nginx/sites-enabled
sudo ln -s ../sites-available/default default

Start Nginx

sudo service nginx start

You can now visit your domain mywebsite.com and see “Welcome to Nginx”

sudo rm default
sudo service nginx stop
sudo service php5-fpm stop

Remove the symlink igen and stop Nginx

Configure Nginx

cd /etc/nginx

Edit nginx.conf

nano nginx.conf

Add this (gist)

Change worker_processes and worker_connections to match your server. If your VPS has got 6 CPU cores, adjust worker_processes to 6. worker_connections till 6 * 1024 = 6144. Find out how many CPU cores by running cat /proc/cpuinfo

Go to /sites-avaliable

cd sites-available

Create a file called mywebsite.com

touch mywebsite.com
nano mywebsite.com

Add this (gist)

Create the folder global inside the nginx folder

cd /etc/nginx
sudo mkdir global
cd global

Create the file restrictions.conf

touch restrictions.conf
nano restrictions.conf

Add this: (gist)

Create the file php5-fpm.conf inside the global directory

touch php5-fpm.conf
nano php5-fpm.conf

Add this (gist)

Set up your site

cd /etc/nginx/sites-enabled
sudo ln -s ../sites-available/mywebsite.com.se mywebsite.com

Go to the www folder

cd /var/www

Create a group

sudo groupadd web

Add admin rights

sudo usermod -a -G web YOURUSER

Add the group

sudo chgrp web /var/www

Make the www directory writable

sudo chmod -R 775 /var/www

Assign all files to the group

sudo chmod g+s /var/www

Create a folder for your website

mkdir mywebsite.com
cd mywebsite.com

Create a index.php and try out the configuration

touch index.php
nano index.php

Add phpinfo(); and check so everything works

Start Nginx

sudo service nginx start

Start PHP-FPM

sudo service php5-fpm start

Great success!

Secure SSH

Create a user

adduser --home /home/name name

Add user as sudoer

visudo

Add

name ALL=(ALL) ALL

Turn off root login

nano /etc/ssh/sshd_config

Add

PermitRootLogin no
PasswordAuthentication no

Install MySQL

sudo apt-get install mysql-server
sudo apt-get install php5-mysql

Create database

mysqladmin -u root -p create databasnamn

Secure MySQL

mysql_secure_installation

Log in

mysql -u root -p

Create user

CREATE USER 'anvnamn'@'localhost' IDENTIFIED BY 'c0MpLiCaTeDp@55w0rd';

Grant access

GRANT ALL ON *.* TO 'anvnamn'@'localhost';

Logout from the MySQL shell

exit

Manage the database

I prefer to use Sequel Pro . It is a fast, easy-to-use Mac database management application for working with MySQL databases. Simple and looks great. Sequel Pro

Install WordPress

This is outdated. You should use WP-CLI instead.

Istall wget

sudo bash
apt-get update
apt-get -f install
apt-get install wget

Download WordPress

wget http://sv.wordpress.org/wordpress-4.2.2-sv_SE.tar.gz
tar xfz wordpress-4.1-sv_SE.tar.gz
mv wordpress/* ./
rmdir ./wordpress/
rm -f wordpress-3.9.1-sv_SE.tar.gz
mv wp-config-sample.php wp-config.php

Edit wp-config add your credentials and settings

nano wp-config.php

Or use my little bash script wp-installer

Install cURL

sudo apt-get install curl

Install WP-CLI

WP-CLI is a set of command-line tools for managing WordPress installations. You can update plugins, set up multisite installs and much more, without using a web browser.

First, download wp-cli.phar using wget or curl. For example

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar

Then, check if it works:

php wp-cli.phar --info

To be able to type just wp, instead of php wp-cli.phar, you need to make the file executable and move it to somewhere in your PATH. For example:

chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

No try wp --info

Bonus: Add Tab completions.

Setup SSH-keys

We need to connect to the server without using password every time:

mkdir ~/.ssh
chmod 700 ~/.ssh
ssh-keygen -t rsa

Own your .ssh folder (for user with rootaccess)

cd ~
sudo chown name .ssh

Copy keys to the server:

cat ~/.ssh/id_rsa.pub | ssh user@dindoman.se 'cat - >> ~/.ssh/authorized_keys'

Set correct access

chmod 600 ~/.ssh/authorized_keys && chmod 700 ~/.ssh/

Install Git

apt-get install git-core

Add the git user

adduser git
su git
cd /home/git
mkdir .ssh
chmod 700 .ssh
cd .ssh
touch authorized_keys (Lägg in samma key som root-användaren)

Test

ssh git@mywebsite.com.se

Add remote git repo

git remote add origin git@mywebsite.com.se/var/www/mywebsite.com

Solve the git objects access rights

cd repository.git
sudo chmod -R g+ws *
sudo chgrp -R mygroup *
git config core.sharedRepository true
sudo chown -R git:git .git/

Set git user as sudoer

visudo
git ALL=(ALL) ALL

W3 Total Cache

touch /etc/nginx/sites-available/mywebsite.com

Add

include global/wordpress-w3-total-cache.conf;

Create the w3 settings file

touch /etc/nginx/global/wordpress-w3-total-cache.conf

nano /etc/nginx/global/wordpress-w3-total-cache.conf

Add this (gist)

Also create nginx.conf inside /var/ww/mywebsite.com

touch nginx.conf
nano nginx.conf

Add: (gist)

Change allowed maximum file size

nano /etc/nginx/sites-available/default

Add for example:

client_max_body_size 30M;

Edit php.ini

nano /etc/php5/fpm/php.ini

Under File Uploads, change to:

upload_max_filesize = 30M;

Reload PHP-FPM and Nginx

service php5-fpm reload
service nginx reload

Read more

Add correct MIME-type for SVG (.svg)

Edit /etc/nginx/mime.types

nano/etc/nginx/mime.types
image/svg+xml svg svgz;

Add correct mime-types for webfonts

if you use webfonts, Nginx can need a helping hand serving the correct mime-types, instead of just the default application/octet-stream. Edit /etc/nginx/mime.types

application/vnd.ms-fontobject eot;
application/x-font-ttfttf;
font/opentype ott;
application/font-woff woff;

Support more file formats

Allow .eps files to be uploaded in wp-admin

add_filter('upload_mimes', 'website_upload_mimes');

function website_upload_mimes ( $existing_mimes=array() ) {

// Add *.EPS files to Media upload
$existing_mimes['eps'] = 'application/postscript';

return $existing_mimes;
}

First 5 minutes on a server

Update. If you use Ubuntu 12 och PHP 5.4+, check out:

Fix locale issues

locale-gen en_US en_US.UTF-8 hu_HU hu_HU.UTF-8
dpkg-reconfigure locales