LEMP stacks are an open source platform for applications that is compatible with the LAMP (refers to a Linux-based operating system, the Apache web server, the MySQL database server, and the PHP programming language). LEMP replaces Apache with Nginx which is light-weight and its ability to scale easily on minimal hardware. This tutorial (How to install LEMP Server (Nginx 1.8, MariaDB 10.1, PHP-FPM) on CentOS 7) will help sysadmins to set up a new web server using LEMP stack.
In previous tutorial series how to install LEMP stacks on CentOS, I usually use Remi’s RPM repository to install MariaDB 5.5, and base EPEL’s repository to install Nginx 1.6.3. The thing is you can’t usually get the newest version of Nginx or MariaDB from them, to get the newest version of Nginx & MariaDB, you will have to compile and install them from source. In this tutorial I’m going to show you how to install LEMP Server with Nginx 1.8, MariaDB 10.1 and PHP-FPM on CentOS 7.
Installing the Required Software
You will need to install a few required software before compile from source, like the GCC compiler and other utilities. Install it by running the following command in a terminal:
# yum update # yum install GeoIP GeoIP-devel fontconfig fontpackages-filesystem freetype gd gperftools-libs libX11 libX11-common libXau libXpm libjpeg-turbo libpng libunwind libxcb libxslt nano make gcc gcc-c++ zlib-devel pcre-devel openssl openssl-devel
Install Nginx 1.8 on CentOS 7
Nginx is a popular lightweight, high performance web server, it’s free and open source. Nginx comes with simple configuration files, and with asynchronous architecture (event-driven) it uses much less resources vs Apache. At the time of writing, the latest stable version of Nginx is 1.8.0. Nginx 1.8.0 comes with many few features like hash load balancing method, backend SSL certificate verification, thread pools support, proxy_request_buffering, and more. You can check the latest versions and changelog at the main nginx site.
Download Nginx 1.8
We are going to download and save nginx 1.8 source code to /tmp directory (you can download it anywhere you want to) using wget command, and extract the tar archive file.
# cd /tmp # wget http://nginx.org/download/nginx-1.8.0.tar.gz # tar -xvzf nginx-1.8.0* # cd nginx-1.8.0
Nginx’s options
You can customize Nginx installation process to the way you want, you can look at the Install Options page for full details, or you can use –help to see configuration options and modules needed for your compilation process.
# ./configure --help
output of ./configure with –help option, for detailed of each modules, please refer to http://nginx.org/en/docs/
--help print this message --prefix=PATH set installation prefix --sbin-path=PATH set nginx binary pathname --conf-path=PATH set nginx.conf pathname --error-log-path=PATH set error log pathname --pid-path=PATH set nginx.pid pathname --lock-path=PATH set nginx.lock pathname --user=USER set non-privileged user for worker processes --group=GROUP set non-privileged group for worker processes --build=NAME set build name --builddir=DIR set build directory --with-rtsig_module enable rtsig module --with-select_module enable select module --without-select_module disable select module --with-poll_module enable poll module --without-poll_module disable poll module --with-threads enable thread pool support --with-file-aio enable file AIO support --with-ipv6 enable IPv6 support --with-http_ssl_module enable ngx_http_ssl_module --with-http_spdy_module enable ngx_http_spdy_module --with-http_realip_module enable ngx_http_realip_module --with-http_addition_module enable ngx_http_addition_module --with-http_xslt_module enable ngx_http_xslt_module --with-http_image_filter_module enable ngx_http_image_filter_module --with-http_geoip_module enable ngx_http_geoip_module --with-http_sub_module enable ngx_http_sub_module --with-http_dav_module enable ngx_http_dav_module --with-http_flv_module enable ngx_http_flv_module --with-http_mp4_module enable ngx_http_mp4_module --with-http_gunzip_module enable ngx_http_gunzip_module --with-http_gzip_static_module enable ngx_http_gzip_static_module --with-http_auth_request_module enable ngx_http_auth_request_module --with-http_random_index_module enable ngx_http_random_index_module --with-http_secure_link_module enable ngx_http_secure_link_module --with-http_degradation_module enable ngx_http_degradation_module --with-http_stub_status_module enable ngx_http_stub_status_module --without-http_charset_module disable ngx_http_charset_module --without-http_gzip_module disable ngx_http_gzip_module --without-http_ssi_module disable ngx_http_ssi_module --without-http_userid_module disable ngx_http_userid_module --without-http_access_module disable ngx_http_access_module --without-http_auth_basic_module disable ngx_http_auth_basic_module --without-http_autoindex_module disable ngx_http_autoindex_module --without-http_geo_module disable ngx_http_geo_module --without-http_map_module disable ngx_http_map_module --without-http_split_clients_module disable ngx_http_split_clients_module --without-http_referer_module disable ngx_http_referer_module --without-http_rewrite_module disable ngx_http_rewrite_module --without-http_proxy_module disable ngx_http_proxy_module --without-http_fastcgi_module disable ngx_http_fastcgi_module --without-http_uwsgi_module disable ngx_http_uwsgi_module --without-http_scgi_module disable ngx_http_scgi_module --without-http_memcached_module disable ngx_http_memcached_module --without-http_limit_conn_module disable ngx_http_limit_conn_module --without-http_limit_req_module disable ngx_http_limit_req_module --without-http_empty_gif_module disable ngx_http_empty_gif_module --without-http_browser_module disable ngx_http_browser_module --without-http_upstream_hash_module disable ngx_http_upstream_hash_module --without-http_upstream_ip_hash_module disable ngx_http_upstream_ip_hash_module --without-http_upstream_least_conn_module disable ngx_http_upstream_least_conn_module --without-http_upstream_keepalive_module disable ngx_http_upstream_keepalive_module --with-http_perl_module enable ngx_http_perl_module --with-perl_modules_path=PATH set Perl modules path --with-perl=PATH set perl binary pathname --http-log-path=PATH set http access log pathname --http-client-body-temp-path=PATH set path to store http client request body temporary files --http-proxy-temp-path=PATH set path to store http proxy temporary files --http-fastcgi-temp-path=PATH set path to store http fastcgi temporary files --http-uwsgi-temp-path=PATH set path to store http uwsgi temporary files --http-scgi-temp-path=PATH set path to store http scgi temporary files --without-http disable HTTP server --without-http-cache disable HTTP cache --with-mail enable POP3/IMAP4/SMTP proxy module --with-mail_ssl_module enable ngx_mail_ssl_module --without-mail_pop3_module disable ngx_mail_pop3_module --without-mail_imap_module disable ngx_mail_imap_module --without-mail_smtp_module disable ngx_mail_smtp_module --with-google_perftools_module enable ngx_google_perftools_module --with-cpp_test_module enable ngx_cpp_test_module --add-module=PATH enable an external module --with-cc=PATH set C compiler pathname --with-cpp=PATH set C preprocessor pathname --with-cc-opt=OPTIONS set additional C compiler options --with-ld-opt=OPTIONS set additional linker options --with-cpu-opt=CPU build for the specified CPU, valid values: pentium, pentiumpro, pentium3, pentium4, athlon, opteron, sparc32, sparc64, ppc64 --without-pcre disable PCRE library usage --with-pcre force PCRE library usage --with-pcre=DIR set path to PCRE library sources --with-pcre-opt=OPTIONS set additional build options for PCRE --with-pcre-jit build PCRE with JIT compilation support --with-md5=DIR set path to md5 library sources --with-md5-opt=OPTIONS set additional build options for md5 --with-md5-asm use md5 assembler sources --with-sha1=DIR set path to sha1 library sources --with-sha1-opt=OPTIONS set additional build options for sha1 --with-sha1-asm use sha1 assembler sources --with-zlib=DIR set path to zlib library sources --with-zlib-opt=OPTIONS set additional build options for zlib --with-zlib-asm=CPU use zlib assembler sources optimized for the specified CPU, valid values: pentium, pentiumpro --with-libatomic force libatomic_ops library usage --with-libatomic=DIR set path to libatomic_ops library sources --with-openssl=DIR set path to OpenSSL library sources --with-openssl-opt=OPTIONS set additional build options for OpenSSL --with-debug enable debug logging
For this tutorial, the following modules and specifications are going to be used. With these modules, Nginx can handle typical modern website scripts like WordPress, PhpBB, … etc. you can add or remove modules and/or prefix/path to whatever you need.
To add modules
--with-module_name
To disable/remove modules
--without-module_name
** make sure the command with options stays on a single line
# ./configure --user=nginx --group=nginx --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --with-http_geoip_module --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-mail --with-mail_ssl_module --with-ipv6 --with-http_spdy_module --with-pcre
Configuration summary + using system PCRE library + using system OpenSSL library + md5: using OpenSSL library + sha1: using OpenSSL library + using system zlib library nginx path prefix: "/etc/nginx" nginx binary file: "/usr/sbin/nginx" nginx configuration prefix: "/etc/nginx" nginx configuration file: "/etc/nginx/nginx.conf" nginx pid file: "/var/run/nginx.pid" nginx error log file: "/var/log/nginx/error.log" nginx http access log file: "/var/log/nginx/access.log" nginx http client request body temporary files: "client_body_temp" nginx http proxy temporary files: "proxy_temp" nginx http fastcgi temporary files: "fastcgi_temp" nginx http uwsgi temporary files: "uwsgi_temp" nginx http scgi temporary files: "scgi_temp"
Please note, default Nginx’s installation paths and locations for various files are different from what I’m using. I’m used to install Nginx from EPEL’s repository and they saves configuration files in /etc/nginx.
Now we can build the binaries using make command, and make install to install Nginx 1.8 on CentOS 7
# make # make install
NGINX Init Scripts for CentOS 7
By installing Nginx 1.8 from source, init script won’t be automatically created for you, if you want to manage Nginx daemon process through a init script, create the script below in /etc/init.d/ so you can use systemctl command to manage the process
If you have used other options or have placed the Nginx binary in a directory other than /usr/sbin/nginx then you will need to adjust the script shown below to match your installation.
# nano /etc/init.d/nginx
with the content below
#!/bin/sh # # nginx - this script starts and stops the nginx daemon # # How to install LEMP Server (Nginx 1.8, MariaDB 10.1, PHP-FPM) on CentOS 7 # https://www.namhuy.net/3395/install-lemp-server-nginx-1-8-mariadb-10-1-php-fpm-on-centos-7.html # # chkconfig: - 85 15 # description: NGINX is an HTTP(S) server, HTTP(S) reverse \ # proxy and IMAP/POP3 proxy server # processname: nginx # config: /etc/nginx/nginx.conf # pidfile: /var/run/nginx.pid # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ "$NETWORKING" = "no" ] && exit 0 nginx="/usr/sbin/nginx" prog=$(basename $nginx) NGINX_CONF_FILE="/etc/nginx/nginx.conf" lockfile=/var/lock/subsys/nginx make_dirs() { # make required directories user=`$nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -` if [ -z "`grep $user /etc/passwd`" ]; then useradd -M -s /bin/nologin $user fi options=`$nginx -V 2>&1 | grep 'configure arguments:'` for opt in $options; do if [ `echo $opt | grep '.*-temp-path'` ]; then value=`echo $opt | cut -d "=" -f 2` if [ ! -d "$value" ]; then # echo "creating" $value mkdir -p $value && chown -R $user $value fi fi done } start() { [ -x $nginx ] || exit 5 [ -f $NGINX_CONF_FILE ] || exit 6 make_dirs echo -n $"Starting $prog: " daemon $nginx -c $NGINX_CONF_FILE retval=$? echo [ $retval -eq 0 ] && touch $lockfile return $retval } stop() { echo -n $"Stopping $prog: " killproc $prog -QUIT retval=$? echo [ $retval -eq 0 ] && rm -f $lockfile return $retval } restart() { configtest || return $? stop sleep 1 start } reload() { configtest || return $? echo -n $"Reloading $prog: " killproc $nginx -HUP RETVAL=$? echo } force_reload() { restart } configtest() { $nginx -t -c $NGINX_CONF_FILE } rh_status() { status $prog } rh_status_q() { rh_status >/dev/null 2>&1 } case "$1" in start) rh_status_q && exit 0 $1 ;; stop) rh_status_q || exit 0 $1 ;; restart|configtest) $1 ;; reload) rh_status_q || exit 7 $1 ;; force-reload) force_reload ;; status) rh_status ;; condrestart|try-restart) rh_status_q || exit 0 ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}" exit 2 esac
The nginx’s init file we created is a shell script, it needs executions permissions and manage the daemon with the command below
# chmod +x /etc/init.d/nginx
You need to run systemctl daemon-reload to reload systemd before you can use systemctl to start/stop/restart Nginx
# systemctl daemon-reload
** If you don’t reload systemd, you won’t be able to run systemctl to start/stop/restart Nginx, and you might get the error below which I did.
Failed to start nginx.service: Unit nginx.service failed to load: No such file or directory.
Start, stop, and restart Nginx
Now we can start, stop, restart, and reload Nginx on CentOS 7 using these commands:
# systemctl start nginx # systemctl stop nginx # systemctl restart nginx
or
# /etc/init.d/nginx start # /etc/init.d/nginx stop # /etc/init.d/nginx restart # /etc/init.d/nginx reload
You can also check the current Nginx status as well as the configuration syntax:
# /etc/init.d/nginx status # /etc/init.d/nginx configtest
Start Nginx on startup
If you want Nginx starts on boot up by itself (which you will want), run this command
# systemctl enable nginx
Install MariaDB 10.1 on CentOS 7
MariaDB 10.1 is the latest stable version of MariaDB. There are many great new features in MariaDB 10.1, for example Galera (multi-master solution), table, tablespace and log encryption, page compression, improved optimization, increased InnoDB pages to 64k vs 16k old limit, many bugs & security fixed in MariaDB 10.1. For a full detailed list of new features of MariaDB 10.1 you can visit https://mariadb.com/kb/en/mariadb/what-is-mariadb-101/
Installing MariaDB 10.1 on CentOS 7 is quite easier than installing Nginx 1.8 on CentOS 7. You don’t have to compile MariaDB 10.1, you can install MariaDB 10.1 with yum command from MariaDB’s repository with a few simple steps.
Adding the MariaDB Repository
Let’s create a .repo file for MariaDB, you can call it anything you want but to keep things simple, we are gonna create MariaDB.repo in /etc/yum.repos.d/ directory
# nano /etc/yum.repos.d/MariaDB.repo
With the content below (this MariaDB.repo entry IS for CentOS 7, if you use other OS this will not work)
# MariaDB 10.1 CentOS repository list - created 2016-01-20 20:18 UTC # http://mariadb.org/mariadb/repositories/ [mariadb] name = MariaDB baseurl = http://yum.mariadb.org/10.1/centos7-amd64 gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck=1
Install MariaDB
Once you have created MariaDB.repo, you now can install MariaDB 10.1 via yum command.
# yum install MariaDB-server MariaDB-client
You will be ask to confirm MariaDB’s signing key before import it, say “y” for yes to confirm.
Retrieving key from https://yum.mariadb.org/RPM-GPG-KEY-MariaDB Importing GPG key 0x1BB943DB: Userid : "MariaDB Package Signing Key <[email protected]>" Fingerprint: 1993 69e5 404b d5fc 7d2f e43b cbcb 082a 1bb9 43db From : https://yum.mariadb.org/RPM-GPG-KEY-MariaDB Is this ok [y/N]: y
Start, stop, and restart MariaDB
Now we can start, stop, restart, and reload MariaDB on CentOS 7 using these commands:
# systemctl start mariadb # systemctl stop mariadb # systemctl restart mariadb
Start MariaDB on startup
If you want MariaDB starts on boot up by itself (which you will want), run this command
# systemctl enable mariadb
# /usr/bin/mysql_secure_installation
Basically the script asks you to
- If this is the first time you install mariadb, you should not have a password for root. Enter for none.
- Set new root password, enter your root password for mariadb
- Remove anonymous users, enter “y” for yes.
- Disallow root login remotely, enter “y” for yes.
- Reload privilege tables now? enter “y” for yes
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY! In order to log into MariaDB to secure it, we'll need the current password for the root user. If you've just installed MariaDB, and you haven't set the root password yet, the password will be blank, so you should just press enter here. Enter current password for root (enter for none): OK, successfully used password, moving on... Setting the root password ensures that nobody can log into the MariaDB root user without the proper authorisation. Set root password? [Y/n] y New password: Re-enter new password: Password updated successfully! Reloading privilege tables.. ... Success! By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? [Y/n] y ... Success! Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? [Y/n] y ... Success! By default, MariaDB comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? [Y/n] y - Dropping test database... ... Success! - Removing privileges on test database... ... Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? [Y/n] y ... Success! Cleaning up... All done! If you've completed all of the above steps, your MariaDB installation should now be secure. Thanks for using MariaDB!
Install PHP-FPM on CentOS 7
We can make PHP5 work in nginx through PHP-FPM, FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation with some additional features (mostly) useful for heavy-loaded sites. We are going to add EPEL & Remi repository, then install PHP 7, PHP-FPM and other php’s modules.
Adding EPEL and Remi repository
# rpm -Uvh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm # rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
For this tutorial I’m going to install various PHP’s modules that most of modern PHP websites/scripts required, feel free to add or remove modules depends on your need.
# yum --enablerepo=remi,remi-php70 install php70-php-fpm php70-php-cli php70-php-common php70-php-devel php70-php-mysqlnd php70-php-opcache php70-php-pear php70-php-gd php70-php-mbstring php70-php-mcrypt php70-php-pdo php70-php-xml php70-php-tidy php70-php-pecl php70-php-pecl-geoip -y
For the full list of PHP’s modules, you can use the command below
# yum search all php
Start, stop, and restart PHP-FPM
Now we can start, stop, restart, and reload PHP-FPM on CentOS 7 using these commands:
# systemctl start php-fpm # systemctl stop php-fpm # systemctl restart php-fpm
Start PHP-FPM on startup
To make php-fpm to start on boot up by itself, run this command
# systemctl enable php70-php-fpm
To update PHP 7 and its modules, you can use the command below. You can do it manually or add it to cron.
# yum --enablerepo=remi-php70 update php\*
By now you should have installed LEMP Server (Nginx 1.8, MariaDB 10.1, PHP-FPM 7) on CentOS 7, but I have not shown you how to configure the LEMP stacks for them to work properly.