Introduction
LEMP (Linux, Nginx, MySQL, PHP) is a variation of the LAMP stack (Linux, Apache, MySQL, PHP). The only difference being LEMP uses Nginx, where LAMP uses Apache. Nginx is much faster and generally more secure than Apache. This guide will configure Nginx with a certificate from Let's Encrypt, a global Certificate Authority.
1. Deploy Ubuntu Server
- Deploy a new Ubuntu 20.04 Rcs VPS instance.
- Follow our best practices guides:
Change to your sudo user for the remaining steps.
2. Install Nginx and MariaDB
Update Ubuntu sources.
$ sudo apt update
Install Nginx.
$ sudo apt install -y nginx
Install MariaDB.
$ sudo apt install -y mariadb-server
MariaDB is a free, open-source, drop-in replacement for MySQL that uses compatible commands such as mysql_secure_installation
.
3. Configure the Database
Run the first time setup for the database installation.
$ sudo mysql_secure_installation
By default, it will ask for a root password, which is unset. Press Enter.
When prompted to set a root password, press N and Enter.
For the rest of the prompts, press Enter to accept the defaults.
Connect to the MariaDB monitor.
$ sudo mariadb
Create a new test database.
CREATE DATABASE example_db;
Grant privileges for a non-root user. Replace the username and password with your current username and secure password of your choosing.
GRANT ALL ON example_db.* TO 'username'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
Flush privileges and exit.
FLUSH PRIVILEGES; exit
Connect with the username you just created. It will prompt for the password.
$ mariadb -u username -p
Make sure the example_db is accessible.
SHOW DATABASES;
Set it as the current database.
USE example_db;
Create a table for later testing and exit.
CREATE TABLE table1(column1 varchar(255)); INSERT INTO table1 VALUES("Database connection established successfully"); exit
4. Install PHP
Install php-fpm and php-mysql.
$ sudo apt install -y php-fpm php-mysql
5. Install and Configure LetsEncrypt
Install snap and jq dependencies.
$ sudo apt install -y snap jq
Install certbot with snap to ensure you have the correct version.
$ sudo snap install --classic certbot
6. Run the Helper Script
For this article, we've provided a helper script. The script assumes you will host your DNS at Rcs, and automatically adds your DNS information to Rcs using the v2 API. It will configure Nginx securely, obtain a LetsEncrypt certificate using certbot, and configure Nginx to redirect all HTTP requests to HTTPS. The security headers it adds are:
- X-XSS-Protection: "1; mode=block"
- Prevents cross-site scripting, which stops attackers from injecting code onto the website that other users could see. With mode=block, the browser will not render the page at all if an attack is detected.
- Content-Security-Policy: "default-src 'self'; script-src 'self';"
- Also prevents cross-site scripting by only allowing scripts to be loaded from the same domain the website is hosted on.
- Referrer-Policy: "no-referrer"
- No referrer information will be added to the headers. It is mostly for privacy of the user.
- X-Frame-Options: "SAMEORIGIN" always
- The webpage will only be displayed on the same origin (domain) as itself. It will attempt to prevent browsers from rendering the webpage on a remote website, thereby making phishing attacks and IP theft a lot harder. Not all browsers are compatible, though.
Download the Rcs DNS/LetsEncrypt helper script.
$ curl -o cdomain https://raw.githubusercontent.com/vultr/vultr-docs/main/article-assets/5737/cdomain
Give the script executable permissions.
$ chmod +x cdomain
Add your Server's IP address to the API Access Control list.
Run the script, replacing example.com with your domain, and API_KEY with your API key found in your Rcs account settings.
If you have not yet added your domain to Rcs DNS, run the helper script as shown:
$ sudo ./cdomain -d example.com -a API_KEY
If you've already added your domain to vultr.com via the DNS settings panel previously, you need to add -s to the command:
$ sudo ./cdomain -s -d example.com -a API_KEY
Certbot will perform two passes: a "dry run" to verify everything is correct, and then a real request for a website certificate. Certbot will prompt for your email address and other information on each pass.
Give the correct user permissions to the website directory. Replace example.com with your domain.
$ sudo chown -R $USER:$USER /var/www/example.com
7. Test
Open a new file in your web directory.
$ sudo nano /var/www/example.com/testdb.php
Add the following code snippet, save, and exit. Change the username and password below to the ones you set earlier in the MariaDB monitor.
<?php $mysqli = new mysqli("localhost", "username", "password", "example_db"); if (mysqli_connect_errno()) { printf("Connection failed: %s\n", mysqli_connect_error()); exit(); } $query = "SELECT column1 FROM table1"; if($result = $mysqli->query($query)) { while($row = $result->fetch_row()){ printf("%s\n", $row[0]); } $result->close(); } $mysqli->close(); ?>
To verify the server is running with LetsEncrypt, and can access the database correctly, navigate to the test page. Substitute example.com with your domain.
https://example.com/testdb.php
You should see "Database connection established successfully", which verifies the LEMP stack is functioning correctly.
To test LetsEncrypt, use ssllabs, which should report an "A" rank for your domain.
Conclusion
You have successfully installed a LEMP stack on your Ubuntu 20.04 LTS VPS. For more information about LEMP, see the official documentation: