Installing and Configuring LEMP Stack on Ubuntu 22.04

The LEMP stack is a group of open-source software used to serve dynamic web applications. It includes Linux as the operating system, Nginx (Engine-X) as the web server, MySQL (or MariaDB) as the database, and PHP as the backend programming language. In this blog post, we'll walk through installing the LEMP stack, configuring the firewall, securing it with Let's Encrypt SSL, and installing multiple PHP versions with the recommended extensions.

Step 1: Update the System

Before starting, ensure your server is up to date by running the following commands:

sudo apt update
sudo apt upgrade

Step 2: Install Nginx

To install Nginx, use the following command:

sudo apt install nginx -y

Once installed, start and enable Nginx to run on boot:

sudo systemctl start nginx
sudo systemctl enable nginx

You can check the status of the Nginx service with:

sudo systemctl status nginx

Verify that Nginx is serving the default web page by navigating to your server's IP address in a browser.

Step 3: Install MySQL

For the database, we'll use MySQL. To install it, run:

sudo apt install mysql-server -y

Once installed, secure the MySQL installation:

sudo mysql_secure_installation

The mysql_secure_installation script is used to improve the security of your MySQL installation. It helps with basic security tasks such as setting the root password, removing anonymous users, and disabling remote root login. Below is an overview of the output and suggestions for each prompt when you run.

mysql_secure_installation

This process will guide you through several prompts, allowing you to enhance the security of your MySQL installation. The first prompt will ask if you'd like to enable the Validate Password Plugin, which checks the strength of passwords for new MySQL users before they are accepted.

If you choose to enable the Validate Password Plugin, any MySQL user you create who uses a password will need to meet the password policy you select.

  • Securing the MySQL server deployment.
  • Connecting to MySQL using a blank password.
  • VALIDATE PASSWORD COMPONENT can be used to test passwords
  • and improve security. It checks the strength of password
  • and allows the users to set only those passwords which are
  • secure enough. Would you like to setup VALIDATE PASSWORD component?
  • Press y|Y for Yes, any other key for No:

Choose whether or not to reset the root password. Whether you choose this or not will be determined by the applications you're going to be using and your server configuration. Root is not set to authenticate to the database shell using a password.

  • Please set the password for root here.
  • New password:
  • Re-enter new password:

The remaining options simply answer yes to for the default recommended options to finish configuring MySQL

  • Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
  • Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y
  • Remove test database and access to it? (Press y|Y for Yes, any other key for No): y
  • Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y

Test mysql and ensure you're able to login.

root@server:~# mysql

or if using a sudo user:

sudo mysql -u root -p

Step 4: Install PHP and Required Extensions

Next, install PHP and the necessary extensions for running PHP applications. In this step, we'll ensure that the most common and recommended extensions are installed:

sudo apt install php-fpm php-mysql php-cli php-curl php-xml php-mbstring php-zip php-gd php-json php-common -y

PHP-FPM is required for Nginx, as it doesn't come with built-in support for processing PHP files.

Step 5: Configure Nginx to Use PHP

Create a server block configuration for your website. By default, Nginx uses /etc/nginx/sites-available/default. To create a custom configuration, you can copy the default:

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/yourdomain.com

Edit the file you've copied replacing all instances of yourdomain.com with your actual domain name

sudo nano /etc/nginx/sites-available/yourdomain.com

Update your server block with the necessary changes. here's an example

Save and exit the file then create a directory for your website

sudo mkdir -p /var/www/yourdomain.com

Set ownership and permissions for the directory to the correct user

chown -R $USER:$USER /var/www/yourdomain.com

Activate your site so nginx can load it when visiting the domain name

sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

Disable the default site for Nginx. You can enable it again using the above link command

unlink /etc/nginx/sites-enabled/default

Check the nginx configuration

nginx -t

If everything was configured correctly, Nginx will report back that the configuration is ok. Otherwise go back and resolve any errors.

root@server:~# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If everything is ok, restart Nginx

systemctl reload nginx

Step 6: Install and Configure UFW Firewall

We'll use UFW (Uncomplicated Firewall) to configure basic firewall settings. First, ensure UFW is installed:

apt install ufw -y

Set the default incoming and outgoing policies for UFW. Run the following commands

ufw default deny incoming
ufw default allow outgoing

Open the ports in UFW that you'll need to use. We'll start with SSH

ufw allow OpenSSH

Next well allow Nginx while also allowing it to connect and process https connections

ufw allow 'Nginx Full'

Enable the firewall

sudo ufw enable

Step 7: Secure Your Website with Let's Encrypt SSL

To secure your website, install the Certbot client for Nginx, which handles obtaining and renewing SSL certificates.

First, install Certbot and the Nginx plugin:

sudo apt install certbot python3-certbot-nginx -y

Obtain the SSL Certificate

sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Follow the prompts to configure HTTPS. Certbot will automatically update your Nginx configuration to redirect HTTP traffic to HTTPS.

Check automatic certificate renewal

sudo certbot renew --dry-run

Step 8: Install Additional PHP Versions

To support multiple PHP versions, you'll need to add the necessary repository and install the desired versions.

First, add the Ondřej Surý repository:

sudo add-apt-repository ppa:ondrej/php
sudo apt update

Now, install additional PHP versions. For example, to install PHP 7.4 and PHP 8.1, run:

sudo apt install php7.4-fpm php8.1-fpm

Each version will have its own PHP-FPM service, which you can manage like this:

sudo systemctl start php7.4-fpm
sudo systemctl enable php8.1-fpm

You can install extensions as needed for your PHP versions. For example:

sudo apt install php7.4-mysql php8.1-mbstring

Switching Between PHP Versions in Nginx

To switch between PHP versions, edit the fastcgi_pass directive in your Nginx server block to point to the corresponding PHP-FPM socket.

For PHP 7.4:

fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;

After making changes, don't forget to reload Nginx:

sudo systemctl reload nginx

Conclusion

You now have a fully functional LEMP stack with PHP, MySQL, Nginx, a basic UFW firewall, and SSL encryption via Let's Encrypt. Additionally, you've set up multiple PHP versions to switch between as necessary. You can start hosting PHP-based applications and serve them securely over HTTPS.