Nginx + PHP-FPM + APC + MySql + WordPress on Debian 6

Nginx + PHP-FPM + MySql + APC + WordPress

Add the following lines in /etc/apt/sources.list

deb http://packages.dotdeb.org stable all
deb-src http://packages.dotdeb.org stable all

Apply GnuPG key

wget http://www.dotdeb.org/dotdeb.gpg
cat dotdeb.gpg | apt-key add -

Update Sources

apt-get update

Install PHP and Nginx

apt-get install php-apc php-auth php-net-smtp php-net-socket php-pear php5 php5-curl php5-gd php5-mcrypt php5-mysql php5-fpm nginx

Install MySql

apt-get install make
apt-get install mysql-server mysql-client

The mysql-client is a CLI client which you can use to access local and remote mysql servers to administer them. And the server is well, the server part of it. You definitely want that one, but you also probably to have the client installed for emergencies or general maintenance.

Install WordPress


mkdir /var/www
mkdir /var/www/sitename.com
mkdir /var/www/sitename.com/public_html
cd /var/www/sitename.com/public_html/
wget http://wordpress.org/latest.tar.gz
tar -zxvf latest.tar.gz
mv wordpress/* /var/www/sitename.com/public_html/
rmdir wordpress
chown -R www-data:www-data /var/www/sitename.com/public_html

/etc/nginx/nginx.conf

user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events {
use epoll;
worker_connections 1024;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
error_log /var/log/nginx/error.log;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 3;
server_tokens off;
access_log off;
client_max_body_size 32m;
# client_body_timeout 60;
# client_header_timeout 60;
# send_timeout 60;
# reset_timedout_connection on;
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_static on;
gzip_proxied any;
gzip_comp_level 9;
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;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

Vhost Configuration (/etc/nginx/sites-enabled/sitename.conf)
rm /etc/nginx/sites-enabled/default
nano /etc/nginx/sites-enabled/sitename

Add the following code to it.

server {
listen 80;
server_name sitename.com www.sitename.com;
root /var/www/sitename.com/public_html;
index index.php index.html;
include global/wordpress.conf;
}

mkdir /etc/nginx/global/
nano /etc/nginx/global/wordpress.conf

Drop the following content to it.

/etc/nginx/global/wordpress.conf

location = /favicon.ico {
log_not_found off;
}
location = /robots.txt {
allow all;
log_not_found off;
}
location ~ /. {
deny all;
access_log off;
log_not_found off;
}

/etc/php5/fpm/pool.d/www.conf

;listen = 127.0.0.1:9000
listen = /dev/shm/php-fastcgi.socket
php_flag[display_errors] = on
php_admin_value[error_log] = /var/log/fpm-php.www.log
php_admin_flag[log_errors] = on
php_admin_value[error_reporting] = 0
php_admin_value[memory_limit] = 128M
php_admin_value[date.timezone] = Asia/Calcutta

MySql Configuration: /etc/mysql/my.cnf

[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock

[mysqld]
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
language = /usr/share/mysql/english
skip-external-locking
bind-address = 127.0.0.1

thread_stack = 192K
myisam-recover = BACKUP

expire_logs_days = 10
max_binlog_size = 100M

bulk_insert_buffer_size = 8M
connect_timeout=10
interactive_timeout=50
join_buffer=1M
key_buffer=250M
max_allowed_packet=16M
max_connect_errors=10
max_connections=100
max_heap_table_size = 32M
myisam_sort_buffer_size=96M
query_cache_limit = 4M
query_cache_size = 250M
query_cache_type = 1
query_prealloc_size = 65K
query_alloc_block_size = 128K
read_buffer_size=1M
read_rnd_buffer_size=768K
record_buffer=1M
safe-show-database
skip-innodb
skip-locking
skip-networking
sort_buffer=1M
table_cache=4096
thread_cache_size=1024
thread_concurrency=8
tmp_table_size = 32M
wait_timeout=500

[mysqldump]
quick
max_allowed_packet = 16M

[mysql]
no-auto-rehash

[mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
nice = -5
open_files_limit = 8192

[isamchk]
key_buffer = 64M
sort_buffer = 64M
read_buffer = 16M
write_buffer = 16M

!includedir /etc/mysql/conf.d/

Configuration Files:

/var/www/sitename.com/public_html/
/etc/nginx/nginx.conf
/etc/mysql/my.cnf
/etc/php5/fpm/php.ini
/etc/php5/fpm/php-fpm.conf
/etc/php5/fpm/pool.d/www.conf
/etc/nginx/sites-enabled/sitename.conf

Create Database:

mysql -uroot -p
CREATE DATABASE sitename_main;
GRANT ALL PRIVILEGES ON sitename_main.* TO [email protected] IDENTIFIED BY 'password' WITH GRANT OPTION;

Modifications/ Optimizations
/etc/php5/fpm/php-fpm.conf
pm.max_children = 25
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 10
pm.max_requests = 500
request_terminate_timeout = 30s (optional but recommended)

Adding a New Domain/ Creating Vhost
rm /etc/nginx/sites-enabled/default
nano /etc/nginx/sites-available/www.sitename.com
Create a symlink for the new vhost:
ln -s /etc/nginx/sites-available/www.sitename.com /etc/nginx/sites-enabled/www.sitename.com

Managing Server:

/etc/init.d/nginx restart|status|start|stop
/etc/init.d/php5-fpm restart|status|start|stop
/etc/init.d/mysql restart|status|start|stop
User and Group =  www-data
Public Directory: /var/www/sitename.com/public_html

Useful Resources
http://blog.digitalstruct.com/2010/07/12/getting-started-with-nginx-and-php-fpm/
http://andreas-lehr.com/blog/archives/491-nginx-wordpress-php-fpm-on-debian-squeeze.html
http://www.betasix.net/build-nginx-php-fpm-apc-memcache-on-debian-64-bits/
http://senko.net/en/fast-wordpress-nginx-on-cheap-vps/
http://unrealexpectations.com/blog/2010/01/nginx-fastci-wordpress-no-input-file-specified/
http://codex.wordpress.org/Nginx
http://terra-byte.org/vps/set-up-vps/
http://unimaxlin.com/tag/nginx/

Join the Conversation

4 Comments

  1. Super break down man, you rock!

    One thing though, 403 forbidden permissions gone crazy on a domain.ext/wp-admin. Wonder where to look in a set-up on the root.

  2. HI,

    I followed all instructions but when trying to restart php5-fpm I get error: “Process Manager: php5-fpm failed!”
    What could be the problem?

    Also do we need to include anything in website.conf about php-fpm? Like :
    “location ~ .*.(php|php5)?$
    {

    fastcgi_pass unix:/tmp/php-cgi.sock;

    fastcgi_index index.php;

    include fcgi.conf;

    } ”
    How do I know it’s using php fpm?

    Thank you.

Leave a comment

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