Ultimate LEMP Stack Installation Guide for Ubuntu

In this article, we'll install PHP 8.3, NGINX, MySQL, PHPMyAdmin, SSL, Composer and NPM on a fresh Ubuntu installation.

Published by Rizwan on September 2, 2024
Edited by Rizwan on September 24, 2024

If you’re an old school developer like me, you probably prefer setting up server yourself. LEMP Stack is my go-to stack for a Web Server. And we all love the good old PHPMyAdmin for database administration. So, in this article I’ll show you how to install LEMP Stack and PHPMyAdmin on a Ubuntu VPS.

Things we’ll install:

  1. PHP 8.3 (with PHP-FPM)
  2. NGINX
  3. MySQL Server
  4. PHPMyAdmin
  5. Composer
  6. Node + NPM
  7. And finally a free SSL from Let’s Encrypt via CertBot

If you’re looking for commands / code only and don’t have time to read this article, you can find it on this secret gist I made.

1. Prerequisites

The first thing is to make sure your package repos are up to date, for that run this:

apt update

This will update your VPS’ packages list.

Next, upgrade your packages that are pre-installed:

apt upgrade

If you’re running Ubuntu 24.04 LTS or later, you can skip this step. For Ubuntu 22.04 LTS or older, you also need to add Odrej’s PHP repository with this:

apt-get install ca-certificates apt-transport-https software-properties-common
add-apt-repository ppa:ondrej/php
apt update

The second command would ask you to hit “Enter” twice for confirmation.

2. Installing PHP 8.3

Run this command to install PHP 8.3:

apt install php8.3

Also install some essential packages we’ll need:

apt install php-mbstring php-zip php-gd php-json php-curl php-intl unzip curl npm

3. Installing NGINX and PHP-FPM

Once we’ve installed php8.3, we’ll now install NGINX and PHP-FPM:

apt install nginx
apt install php8.3-fpm

4. Enable Firewall

On most VPS, and on all the droplets of DigitalOcean, UFW (or Uncomplicated Firewall) is pre-installed. You just need to configure and enable it. Since our server will only be running a web server (port 80 and 433) and we’ll need SSH access to it as well (port 22), you need to allow these ports by running the following commands:

ufw allow 80
ufw allow 443
ufw allow 22

These will allow traffic on port 80, 443 and 22. Next, run this command to enable the firewall:

ufw enable

5. Install MySQL and PHPMyAdmin

Run this command to install MySQL server:

apt install mysql-server

Once the MySQL server is installed, it’ll ask you to run mysql_secure_installation but you shouldn’t right away. Securing MySQL Installation can lead to password validation issues when installing PHPMyAdmin, so once the MySQL Server is installed you should install PHPMyAdmin:

apt install phpmyadmin

During installation it’ll ask you to select your web server and the list would contain “Apache2” and “lighttpd”. Since we’re using NGINX, you can skip this step by just hitting “enter”.

Next, it’ll ask you to “Configure database for phpmyadmin with dbconfig-common?”. Here you need to select “Yes”. And on the next screen, where it’ll ask you to enter a password, just hit “enter” with empty password, the installation will generate a password on it’s own.

Now you can run this command to secure installation:

mysql_secure_installation

Now link the phpmyadmin directory to root of the web server (we’ll configure NGINX in the next step):

ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin

6. NGINX Configuration

Create a new NGINX Site config with nano:

nano /etc/nginx/sites-available/yourwebsite.com

You can paste the following config and edit to your requirement:

server {
    listen 80;
    server_name yourwebsite.com www.yourwebsite.com;

    root /var/www/html;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

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

    location ~ /\. {
        deny all;
    }

    # auth_basic "Restricted Content";
    # auth_basic_user_file /etc/nginx/.htpasswd;

}

If this is a staging/test server, you might want to uncomment the auth_basic code from line 21 and 22. And make sure the auth user file exists, by running this command:

sudo htpasswd -c /etc/nginx/.htpasswd yourusername

Once you save the site config in /etc/nginx/sites-available/yourwebsite.com you’ll now link it to Enabled Sites:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

Run this command to check for any errors in NGINX config:

sudo nginx -t

If it’s all good, run this to restart NGINX server:

sudo systemctl restart nginx

7. Install Free SSL via CertBot

Install packages for Certbot and and Certbot NGINX plugin:

apt install certbot python3-certbot-nginx

Once installed, run Certbot and follow on screen instructions:

certbot

8. Install Composer

Tun these commands to install composer:

curl -sS https://getcomposer.org/installer -o composer-setup.php

HASH=$(curl -sS https://composer.github.io/installer.sig)

php -r "if (hash_file('SHA384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"

php composer-setup.php --install-dir=/usr/local/bin --filename=composer

Now confirm if the composer is installed with this command:

composer --version

9. Install Node + NPM via NVM

Run this command to install NVM (Node Version Manager):

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash

Now run nvm to install stable Node + NPM:

nvm install stable

Conclusion

Setting up a server yourself can be daunting, especially if you’re new to DevOps. You can run into PHPMyAdmin not installing due to “Password does not satisfy the current policy requirements”, Conflicting Node/NPM versions etc. or so many other errors. So, over the years, I’ve perfected the solution that I wrote in this article. We installed PHP 8.3, NGINX, MySQL, PHPMyAdmin, SSL, Composer and NPM using the leanest way possible.

If you have any questions or run into issues, feel free to reach out. Happy coding!

How we reviewed this article:

  • Content Process
My process of publishing articles include:
  1. I get an Idea
  2. Get feedback from fellow developers if they want a detailed post on it
  3. Research existing blog posts to see if there's a well written article on it
  4. Write the post
  5. Get feedback from colleagues, improve and publish!