how to setup Nginx, php-fpm

The well known, good'ol LAMP stack has slowly made place for a LEMP stack in many of my configurations. Enough articles have been written on why Apache or Nginx are better in certain situations, but I like the clean way of configuration that Nginx uses. (pronounced Engine X, hence the E in LEMP). So I generally use Nginx. I however never made an article about it, so here it is, long overdue.


Install Nginx

There are generally three options to install Nginx. First option is to use packages from the vendor, this however leaves you with a older version of Nginx. In the base repository's of Centos 7, Nginx is not included. So you need to install epel-release if you wish to go that route, at the time of writing, the available package is 1.10.2.This is the fastest option and large chance it will be updated more frequently then when you manually download and compile it. However if you wan't the newest features this is the better option. A third option is to use external repository's. All methods will result in a working setup.

1) Install Nginx using epel

(recommended method)

  • yum install epel-release
  • yum install nginx
2) Install Nginx from binary packages

Add /etc/yum.repos.d/nginx.repo

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

Then run yum install nginx

note this installs the mainline.

3) Install Nginx straight from source

Notice that there is a difference between mainline and stable version

  • cd /opt
  • mkdir nginx
  • cd nginx
  • # check the latest version on : http://nginx.org/en/download.html
  • wget http://nginx.org/download/nginx-1.11.10.tar.gz
  • # untar
  • tar xzvf nginx-1.11.10.tar.gz
  • # install dependencies
  • yum install gcc pcre-devel zlib-devel openssl-devel
  • # configure
  • ./configure --with-http_ssl_module
  • # make and make install
  • make
  • make install
4) Install Nginx from external repo

You could use webtatic to install nginx; This is similar to how I am going to install php-fpm :

  • rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
  • yum install nginx1w

for more detailed instructions, and dynamic modules, see there blogpost.

Install PHP

Installing PHP (lemP) is done using the php-fpm package (PHP FastCGI Process Manager) now sadly in the epel-release the version is super outdated at this writing : PHP 5.4. This version is no longer supported, on top of that, its pretty clear that PHP 7+ is faster and less resource hungry. Whatever version you chose, either should work. I use webtatic as repository and have found no issue's so far. For PHP 7.1 : (on Centos 7)

  • rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm

After that you are ready to install PHP :

  • yum install php71w-fpm php71w-opcache php71w-mysqlnd php71w-mcrypt php71w-gd php71w-xml
Configure php-fpm

After the installation its time to finetune our setup a bit. Let's start with php-fpm , we need to change /etc/php-fpm.d/www.conf

Change both the user and the group to nginx.

  • ; Start a new pool named 'www'.
  • [www]
  • ; Unix user/group of processes
  • ; Note: The user is mandatory. If the group is not set, the default user$
  • ; will be used.
  • ; RPM: apache Choosed to be able to access some dir as httpd
  • user = nginx
  • ; RPM: Keep a group allowed to write in log dir.
  • group = nginx
  • [...]

note : it's possible to let Nginx use a socket instead of loopback device. This is a bit faster, but I found that the headache is not really worth it.

Configure Nginx

Depending on the installation there is already a default server configuration. I tend to remove it and replace it with an empty file and create a file [name].conf in /etc/nginx/conf.d/

http server
  • server {
  • # listen to port 80
  • listen 80;
  • # server name or names
  • server_name svennd.be;
  • # the location of webroot
  • # I always use /var/www/html/*
  • # Nginx by default uses another structure
  • # but this made the transition from Apache allot easier!
  • root /var/www/html/svennd.be;
  • # in root location
  • location / {
  • # look for index.php/index.html/index.htm as "index file"
  • index index.php index.html index.htm;
  • # this is specifically for wordpress
  • # makes it possible to have url rewrites
  • try_files $uri $uri/ /index.php?$args;
  • }
  • # default error pages
  • # note that wp already catches most
  • error_page 404 /404.html;
  • error_page 500 502 503 504 /50x.html;
  • location = /50x.html {
  • root /usr/share/nginx/html;
  • }
  • # here we have to let nginx know what to do with these php files
  • # as html files are just send directly to the client
  • location ~ \.php$ {
  • # if the file is not there show a error : mynonexistingpage.php -> 404
  • try_files $uri =404;
  • # pass to the php-fpm server
  • fastcgi_pass 127.0.0.1:9000;
  • # also for fastcgi try index.php
  • fastcgi_index index.php;
  • # some tweaking
  • fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  • fastcgi_param SCRIPT_NAME $fastcgi_script_name;
  • fastcgi_buffer_size 128k;
  • fastcgi_buffers 256 16k;
  • fastcgi_busy_buffers_size 256k;
  • fastcgi_temp_file_write_size 256k;
  • include fastcgi_params;
  • }
  • }

