LowEndBox - Cheap VPS, Hosting and Dedicated Server Deals

LEMP Stack Installation on Debian 9

This tutorial will show you how to install and configure the LEMP stack on your VPS/LowEndBox, running Debian 9.

LEMP stands for Linux Nginx MySQL PHP, and is a lightweight variation of the LAMP stack, which includes Apache instead of Nginx. You’ll notice that it’s not written as LNMP, and that’s due to the pronunciation of the word Nginx (Engine-X).

LEMP consumes far less resources than the LAMP stack, and is thus more sutiable for cheap VPS machines and Low End Boxes. It is 2.5 times faster under heavy load, according to benchmarks. Also, to speed up things even more, we are going to install MariaDB instead of MySQL as it is much faster, but still fully compatible with the original MySQL.

What We Are Going To Cover

  • Installing Nginx
  • Nginx configuration basics
  • Setting up a Firewall
  • Installing and configuring MariaDB
  • Installing latest PHP
  • Configuring Nginx to serve PHP files
  • Testing the installed stack
  • (With a domain) Securing the site with Let’s Encrypt certificates


We will install and set up the LEMP stack on Debian 9:

  • Starting with a clean VPS with
  • At least 512Mb of RAM
  • 15Gb of free disk space
  • You will need root user access
  • You must have DNS records for your domain (example.com in this tutorial) already set up to point to your VPS in order to install Let’s Encrypt certificates. If you don’t have one, access your IP address instead and skip the last step

Step 1: Install Nginx

Installation and Firewall Setup

First, log in to your server as root or as an another account with sudo privileges. Then, update your package manager’s cache:

sudo apt update

Install Nginx by running the following command:

sudo apt install nginx -y

Nginx is now installed. Go to your domain (or IP address if you don’t have one) in your browser. The default Nginx welcome page will be shown:

Nginx default page

This means that Nginx was installed successfully. Enable it via systemctl to start it at every server boot:

sudo systemctl enable nginx

For maximum security, you’ll now install ufw (uncomplicated firewall) and configure it to allow HTTP, HTTPS, FTP and SSH connections, and to deny all others:

sudo apt install ufw -y
sudo ufw allow 'Nginx Full'
sudo ufw allow OpenSSH
sudo ufw allow SSH
sudo ufw allow ftp

Enable it (make it active) by running:

sudo ufw enable

Answer y when asked, and reload the site in your browser. If you still see the same welcome page, you have configured your firewall correctly. If it shows an error (such as Access Denied), disable the firewall:

sudo ufw disable

and check its configuration:

sudo ufw status

You’ll see a list of enabled profiles. If you don’t see the ones from above, rerun the commands and enable it again.

Configuration Directories

On Debian 9, Nginx stores its configuration files under /etc/nginx, and the default directory for serving static files is /usr/share/nginx/html. This will become important in the later steps, when we’ll need to change the configuration and add new files.

Step 2: Installing MariaDB

Install MariaDB (it is available to apt by default):

sudo apt install mysql-server  -y

Start it when the installation finishes:

sudo systemctl start mysql

To retain full compatibility with the original MySQL product, MariaDB responds to the mysql command.

After MariaDB installation, it is mandatory to run a script (called mysql_secure_installation) to secure the database:

sudo mysql_secure_installation

When it asks you for the current root password, press Enter, because this is the first time you are configuring it. Then, enter a new password for the root user and answer y for anonymous user removal. If you don’t plan on accessing the database from outside the server, answer y to the next question, otherwise type in n. Enter y or press Enter for all questions that follow.

Try to connect to it by running:

sudo mysql -u root -p

When prompted, enter the root password you just set.

You’ll see the mysql prompt:

mysql command prompt

meaning that MariaDB is working correctly and is properly secured. Type in exit to quit the console.

Step 3: Installing PHP

You’ll now install PHP 7.0, the version available by default on Debian 9.

To install PHP 7.0, run:

sudo apt install php-fpm php-mysql

Then, install additional PHP extensions that you will most likely need:

sudo apt install php-mysql php-mbstring php-dev php-gd php-pear php-zip php-xml php-curl -y

To set the version of PHP you just installed as the default one system-wide, run the following command:

sudo update-alternatives --set php /usr/bin/php7.0

Now check the version of the available PHP:

sudo php --version

You’ll see that the version is 7.0, as it should be.

PHP version output

Step 4: Configuring Nginx to Serve PHP Content

PHP is installed and working correctly, but we now have to configure Nginx to use it, because it won’t do so automatically (unlike Apache).

As noted in Step 1, Nginx stores its configuration files under /etc/nginx. Configuration that is currently enabled (which will be applied by Nginx) is stored in a folder named sites-enabled. Similarly, sites that are available, but are not enabled (and thus can not be accessed from the Internet), are stored in a folder named sites-available. We’ll edit the configuration of the default enabled site.

Delete the default config file, because we won’t be needing it:

rm /etc/nginx/sites-enabled/default

A copy of the default site config can be found at /etc/nginx/sites-available/default.

Create a new config file for editing:

nano /etc/nginx/sites-enabled/default

Add the following lines:

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 _;

    location / {
            try_files $uri $uri/ =404;

    location ~ \.php$ {
           include snippets/fastcgi-php.conf;
           fastcgi_pass unix:/run/php/php7.3-fpm.sock;

    location ~ /\.ht {
           deny all;

Save and close the file.

The first part of the above config specifies that Nginx should listen to the HTTP port 80 for requests. Then it sets the root folder for serving files to /var/www/html (which is where you’ll store your website files) and tells Nginx to first try to serve PHP files (instead of HTML).

The rest of the config shown tells Nginx how to call PHP when requested, and to deny access to .htaccess and similar files, which originate from the Apache web server. They are not used by Nginx, and should not be served to users because they might contain some sensitive info.

Restart Nginx for the changes to take effect:

sudo systemctl restart nginx

Try reloading your site (or IP address) in your browser. You should see the same Nginx default welcome page as before.

To test if PHP rendering is working, create a PHP file in /var/www/html:

sudo nano /var/www/html/index.php

Put the following into it:




Save and close the file.

The phpinfo() function outputs very detailed information about PHP installation.

Reload the site in your browser. This time, if all is well, you’ll see a page similar to this:

phpinfo() output

If you see a 502 Bad Gateway error, check the fastcgi_pass line in the above config (the PHP version may be different, though that is unlikely).

Be sure to remove the file immediately afterwards, because it reveals a lot of sensitive info:

rm /var/www/html/index.php

Step 5: Securing Your Domain Using Let’s Encrypt

If you have a domain name, fully registered and pointed to your server, you can secure it using free Let’s Encrypt TLS certificates. The benefits of this are that you’ll have HTTPS access and a padlock will show next to your domain name in all browsers.

Let’s Encrypt certificates will be generated and configured using Certbot, a free program created for this purpose. Let’s Encrypt certificates expire after 90 days, and Certbot will automatically renew them when it decides it is time (every 60 days by default), so you don’t have to worry about them at all.

To install Certbot, you’ll first need to enable the Debian Backports repository by running:

secho "deb http://ftp.debian.org/debian stretch-backports main" |
sudo tee /etc/apt/sources.list.d/backports.list

Update your package manager cache:

sudo apt update

Then, install Certbot:

sudo apt install certbot python-certbot-nginx -t stretch-backports -y

Once it is done, run Certbot:

sudo certbot --nginx --rsa-key-size 4096

Enter an email address you know you’ll check, then agree to the terms of service by typing in A. Press Y if you want to subscribe to EFF’s newsletter, and then input your domain name. Certbot will then ask you if you wish to redirect all traffic to HTTPS – you do, so type in 2.

You’ll receive a congratulatory message, which means that your domain is now secured with free HTTPS certificates from Let’s Encrypt. Refresh your domain in your browser once more. A padlock will show to the left of your site address, meaning that the connection is encrypted. If you want, you can run your site through the SSL Server Test and see that you’ll get an A or better.

What You Can Do Next

You have now installed and configured a LEMP stack on your Debian 9 server. You can now host your PHP website(s) on it, and they will have access to the MariaDB database. For example, you can install WordPress, Joomla, Drupal, Moodle, or any other PHP application that may need to access the database, and it will work with sufficient further configuration.

Dusko Savic is a technical writer and programmer.


No Comments

    Leave a Reply

    Some notes on commenting on LowEndBox:

    • Do not use LowEndBox for support issues. Go to your hosting provider and issue a ticket there. Coming here saying "my VPS is down, what do I do?!" will only have your comments removed.
    • Akismet is used for spam detection. Some comments may be held temporarily for manual approval.
    • Use <pre>...</pre> to quote the output from your terminal/console, or consider using a pastebin service.

    Your email address will not be published. Required fields are marked *