Steps to Build WordPress Environment with Nginx + php-fpm + MySQL on CentOS 6.3 (Sakura VPS)

Tadashi Shigeoka ·  Sun, September 15, 2013

I’ll introduce the steps to build a WordPress environment with Nginx + php-fpm + MySQL on Sakura VPS - CentOS6.3.

WordPress | ワードプレス

Installing Nginx

Register Nginx Repository

# vim /etc/yum.repos.d/nginx.repo

[nginx]
name=nginx
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=0

Check Available Nginx Versions

# yum info --enablerepo=nginx nginx

Install Nginx

# yum -y install --enablerepo=nginx nginx

Verify Nginx Installation

# nginx -v
nginx version: nginx/1.4.2

Nginx Configuration

# vim /etc/nginx/nginx.conf
user  nginx;
worker_processes  2;

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
    gzip  on;
    gzip_http_version 1.0;
    gzip_vary         on;
    gzip_comp_level   6;
    gzip_types        text/xml text/css application/xhtml+xml application/xml application/rss+xml application/atom_xml application/x-javascript application/x-httpd-php;
    gzip_disable      "MSIE [1-6]\\.";

    # reverse proxy
    proxy_cache_path  /var/cache/nginx levels=1:2 keys_zone=czone:4m max_size=50m inactive=120m;
    proxy_temp_path   /var/tmp/nginx;
    proxy_cache_key   "$scheme://$host$request_uri";
    proxy_set_header  Host               $host;
    proxy_set_header  X-Real-IP          $remote_addr;
    proxy_set_header  X-Forwarded-Host   $host;
    proxy_set_header  X-Forwarded-Server $host;
    proxy_set_header  X-Forwarded-For    $proxy_add_x_forwarded_for;

    upstream backend {
        ip_hash;
        server 127.0.0.1:8080;
    }

    include /etc/nginx/conf.d/*.conf;
}
# vim /etc/nginx/conf.d/virtual.conf
server {
 
    listen      80;
    server_name example.com;
    root        /var/www/vhosts/example.com/www;
    access_log  /var/log/nginx/example.com/access.log   main;
    error_log   /var/log/nginx/example.com/error.log;
    client_max_body_size 36M;
 
    location /wp-admin { proxy_pass http://backend; }
    location ~ .*\\.php { proxy_pass http://backend; }
    location / {
        set $mobile "";
        if ($http_user_agent ~* '(DoCoMo|J-PHONE|Vodafone|MOT-|UP\\.Browser|DDIPOCKET|ASTEL|PDXGW|Palmscape|Xiino|sharp pda browser|Windows CE|L-mode|WILLCOM|SoftBank|Semulator|Vemulator|J-EMULATOR|emobile|mixi-mobile-converter)') {
            set $mobile "@ktai";
        }
        if ($http_user_agent ~* '(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry)') {
            set $mobile "@mobile";
        }
        if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) {
            set $do_not_cache 1;
        }
 
        proxy_no_cache     $do_not_cache;
        proxy_cache_bypass $do_not_cache;
        proxy_cache czone;
        proxy_cache_key "$scheme://$host$request_uri$is_args$args$mobile";
        proxy_cache_valid  200 301 302 60m;
        proxy_cache_valid  404 5m;
        proxy_cache_use_stale  error timeout invalid_header updating
                               http_500 http_502 http_503 http_504;
        proxy_pass http://backend;
        proxy_redirect http://example.com:8080/ /;
    }
}
 
server {
 
    listen      8080;
    server_name example.com;
    root        /var/www/vhosts/example.com/www;
    access_log  /var/log/nginx/example.com/access.log   main;
    error_log   /var/log/nginx/example.com/error.log;
    client_max_body_size 36M;
 
    location / {
        index  index.php index.html index.htm;
        # static files
        if (-f $request_filename) {
            expires 14d;
            break;
        }
        # request to index.php
        if (!-e $request_filename) {
            rewrite ^(.+)$  /index.php?q=$1 last;
        }
    }
 
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    location ~ \\.php$ {
        include        fastcgi_params;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME  /var/www/vhosts/example.com/www/$fastcgi_script_name;
    }
}

Create log directory.

mkdir /var/log/nginx/example.com

After editing the conf file, perform syntax check.

# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Add to firewall settings to open Port8080.

# vim /etc/sysconfig/iptables

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 8080  -j ACCEPT

Configure Nginx Auto-start

chkconfig nginx on

Installing MySQL

Next, install MySQL.

Check Available MySQL Versions

# yum info mysql-server

Install MySQL Server

Note that the yum package is mysql-server, not mysql.

# yum -y install --enablerepo=remi mysql-server

Modify MySQL Configuration File

# cp /etc/my.cnf /etc/my.cnf.default
# vim /etc/my.cnf

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

# Settings user and group are ignored when systemd is used (fedora >= 15).
# If you need to run mysqld under different user or group, 
# customize your systemd unit file for mysqld according to the
# instructions in http://fedoraproject.org/wiki/Systemd
user=mysql

datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks
#symbolic-links=0

# Semisynchronous Replication
# http://dev.mysql.com/doc/refman/5.5/en/replication-semisync.html
# uncomment next line on MASTER
;plugin-load=rpl_semi_sync_master=semisync_master.so
# uncomment next line on SLAVE
;plugin-load=rpl_semi_sync_slave=semisync_slave.so

# Others options for Semisynchronous Replication
;rpl_semi_sync_master_enabled=1
;rpl_semi_sync_master_timeout=10
;rpl_semi_sync_slave_enabled=1

# http://dev.mysql.com/doc/refman/5.5/en/performance-schema.html
;performance_schema

character-set-server=utf8

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid


# Add from here

[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

[mysqldump]
default-character-set=utf8

Start MySQL & Configure Auto-start

service mysqld start
chkconfig mysqld on

Set MySQL Password

# mysqladmin -u root password
# mysqladmin -u root -h hostname password

PHP Installation and Initial Configuration

Finally, install PHP and perform initial configuration.

Check Available PHP Versions

# yum info php php-mbstring php-mysql php-pear php-gd php-pecl-apc php-fpm

Install PHP

# yum -y install php php-mbstring php-mysql php-pear php-gd php-pecl-apc php-fpm

Verify PHP installation.

# php -v
PHP 5.3.15 (cli) (built: Jul 20 2012 12:50:06) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies

Modify php.ini Configuration

# vim /etc/php.ini
expose_php = Off

error_log = /var/log/php_errors.log

mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.http_input = pass
mbstring.http_output = pass
mbstring.encoding_translation = Off

[Date]
date.timezone = Asia/Tokyo

Create Log File

# touch /var/log/php_error.log
# chmod 757 /var/log/php_error.log

APC Configuration

mkdir -p /var/www/vhosts/example.com
cp /usr/share/doc/php-pecl-apc-3.1.10/apc.php /var/www/vhosts/example.com/
vim /var/www/vhosts/example.com/apc.php 

defaults('ADMIN_USERNAME','user');
defaults('ADMIN_PASSWORD','password');

Verify Fast CGI Installation

Verify php-fpm installation.

# php-fpm -v
PHP 5.3.15 (fpm-fcgi) (built: Jul 20 2012 12:52:37)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies

Configure php-fpm

# vim /etc/php-fpm.d/www.conf
user = nginx
group = nginx

pm = dynamic
pm.max_children =  30
pm.start_servers = 11
pm.min_spare_servers = 10
pm.max_spare_servers = 15
pm.max_requests = 500

php_admin_flag[expose_php] = off

Start php-fpm.

service php-fpm start

Enable php-fpm auto-start.

chkconfig php-fpm on
# netstat -ltn | grep -E '(80|9000)'
tcp        0      0 127.0.0.1:9000              0.0.0.0:*                   LISTEN      
tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN

That’s all.

Reference Information

This configuration might be better:

That’s all from the Gemba.