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:
- PHP 8.3 (with PHP-FPM)
- NGINX
- MySQL Server
- PHPMyAdmin
- Composer
- Node + NPM
- 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
- I get an Idea
- Get feedback from fellow developers if they want a detailed post on it
- Research existing blog posts to see if there's a well written article on it
- Write the post
- Get feedback from colleagues, improve and publish!