Basic LEMP Stack Setup with PHP-FPM and Multiple Pools on CentOS 6

This tutorial will get you started with a basic LEMP stack. There are countless tweaks and customizations possible from this base configuration. This tutorial will walk you through setting up NGINX (pronounced engine X), MySQL and PHP-FPM. It is designed to be used in a shared environment or where you need to maintain user isolation. Each user will have their web root located in ~/username/www. Care has been taken to make sure this will work without the need to disable selinux. This was tested on CentOS 6.

Install the EPEL repository:

# yum install epel-release

Install NGINX:

# yum install nginx

Allow port 80 and 443 through iptables:

# iptables -I INPUT -p tcp --dport 80 -j ACCEPT
# iptables -I INPUT -p tcp --dport 443 -j ACCEPT
# service iptables save

If you’re using selinux, allow NGINX to access home directories:

# setsebool -P httpd_enable_homedirs true

Install MySQL:

# yum install mysql mysql-server

Start MySQL:

# service mysqld start

Configure MySQL:

# mysql_secure_installation

You will be asked the following:

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

Install PHP-FPM and any modules you might need:

# yum install php-fpm php-mysql php-pecl-apc php-cli php-pear php-gd php-xml php-mcrypt

Set up your system users and create a directory to hold their websites. We’ll start with two but you can add more later:

# useradd user1
# mkdir -p /home/user1/www; chown user1:user1 /home/user1/www; chmod +x /home/user1
# useradd user2
# mkdir -p /home/user2/www; chown user2:user2 /home/user2/www; chmod +x /home/user2

Create an NGINX virtual host configuration file for your domains. For this example, I will use user1.example.com and user2.example.com.

In /etc/nginx/conf.d, create two files.

/etc/nginx/conf.d/user1.conf

server {
    server_name  user1.example.com;
    root   /home/user1/www;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
        index  index.html index.htm index.php;
    }

    error_page  404              /404.html;
    location = /404.html {
        root   /usr/share/nginx/html;
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        if (!-f $document_root$fastcgi_script_name) {
                return 404;
        }

        fastcgi_pass unix:/var/run/php-fpm/user1.socket;
        fastcgi_index index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

/etc/nginx/conf.d/user2.conf

server {
    server_name  user2.example.com;
    root   /home/user2/www;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
        index  index.html index.htm index.php;
    }

    error_page  404              /404.html;
    location = /404.html {
        root   /usr/share/nginx/html;
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        if (!-f $document_root$fastcgi_script_name) {
                return 404;
        }

        fastcgi_pass unix:/var/run/php-fpm/user2.socket;
        fastcgi_index index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Now we need to set up our individual PHP-FPM pools.

/etc/php-fpm.d/user1.conf

[user1]
user = user1
group = user1
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

listen = /var/run/php-fpm/user1.socket
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

/etc/php-fpm.d/user2.conf

[user2]

user = user2
group = user2
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

listen = /var/run/php-fpm/user2.socket
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

Start the services:

# service nginx start
# service php-fpm start

Make sure our services start on boot:

# chkconfig nginx on
# chkconfig mysqld on
# chkconfig php-fpm on