In this blog post I’ll show you how I installed a LEMP stack on Debian 11, but this post should apply to most distros based on Debian. I won’t go too much into detail about what these services do, but in a nutshell, Nginx is a web server, MariaDB is a database, PHP is a server-side scripting language, and it all comes together to power dynamic websites, including CMS’s (Content Management Systems) like WordPress. LEMP stands for Linux, Nginx, MariaDB or MySQL, and PHP. I’ll also show how to install phpMyAdmin, which will allow you to manage MariaDB through a web interface.
Contents
Prerequisites
If you plan on following along, you’ll need the following:
- An up to date Debian 11 install running on your hardware/software of choice with full root access (You don’t need many resources, but I would recommend at least 512MB of available RAM).
- Some Linux command line experience.
- If you plan on putting it on the internet, then you’ll also need access to your firewall, your public IP address, and a domain name.
- I would recommend enabling SSH since you’ll be able to copy-paste commands, and it’ll make managing your server easier. However, do not do this if you don’t know how to firewall a server off. If you open SSH to the internet and an attacker guesses your login, then they will have full root access to your server.
You really don’t need much for this project, however, I would recommend using a VPS (Virtual Private Server) instead of directly exposing parts of your network to the internet. Not only is it more secure, but you don’t have to worry about stuff like CGNAT (Carrier-Grade NAT) or poor upload speeds (Like I do, thanks Xfinity). I personally use Vultr (What’s a good blog post without a referral plug?), but there’s plenty of good options out there.
Installing Filebrowser (Optional)
I cannot stress this enough, but if you don’t know how to properly firewall off a server, skip this step. If it’s not properly firewalled off, an attacker could guess your login info and gain full access to your server’s filesystem. If you do know what you’re doing, a web-based file manager like Filebrowser makes life a lot easier when editing config files.
However, if you’re using SSH on your server, you can also skip this step (Unless if you want to manage config files through a web interface) since you can leverage SFTP (SSH File Transfer Protocol) through FileZilla. It might not be as user friendly, but this will eliminate the need of having more services running and ports open on your server.
To install Filebrowser, simply copy-paste the following command (Make sure you install curl first):
curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | sudo bash
Filebrowser has various options, but to run Filebrowser and give it full access to your filesystem, replace the example IP address and the port number with yours (If you don’t specify it, then port 8080 will be used), and run the following command:
sudo filebrowser -r / -a 12.34.56.78 -p 1234
You should now be able to access Filebrowser by typing in your_ip_address:your_port_number
in to your web browser. If you can’t access it, check to make sure that the IP address you entered is correct (Or try entering 0.0.0.0, but I’ve found that it doesn’t always work), and make sure that any firewall that your server is behind is allowing the port you specified. Some Linux distros may include a firewall like ufw or iptables by default, but Debian does not.
Securing Filebrowser
Once you’ve accessed the login page, use admin
for the username and password. You’ll want to change this from the defaults.
Over on the left side of the screen, select Settings:
Select User Management:
Select the pencil icon:
Enter a new username and password of your choice:
Then finally, select Save at the bottom of the page:
Making Filebrowser a Service
Since remembering the command for Filebrowser can be difficult and you might want it to run in the background, it’s possible to make it a systemd service by creating a file in /etc/systemd/system/filebrowser.service
with your favorite text editor, and adding the following lines (Replacing Filebrowser Command with your Filebrowser command, obviously):
[Unit]
Descirption=Filebrowser
[Service]
ExecStart=Filebrowser Command
[Install]
WantedBy=multi-user.target
Now you can run Filebrowser in the background simply by typing in sudo systemctl start filebrowser
, or allow it to run at startup by typing in sudo systemctl enable filebrowser
.
Installing Nginx
To install Nginx, run the following command
sudo apt install nginx
Start Nginx by running the following command:
sudo systemctl start nginx
And then check its status:
sudo systemctl status nginx
If Nginx appears to be running, press q on your keyboard if the command didn’t quit, then type the IP address of your server into your web browser’s address bar. You should see a screen that looks like this:
Run the following command to allow Nginx to run at startup:
sudo systemctl enable nginx
Then make the Nginx user (www-data) the owner of the web directory:
sudo chown -R www-data:www-data /usr/share/nginx/html
Nginx Automatic Restart
If Nginx is killed, you’ll need to manually run sudo systemctl restart nginx
, but it’s possible to automate this process. First create the following directory:
sudo mkdir -p /etc/systemd/system/nginx.service.d/
Create and open the following file with your favorite text editor:
/etc/systemd/system/nginx.service.d/restart.conf
Add the following lines (You can replace the highlighted text with whatever time you want, but don’t make it too short):
[Service]
Restart=always
RestartSec=5s
Then finally run the following command so systemd will pick up the changes:
sudo systemctl daemon-reload
You can test that Nginx will be automatically restarted by running sudo pkill nginx
, wait 5 seconds (Or however long you specified), and then run sudo systemctl status nginx
to see if Nginx was restarted.
Troubleshooting
If Nginx fails to start, the output of sudo systemctl status nginx
should show some sort of error. If it doesn’t, then check the error log under /var/log/nginx/error.log
.
If Nginx appears to be running just fine, but you’re still unable to connect, check to make sure that port 80 is permitted in your firewall.
Installing MariaDB
Run the following command to install the MariaDB client and server:
sudo apt install mariadb-server mariadb-client
Start MariaDB:
sudo systemctl start mariadb
Check its status:
sudo systemctl status mariadb
And if it’s running and there’s no errors, run the post installation security script:
sudo mysql_secure_installation
Select yes (Or just press enter) for all of the steps and follow the prompts.
Finally, allow MariaDB to run at startup:
sudo systemctl enable mariadb
Installing PHP7.4
Depending on what you’re trying to run, you might need different PHP extensions than what I’ll list. The following command will install PHP7.4 along with the extensions that I use for WordPress:
sudo apt install php7.4 php7.4-bz2 php7.4-cli php7.4-common php7.4-curl php7.4-fpm php7.4-gd php7.4-intl php7.4-json php7.4-mbstring php7.4-mysql php7.4-opcache php7.4-readline php7.4-xml php7.4-zip php7.4-imagick
Start PHP:
sudo systemctl start php7.4-fpm
Check its status:
sudo systemctl status php7.4-fpm
And if it’s running, then enable it to run at startup:
sudo systemctl enable php7.4-fpm
Installing phpMyAdmin (Optional)
phpMyAdmin is very useful for managing MariaDB (Or any other compatible database), so I would recommend installing it. However, like some of the other tools I recommended, only do this if you can properly firewall it off. If it’s not properly firewalled off, than an attacker could easily gain access to your MariaDB database, thus the data of whatever relies on it.
To start the installation process of phpMyAdmin, run the following command:
sudo apt install phpmyadmin
During installation, various prompts will be displayed. The first prompt will ask you what web server should automatically be configured, but if you’re using Nginx like me, press the tab key, then press enter:
The second prompt will ask you if you want to use dbconfig-common to automatically configure the database. Press enter to select yes:
The last prompt will ask you to enter a password for the phpmyadmin user. Enter a password, then press enter. You’ll be prompted again to confirm your password:
Create an Nginx Server Block
Since the phpMyAdmin setup didn’t include an option to automatically configure Nginx, we’ll have to do it ourselves. Create a file in /etc/nginx/conf.d/phpmyadmin.conf using your favorite text editor, and add the following lines:
server {
#Change the highlighted port numbers.
listen 1234;
#The line below is optional. You don't need it if your server doesn't support IPv6.
listen [::]:1234;
server_name _;
root /usr/share/phpmyadmin/;
index index.php index.html index.htm index.nginx-debian.html;
access_log /var/log/nginx/phpmyadmin_access.log;
error_log /var/log/nginx/phpmyadmin_error.log;
location / {
try_files $uri $uri/ /index.php;
}
location ~ ^/(doc|sql|setup)/ {
deny all;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
include snippets/fastcgi-php.conf;
}
location ~ /\.ht {
deny all;
}
}
Run the following command to have Nginx test your config file:
sudo nginx -t
If there’s no errors, restart Nginx:
sudo systemctl restart nginx
Access phpMyAdmin by typing in your_ip_address:your_port_number
into your web browser. If everything works correctly, then you should see the phpMyAdmin login screen. You can either use root
as the username with the password that you chose while installing MariaDB, or use phpmyadmin
as the username and the password that you chose while installing phpmyadmin. You can also use the login of any other database user that you might have.
If you’ve decided to follow this post and you’ve followed everything correctly (Or I didn’t screw up), then congratulations. You should now have Nginx, MariaDB, and PHP7.4 installed and ready to host your dynamic website. Read part 2 where I’ll show you how to install WordPress on top of this LEMP stack. I hope that you enjoyed reading this post, and hopefully you learned something too. If you have any problems, feel free to leave a comment, and I’ll try my best to help you (I can’t guarantee anything though).
References
Here’s all of the references I used, and two of them are arguably better tutorials.
LinuxBabe’s tutorial on how to install a LEMP stack on Ubuntu