LEMP stack is a group of software and LEMP is an acronym and it describes a Linux operating system, with Nginx web server, MySQL as a database and the dynamic processing is handled by PHP to serve dynamic websites and web applications.
This guide is tested on Ubuntu 18.04 LTE. This installation guide and configuration would be very much similar to other OS or OS versions, but the commands and configuration location may vary as per your installation.
If you need to setup Linux, Apache, MySQL, PHP, read LAMP Stack tutorial:
How To Install LAMP Stack on Ubuntu 18.04, 16.04, 14.04
Step-by-step LEMP Stack Installation Guide
1. Prerequisites
Sign on to Ubuntu and update your system before LEMP Stack installation. In order to do that run the commands below:
sudo apt-get update && sudo apt-get dist-upgrade && sudo apt-get autoremove
2. Install the Nginx Web Server
NGINX is a modern, efficient, lightweight, and high-performance web server. NGINX can work efficiently even under high load as it uses an asynchronous event-driven model. To install the NGINX webs server, run the following command:
sudo apt-get install nginx
If you have ufw
firewall running on your server, you need to allow connections to NGINX.
So you can enable the port 80 by typing:
sudo ufw allow 'Nginx HTTP'
If you have also enabled SSL for your website, you also need to enable the port 443. This can be done by typing:
sudo ufw allow 'Nginx HTTPS'
Now you can check the status for the change that allows connections to NGINX. This can be done by running the command below:
sudo ufw status
You should see the following output that allows traffic for both HTTP and HTTPS.
Status: active To Action From -- ------ ---- 22 ALLOW Anywhere 2222 ALLOW Anywhere Nginx HTTP ALLOW Anywhere Nginx HTTPS ALLOW Anywhere 80 ALLOW Anywhere 443 ALLOW Anywhere 22 (v6) ALLOW Anywhere (v6) 2222 (v6) ALLOW Anywhere (v6) Nginx HTTP (v6) ALLOW Anywhere (v6) Nginx HTTPS (v6) ALLOW Anywhere (v6) 80 (v6) ALLOW Anywhere (v6) 443 (v6) ALLOW Anywhere (v6)
Now, enter the domain name or IP address of your server in the browser to test if the server is working or not.
If the domain name is not pointed to your server or you do not know the public IP Address of your server, you can find it by typing the following commands:
ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'
Alternatively, you can check which IP address is accessible when viewed from the different locations on the internet by running:
curl -4 icanhazip.com
Now type the IP address of your server into the browser and hit enter.
Once you check your domain name or IP into the browser, you see an NGINX welcome page which ensures the correct installation of NGINX web server.
3. Install MySQL
Now we are going to install a database management system, MySQL, to store and manage the database for the website.
To install MySQL run the following command:
sudo apt-get install mysql-server
While installing MySQL Server, you will be asked to set a root password. Set up a strong password and save it for future reference by keeping it in a safe place.
Harden MySQL Server
Harden you MySQL Server by running the mysql_secure_installation
script. This will get rid of several security concerns by removing the test database and anonymous users in a default MySQL installation:
sudo mysql_secure_installation
Now, you will have a choice to change the root password of MySQL. Remove anonymous user accounts, and disable root logins outside of localhost. MySQL root password change is only required if you feel that it is weak and you can strengthen the password more. It is recommended that you answer yes to other options as it will harden your MySQL.The MySQL database software is now installed and well configuration. Now you are ready to go.
The MySQL database software is now installed and configuration. Now you are ready to go.
MySQL Root Login
To log in to MySQL as the root user:
mysql -u root -p
Now enter the root password that you assigned earlier while hardening your MySQL Server using mysql_secure_installation
.
4. Install PHP for Processing
Now we need to connect all these things together to generate a dynamic website. For that processing purpose, we need to install the PHP.
We will need to install php5-fpm
since Nginx web server does not contain native PHP processing. Here fpm stands for “FastCGI Process Manager”.
Now we need to install this module along with some helper packages that will help PHP to communicate with the MySQL database. To install the module and helper packages, run the following command:
sudo apt-get install php-fpm php-mysql
Configuring PHP Processor
We are done with the installation process and to make our setup more secure we need to configure the PHP Processor.
Open the main php5-fpm configuration file php.ini
with root privileges:
sudo nano /etc/php/7.0/fpm/php.ini
Now inside this configuration file look for the cgi.fix_pathinfo
. It is commented by default with a semi-colon ;
and set to 1
by default, which is an extremely insecure setting since it tells PHP to attempt to find and execute the closest file if a PHP file is not found. To make it a secure setting, we need to set cgi.fic_pathinfo
value to 0
by uncommenting it.
cgi.fix_pathinfo=0
Save and close the file and restart the PHP processor:
sudo systemctl restart php7.0-fpm
OR
sudo service php7.0-fpm restart
This will implement the change that we made.
5. Configure Nginx
Now, we to configure our NGINX to run a basic test site. So we need to do some basic settings in the server block. Server blocks are similar to Apache’s Virtual Hosts. We can configure it by editing the default NGINX file by using the following command:
sudo vim /etc/nginx/sites-available/default
Now enter the path for your test site and uncomment location block. This is how your code inside the default file should look like:
server { listen 80; listen [::]:80; server_name example.com www.example.com *.example.com; return 301 https://www.example.com$request_uri; } HTTPS server server { listen 443; listen [::]:443 ssl; server_name example.com www.example.com *.example.com; root /var/www/html/example.com/public_html; index index.php; access_log /var/log/nginx/example.access.log; error_log /var/log/nginx/example.error error; location ~ /.well-known { allow all; } #Leverage browser caching location ~* .(jpg|jpeg|png|gif|ico|css|js)$ { expires 365d; }location ~* \.(pdf)$ { expires 30d; }
ssl on; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_session_timeout 1d; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:ECDHE-RSA-AES128-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA128:DHE-RSA-AES128-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA128:ECDHE-RSA-AES128-SHA384:ECDHE-RSA-AES128-SHA128:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA384:AES128-GCM-SHA128:AES128-SHA128:AES128-SHA128:AES128-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4'; ssl_prefer_server_ciphers on; location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ /index.php?$args; # Uncomment to enable naxsi on this location # include /etc/nginx/naxsi.rules } # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 location ~ .php$ { fastcgi_split_path_info ^(.+.php)(/.+)$; # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini# With php5-fpm: fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
} }
Now save the changes that you have made, and test your Nginx configuration file for syntax errors by running:
sudo nginx -t
If any errors are reported, check the configuration file, make the necessary correction.
If it doesn’t report any error, restart or reload the Nginx by typing:
For restart:
sudo service nginx restart
For reload:
sudo systemctl reload nginx
Learn more about Nginx command line.
6. Create a PHP File to Test Configuration
Our LEMP stack setup completed perfectly but now we need to test our configuration. And to test the configuration, we can create a new test page inside the site directory which we specified earlier while configuring Nginx in the server block. We can create the test page by typing the following command:
sudo vim /usr/share/nginx/html/info.php
Now, enter the following lines of code inside the info.php
file
Now save and close the file.
Now, you can visit this test page in your web browser by visiting your server’s domain name or public IP address followed by /info.php:
https:// domain_name_or_IP/info.php
You should see a web page that has been generated by PHP information about your server. Which looks somewhat like this:
Conclusion
Now you have successfully installed and tested LEMP Stack installation. Now you will be able to host a blazing-fast PHP based dynamic website.
I hope you will find this tutorial on how to install LEMP Stack on Ubuntu 16.04 useful.
If you face any difficulty during LEMP Server configuration, feel free to contact me on my email address: rajesh.rai@websitevidya.com or put your query in the comment section below.