How to setup Linux, Nginx, MySQL & PHP (LEMP) on Debian 9.4

Created by Jordy Leffers at 06-12-2017 11:05:35 +0100

The LEMP stack is a combination of several open-source software packages. In this guide, we will go through all the steps of installing these packages, namely: Linux, Nginx, MySQL and PHP. Together they enable your server to host dynamic web applications or host databases. In this tutorial we'll be going through the installation proces step by step.

Before we start, we need a Linux Debian installation. We'll skip that step in this tutorial since you can easily get a default linux installation on one of the containers on the www.cloudcontainers.net website.

This tutorial is based on the cloud containers created on the my.cloudcontainers.net page. This means that you are by default the root user, so all of the commands below don't make use of sudo. If however, you're not the root user on your system, you'll have to add "sudo" in front of the commands found in the guide below.

 

Install Nginx

Nginx is the engine our webserver will run on, it will display the webpages to our visitors.

It's always good practice to update your currently installed packages to their latest available version:

apt update

apt upgrade


We can use Debian's default repositories to get Nginx

apt install nginx

Now navigate to your server's domain or IP address in your browser.



If you see a picture similar to the one above, you've successfully installed Nginx!

 

 

Install MySQL

The next step is to install MySQL, a popular database management system.

apt install mysql-server -y

You'll be asked to set a password for the administrative account on the MySQL database. 

Next we'll run a script to modify some insecure default settings:

mysql_secure_installation

Again you'll be asked to enter the root user's password and whether you want to change it or not.

The other questions can all be answered y for yes.


If an error looking like this pops up, skip to the bottom of the page to find a fix.

(mariadb.service: Failed at step NO_NEW_PRIVILEGES spawning /usr/sbin/mysqld: Invalid argument)

 

You have now successfully installed your database system!


Install PHP processor

Contrary to other webservers, Nginx does not have a native PHP processor built in it. In order for us to generate dynamic content, however, you might want to use PHP. That's why we will manually install the "FastCGI Process Manager" or fpm.

apt install php-fpm php-mysql


After that we'll need to configure Nginx to use this piece of software for processing PHP requests:

nano /etc/php/7.0/fpm/php.ini

The path to the file might differ a little, depending on php's version.

 

This file contains a somewhat insecure setting as it might allow users to execute scripts they're not intended to.

Find the cgi.fix_pathinfo setting that is commented out using a semicolon. We need to uncomment it and set its value to 0, so it does not by default execute the closest PHP file, once the requested file can't be found.

When you're done, the line should look like this:

cgi.fix_pathinfo=0

After saving and closing the file, we restart our PHP processor:

/etc/init.d/php7.0-fpm restart


Configure Nginx to use PHP-FPM

The last configuration we'll have to make is to the default Nginx server block configuration file:

nano /etc/nginx/sites-available/default

Apart from some additional comments, the file will look like this:

server {        
  listen 80 default_server;        
  listen [::]:80 default_server;         

  root /var/www/html;        
 
  index index.html index.htm index.nginx-debian.html;         
  server_name _;     
    
  location / {                
    # First attempt to serve request as file, then                
    # as directory, then fall back to displaying a 404.                
    try_files $uri $uri/ =404;        
  } 
        
  #location ~ \.php$ {        
  #  include snippets/fastcgi-php.conf;        
  #        
  #  # With php-fpm (or other unix sockets):        
  #  fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;        
  #  # With php-cgi (or other tcp sockets):        
  #  fastcgi_pass 127.0.0.1:9000;        
  #}     
    
  # deny access to .htaccess files, if Apache's document root        
  # concurs with nginx's one        
  #        
  #location ~ /\.ht {        
  #  deny all;        
  #} 
}


There's a couple things we have to change in this document:

  1. index.php should be the first value in our index directive. This tells Nginx prefer php files over e.g. html files.
  2. Modify the server_name to point to the server's domain, or its IP address.
  3. Uncomment the "location ~ \.php$" section, also uncomment the "factcgi-php.conf" inclusion and the php-fpm socket. 
    1. (keep: factcgi_pass 127.0.0.1:9000 commented-out)
  4. Uncomment the "location ~ /\.ht" section, this section deals with .htaccess files. Nginx does not process these files, if these files happen to end up in the document root, they should be denied to the webpage's visitors.


The file should now look like this:

server {        
  listen 80 default_server;        
  listen [::]:80 default_server;         

  root /var/www/html;        
 
  index index.php index.html index.htm index.nginx-debian.html;         
  server_name 83.96.162.87;  
       
  location / {                
    # First attempt to serve request as file, then                
    # as directory, then fall back to displaying a 404.                
    try_files $uri $uri/ =404;        
  }     
    
  location ~ \.php$ {        
    include snippets/fastcgi-php.conf;        
          
    # With php-fpm (or other unix sockets):        
    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;        
    # With php-cgi (or other tcp sockets):        
  #  fastcgi_pass 127.0.0.1:9000;        
  }  
       
  # deny access to .htaccess files, if Apache's document root        
  # concurs with nginx's one        
  #        
  location ~ /\.ht {        
    deny all;        
  } 
}

You can test your configuration file for any syntax errors by entering the following command:

nginx -t

If the test is successful, reload Nginx:

 systemctl reload nginx


Congratulations, you've now installed the LEMP stack on Debian 9.4!

Test PHP

Even though our LEMP stack is now completely set up, we are still going to want to test it.

To test if Nginx can correctly pass .php files to the fpm processor we've just set installed, we'll create a .php file:

nano /var/www/html/info.php

The following code will return some information concerning our server:



Save and close the file.

Navigate to your server's address in your browsers, followed by "/info.php":

http://your_domain_or_IP/info.php

If you reach a page looking like this, everything works correctly:

However, for now we'll delete the page, since it might give away unwanted information to unauthorized users:

rm /var/www/html/info.php


Congratulations, you've now installed and tested the LEMP stack on Debian 9.4!



How to fix the mariadb.service systemd error?

Create a new folder called "mariadb.service.d" inside the systemd/system folder:

mkdir /etc/systemd/system/mariadb.service.d

 

Here, create a new file called "override.conf":

nano/etc/systemd/system/mariadb.service.d/override.conf

 Insert the following text:

[Service] 
NoNewPriviliges=false 
PrivateDevices=false


Save and close the file. Reinstalling MySQL with MariaDB should work now!

Comments

Comments are turned off.