Note that fastcgi_params are installed by php-fpm. In case its missing use the link.

https server

Be sure to check cipherli.st for the latest updates.

  • server {
  • listen 443 ssl;
  • server_name svennd.be;
  • root /var/www/html/svennd.be;
  • ssl_certificate /opt/letsencrypt/certs/svennd.be/fullchain.pem;
  • ssl_certificate_key /opt/letsencrypt/certs/svennd.be/privkey.pem;
  • # verify chain of trust of OCSP response using Root CA and Intermediate certs
  • ssl_trusted_certificate /opt/letsencrypt/certs/svennd.be/chain.pem;
  • ssl_session_timeout 1d;
  • ssl_session_cache shared:SSL:50m;
  • ssl_session_tickets off;
  • # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
  • ssl_dhparam /opt/letsencrypt/certs/dhparam.pem;
  • # needs more info
  • ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
  • # suggested conf (interwebz)
  • ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  • ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
  • ssl_prefer_server_ciphers on;
  • # OCSP Stapling ---
  • # fetch OCSP records from URL in ssl_certificate and cache them
  • ssl_stapling on;
  • ssl_stapling_verify on;
  • # need to lookup options
  • resolver 8.8.8.8 valid=300s;
  • resolver_timeout 5s;
  • # headers
  • # note HSTS might break your website if initial setup !
  • # add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload";
  • # add_header X-Frame-Options DENY;
  • add_header X-Content-Type-Options nosniff;
  • add_header X-XSS-Protection "1; mode=block";
  • # hide version
  • server_tokens off;
  • location / {
  • index index.php index.html index.htm;
  • try_files $uri $uri/ /index.php?$args;
  • }
  • error_page 404 /404.html;
  • error_page 500 502 503 504 /50x.html;
  • location = /50x.html {
  • root /usr/share/nginx/html;
  • }
  • location ~ \.php$ {
  • try_files $uri =404;
  • fastcgi_pass 127.0.0.1:9000;
  • fastcgi_index index.php;
  • fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  • fastcgi_param SCRIPT_NAME $fastcgi_script_name;
  • fastcgi_buffer_size 128k;
  • fastcgi_buffers 256 16k;
  • fastcgi_busy_buffers_size 256k;
  • fastcgi_temp_file_write_size 256k;
  • include fastcgi_params;
  • }
  • }
Install MariaDB

There are two options to install MariaDB, either from the Centos/RHEL repo's or a newer version from MariaDB's repo helper. For simplicity I use the Centos, MariaDB 5.5.52 version. But you can get the 10.1/10.2 if you like.

Install from base repository :

  • yum install mariadb-server

Start the mariadb-server prior to configuration :

  • systemctl enable mariadb
  • systemctl start mariadb

configure mariadb :

  • mysql_secure_installation
Start the server

After that you are ready to run the server :

  • systemctl start php-fpm
  • systemctl enable php-fpm
  • systemctl start nginx
  • systemctl enable nginx

And that's how I generally set up Nginx and php-fpm.



Respectfully yours,

Tiruchirappalli Sivashanmugam
Founder of Arththavial    
Founder President, Genius Mother Institute
Founder President, Intellectual Development Foundation
   p.ss@msn.com
   +91-9444499818
   13/1, Agrahara Manappalli - 637017 - India

விதியில் இல்லாதது மதியில் தோன்றாது