LEMP Stack on CentOS 6

Home » Computer Articles » LEMP Stack on CentOS 6
April 29, 2015 Computer Articles, Linux No Comments

 

At the very least, you should have a basic linux installation. This how-to assumes you have set up a CentOS 6 x86_64 VPS with 1GB RAM, but it should be applicable to most setups with minimal tweaks. All the commands and changes below should be done as the root user.

 

Before continuing, make sure that everything is up to date.

# yum update

Enable and configure third party repositories

You will need to enable some third party repositories--namely, the EPEL (Extra Packages for Enterprise Linux) repository and the Remi repository. The EPEL repo will let you install nginx, while the remi repo provides you with PHP version 5.5.

Install the 2 repositories:

# rpm --import https://fedoraproject.org/static/0608B895.txt

# rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

# rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi

# rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

Edit the epel.repo file, add priorities entry, and make sure to set enabled=1 for the mail EPEL repository.

# vi /etc/yum.repos.d/epel.repo

Your /etc/yum.repos.d/epel.repo file should look something like this:

[epel]
name=Extra Packages for Enterprise Linux 6 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6

[epel-debuginfo]
name=Extra Packages for Enterprise Linux 6 - $basearch - Debug
#baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
gpgcheck=1

[epel-source]
name=Extra Packages for Enterprise Linux 6 - $basearch - Source
#baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6
gpgcheck=1

Edit remi.repo file, add a priorities entry, and make sure to set enabled=1 for the remi and remi-php55 repositories.

# vi /etc/yum.repos.d/remi.repo

Here is what /etc/yum.repos.d/remi.repo should look like:

[remi]
name=Les RPM de remi pour Enterprise Linux 6 - $basearch
#baseurl=http://rpms.famillecollet.com/enterprise/6/remi/$basearch/
mirrorlist=http://rpms.famillecollet.com/enterprise/6/remi/mirror
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi

[remi-php55]
name=Les RPM de remi de PHP 5.5 pour Enterprise Linux 6 - $basearch
#baseurl=http://rpms.famillecollet.com/enterprise/6/php55/$basearch/
mirrorlist=http://rpms.famillecollet.com/enterprise/6/php55/mirror
# WARNING: If you enable this repository, you must also enable "remi"
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi

[remi-test]
name=Les RPM de remi en test pour Enterprise Linux 6 - $basearch
#baseurl=http://rpms.famillecollet.com/enterprise/6/test/$basearch/
mirrorlist=http://rpms.famillecollet.com/enterprise/6/test/mirror
# WARNING: If you enable this repository, you must also enable "remi"
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi

[remi-debuginfo]
name=Les RPM de remi pour Enterprise Linux 6 - $basearch - debuginfo
baseurl=http://rpms.famillecollet.com/enterprise/6/debug-remi/$basearch/
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi

[remi-php55-debuginfo]
name=Les RPM de remi de PHP 5.5 pour Enterprise Linux 6 - $basearch - debuginfo
baseurl=http://rpms.famillecollet.com/enterprise/6/debug-php55/$basearch/
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi

[remi-test-debuginfo]
name=Les RPM de remi en test pour Enterprise Linux 6 - $basearch - debuginfo
baseurl=http://rpms.famillecollet.com/enterprise/6/debug-test/$basearch/
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi

Run yum update again.

# yum update

Install Nginx, start the service, and enable on boot

Now, we're ready to install nginx from the EPEL repository:

# yum install nginx

Start the Nginx service:

# service nginx start

Setup Nginx to start at boot:

# chkconfig nginx on

Note that Nginx's default web root directory on CentOS 6 is /usr/share/nginx/html. This directory may be different depending on what linux distribution you are using.

 

 

Configure Nginx

Edit /etc/nginx/nginx.conf for some performance adjustments.

# vi /etc/nginx/nginx.conf

Here is what your nginx.conf file should look like:

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user              nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log;

pid        /var/run/nginx.pid;

events {
	worker_connections  1024;
}

worker_rlimit_nofile    2048;

