how to setup Nginx, php-fpm on Centos 7
Posted on March 17, 2017 • 6 minutes • 1089 words • Suggest Changes
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=https://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 https://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.