http {
	server_names_hash_bucket_size 64;
	client_max_body_size 20M;
	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;
	keepalive_timeout  2;

	##
	# Gzip Settings
	##

	gzip on;
	gzip_disable "msie6";

	gzip_comp_level 6;
	gzip_min_length  1100;
	gzip_buffers 16 8k;
	gzip_proxied any;
	gzip_types       text/plain application/xml text/css text/js text/xml application/x-javascript text/javascript application/json application/xml+rss;

	# Set real ip from CloudFlare
	set_real_ip_from   204.93.240.0/24;
	set_real_ip_from   204.93.177.0/24;
	set_real_ip_from   199.27.128.0/21;
	set_real_ip_from   173.245.48.0/20;
	set_real_ip_from   103.21.244.0/22;
	set_real_ip_from   103.22.200.0/22;
	set_real_ip_from   103.31.4.0/22;
	set_real_ip_from   141.101.64.0/18;
	set_real_ip_from   108.162.192.0/18;
	set_real_ip_from   190.93.240.0/20;
	set_real_ip_from   188.114.96.0/20;
	set_real_ip_from   197.234.240.0/22;
	set_real_ip_from   198.41.128.0/17;
	set_real_ip_from   162.158.0.0/15;
	real_ip_header     CF-Connecting-IP;

	# Open_file_cache for metadata, can help with performance, might only notice on high traffic website.
	open_file_cache          max=10000 inactive=10m;
	open_file_cache_valid    20m;
	open_file_cache_min_uses 1;
	open_file_cache_errors   on;

	# Load config files from the /etc/nginx/conf.d directory
	# The default server is in conf.d/default.conf
	include /etc/nginx/conf.d/*.conf;
}

Now edit the virtual hosting configuration file, /etc/nginx/conf.d/domainname.conf. (You will need to change domainname to the domain name your own domain name.)

# vi /etc/nginx/conf.d/domainname.conf

Here is a sample domainname.conf file:

#
# A virtual host using mix of IP-, name-, and port-based configuration
#

server {
	server_name www.domainname.com domainname,.com;
	root /usr/share/nginx/html/domainname;
	access_log off;
	#access_log /usr/share/nginx/html/log/domainname.local-access.log;
	error_log /usr/share/nginx/html/log/domainname.local-error.log crit;

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

# Do not allow access to files giving away your WordPress version
location ~ /(\.|wp-config.php|readme.html|licence.txt) {
	return 404;
}

# Don't log robots.txt requests

location = /robots.txt {
	allow all;
	log_not_found off;
	access_log off;
}

# Rewrite for versioned CSS+JS via filemtime
location ~* ^.+\.(css|js)$ {
	rewrite ^(.+)\.(\d+)\.(css|js)$ $1.$3 last;
	expires 31536000s;
	access_log off;
	log_not_found off;
}

# Aggressive caching for static files
# If you alter static files often, please use
# add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
location ~* \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|ogv|otf|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|t?gz|tif|tiff|ttf|wav|webm|wma|woff|wri|xla|xls|xlsx|xlt|xlw|zip)$ {
	expires 31536000s;
	access_log off;
	log_not_found off;
}

location ~ \.php$ {
	# include /etc/nginx/fastcgi_params;
	include /etc/nginx/fastcgi.conf;
	fastcgi_pass unix:/tmp/php5-fpm.sock;
	fastcgi_index index.php;
	fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

}

Create the Log directory.

# mkdir /usr/share/nginx/html/log

You should now have a working Nginx configuration.

 

 

Install MySQL, start the service, and enable on boot

Install the MySQL client tools and the server.

# yum install mysql mysql-server

Start the MySQL service

# service mysqld start

Load the service at boot

# chkconfig mysqld on

Secure MySQL

Run mysql_secure_installation to harden the MySQL installation.

# /usr/bin/mysql_secure_installation
Set a root password? Y
Remove anonymous user? Y
Disallow root login remotely? Y
Remove test database and access to it? Y
Reload privilege tables now? Y
Configure MySQL

Configuration file for MySQL.

# vi /etc/my.cnf
#
# This group is read both both by the client and the server
# use it for options that affect everything
#
[client-server]

[mysqld] 
datadir=/var/lib/mysql 
socket=/var/lib/mysql/mysql.sock 
user=mysql 
symbolic-links=0 
query_cache_size = 2M 
thread_cache_size = 4 
max_connections = 40

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

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

You should now have a working MySQL configuration. In step 4, we show you how to set up php-fpm on CentOS 6.

For tuning MySQL, we recommend you download Matthew Montgomery's MySQL performance tuning primer script.

 

 

Install Php-fpm, start the service, and enable on boot

# yum install php-fpm php-cli php-mysql php-gd php-pear php-xml php-xmlrpc php-magickwand php-magpierss php-mbstring php-mcrypt php-tidy php-opcache

Set up Php-fpm to start at boot.

# chkconfig php-fpm on

Start the Php-fpm service.

# service php-fpm start

Configure Php-fpm

Edit # vi /etc/php.ini (Don't copy and paste this into the file, look for each parameter and change it.)

cgi.fix_pathinfo=0
memory_limit = 128M
expose_php = Off
date.timezone = US/Eastern (Set to your timezone)

Edit # vi /etc/php-fpm.conf (Don't copy and paste this into the file, look for each parameter and change it.)

emergency_restart_threshold = 10
emergency_restart_interval = 1m
process_control_timeout = 10s

Edit the vi /etc/php-fpm.d/www.conf and make changes below. (Don't copy and paste this into the file, look for each parameter and change it.)

;listen = 127.0.0.1:9000
listen = /tmp/php5-fpm.sock 
user = nginx 
group = nginx 
pm.max_children = 8
pm.start_servers = 3 
pm.min_spare_servers = 2 
pm.max_spare_servers = 6 
pm.max_requests = 200 
pm.status_path = /status 
request_terminate_timeout = 120s 
request_slowlog_timeout = 5s 
rlimit_files = 131072 
rlimit_core = unlimited 
catch_workers_output = yes 
env[HOSTNAME] = $HOSTNAME 
env[TMP] = /tmp 
env[TMPDIR] = /tmp 
env[TEMP] = /tmp

Restart the Php-fpm service

# service php-fpm restart

Configure vhost in nginx

Edit the vhost in default.conf

# vi /etc/nginx/conf.d/default.conf and uncomment these entries. The fastcgi_param SCRIPT_FILENAME needs to be changed.

    location ~ \.php$ {
        root           html;
        fastcgi_pass  unix:/tmp/php5-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    location ~ /\.ht {
        deny  all;
    }

Restart the Nginx service

# service nginx restart

Test Php-fpm

Create a phpinfo.php and make sure php is working properly.

# vi /usr/share/nginx/html/phpinfo.php

<?php 
// Show all information, defaults to INFO_ALL 
phpinfo(); 
?>

Go to a web browser and see if the phpinfo page loads proper. If it does, great!

 

 

Optional: Improve Php-fpm performance with opcache

Let's enable opcache for better performance. You may not want to enable this is you are making a lot of PHP script changes.

# vi /etc/php.d/opcache.ini (Don't copy and paste this into the file, look for each parameter and change it.)

opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1 
opcache.save_comments=0

Restart Php-fpm service.

# service php-fpm restart

If for some reason you can't connect to your new webserver, check your iptables firewall rules and make sure to add port 80 and 443.

Now, you can install WordPress or any other CMS that needs this type of setup.

Share This:

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.