Setup LEMP on Debian 10 (Buster) with NFTables

Debian 10 is out! I discovered this after running into a problem on a new Debian 9.8 distro. Decided to spring for 10 for my LEMP server needs. Debian 10 also ships with NFTables which replaces IPTables – Something I didn’t know until neck deep in setup.

The order I execute these steps isn’t the only way to do it. My goal is to take you from a fresh server install to installing a WordPress site with an SSL certificate. So the order I execute reflects this.

Ready? Let’s get on with it!

Update Your Server

*Note: This post assumes you have just loaded Debian Buster on a server or VPS. Get to your command line via SSH (terminal for Mac) and type:

apt update && apt upgrade

*Note: Normally, you’ll always type in sudo and then the command, as you won’t be signed in as the root user. This is assumed.

Set Server’s DNS Name

Now make sure you’ve entered your server’s fully qualified DNS name into your server’s hosts file. Obviously this needs to be setup in DNS as well.

nano /etc/hosts (no trailing slash)

The format should look similar to:    servername

Install Nginx

As you know, LEMP servers using nginx vs apache. As of April 2019, Debian 10 ships with nginx 1.14.2.

apt install nginx

Use nginx -v to see your version after installation.

Remove Apache

I like to get Apache2 off my Debian 10 server. Why? Every once in awhile, it can accidentally get loaded on a server reboot, and you’ll beat your head on the desk trying to figure out why nginx won’t load.

service apache2 stop
apt-get remove apache2*
apt-get autoremove
apt-get autoclean
rm -rf /etc/apache2 /var/lib/apache2 /var/lib/apache2

Be sure to run all of those commands (sudo assumed) or the rebellious Apache2 will raise it’s ugly head later on. If you still have problems with Apache2 showing up, use these commands:

apt-get purge apache2
apt-get remove --purge apache2 apache2-utils

Install Maria DB Server

If you’re new to later versions of Debian (or Ubuntu) you may not have used Maria yet. Don’t worry – it’s a beautiful drop in replacement for MySQL. All the commands you’re used to using still work.

apt install mariadb-server

Secure Maria DB Server

Running the secure installation script allows you to tighten up the default Maria install for your Debian LEMP server by setting a root password, removing test users and disabling remote access. Remote access does not mean an SSH connection, as that is signing on as if local.


Set the root password (hit enter as there is none set for Maria yet). Answer ‘yes’ to the other remaining questions. Easy as pie.

Install PHP & Libraries

If you use WordPress, you know they’re recommending php 7.3 as the minimum version. Maybe still a little bleeding edge, but I’ve not had any issues, and my WordPress site does some complicated stuff. PHP 7.3 is the current stable as of April 2019. Type php -v to show the version after install.

A handful of other common libraries you’ll need, including support for Maria DB and PHP-FPM (FastCGI Process Manager) :

apt install php-fpm php-cli php-mysql php-zip php-gd php-curl php-xml php7.3-mbstring

Configure NFTables (Firewall)

You’ve probably heard of iptables — It’s been the go to firewall for Linux for many moons. But Debian Buster is now shipping with nfttables as the replacement to iptables. NFTables is a different animal, but more powerful. When you first load your VPS, nothing is blocked, so you need to do this quickly.

This will list the current ruleset:

nft list ruleset

If that command doesn’t produce a result, your particular Debian 10 distro probably has iptables instead. Just use apt remove to remove and then apt install.

apt remove iptables
apt install nftables

Update NFTables Config

Use an sFTP client (you can also you nano) and edit the /etc/nftables.conf file. If you’re a MAC user, ForkLift cannot be beat. Trust me. It’s the best sFTP client out there.

The link below contains a sample starter configuration that will allow http, https and ssh ports while blocking everything else:

Load New Configuration

Type the following:


Now your config is live. If you use the command at the top again, you’ll see the updated ruleset.

Make New Ruleset Persistent

Type the following commands in to make your NFTables config persistent when your Debian 10 server is rebooted:

systemctl enable nftables
systemctl start nftables
systemctl status nftables

You’re good to go! There’s a lot more that can be done with NFTables, but now your server has basic protection. Also, if you change the nftables.conf file, use these words to tell Debian Buster to load the new config:

nft flush ruleset

Now type nft list ruleset to show the new config. You should see your new rules listed.


Setup Website with Nginx on Debian 10

Now let’s get that first nginx-based website rocking and rolling. We’ll prep the server for a WordPress site, which will obviously use both nginx and Maria DB.

Create Site Folder & Download WordPress

mkdir -p /var/www/

Go to and download the WordPress installation files. Unzip them, and then copy the contents to the public_html folder created above.

Change Ownership to WWW-DATA

Once you’ve copied the WordPress files to your public_html folder, use the following command to ensure the www-data user has ownership:

chown -R www-data:www-data /var/www/

Create Nginx Server Block

nano /etc/nginx/sites-available/default

Add a space or any minor change, and then hit Ctrl-X to save the file. Follow the prompts to save as a different filename. Name the file the name of your website, including the TLD. Example:

Enable the Website

Once your server block file is ready, you must enable it. The command below places a link to your new server block file in the /etc/nginx/sites-enabled folder.

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

*Note: You’ll also want to remove default from the sites enabled folder.

Verify Website Configuration

At the command line type:

service nginx restart

When you hit enter, it should take you to a blank command line. If there are any problems, you’ll see an error message. The best way to get the scoop on nginx errors is to open the log. This can be found at /var/log/nginx/error.log.

Enable SSL with Let’s Encrypt

Obtaining an SSL certificate and installing it for your website used to be a royal pain. Not it’s easy thanks to Let’s Encrypt and their official server client: Certbot. Back at your command line type:

apt-get install certbot python-certbot-nginx

Now let’s add an SSL certificate to your new website. I do this before installing WordPress so the installation configures the site for https:// right out the door.

certbot --nginx (use TWO dashes before nginx)

The first time you do this it’s going to ask you a couple questions like admin email, etc. After that completes, it will display the available nginx server blocks on your Debian 10 server. Select both the www and non-www names via their number and a comma. Next you’ll be asked about redirect – You want Option 2.

More on certbot:

*Note: DNS for the domain name you’re setting up must be pointed to your server for this to work. Try and ping your domain name from the server command line to ensure DNS is working.

Create WordPress Database

As you know, WordPress needs a database to run from. Let’s jump into Maria DB server and get a database ready!

mysql -u root -p

Enter the password you set in the MySQL secure installation step from above.

create database yourdbname;

*Note: All MySQL/Maria DB commands must end with a semicolon.

Now that your database is created, you need to assign rights to a user. The command below grants access to your new database to a username you create (make one up here) identified by a password (make this difficult and jot it down as you’ll need this when setting up WordPress).

Grant all on yourdbname.* to 'yourdbuser' identified by 'yourpassword';
Flush privileges:]flush privileges;

Now type quit to exit Maria DB.

Set File Upload Size

Before we kick of the WordPress installation, you’ll want to set a file upload size in two configuration files on your Debian Buster server:


You’ll find this file in /etc/nginx/. Add the line below to the http area. Restart nginx after saving to verify everything was done correctly.

client_max_body_size 25M;


Sometimes there can be more than one php.ini on a server. The one you need to edit for PHP-FPM on your Debian 10 server is found at /etc/php/7.3/fpm/php.ini. The upload max filesize line will already be in this file. You just need to update it.

upload_max_filesize = 25M

Now restart your PHP-FPM service:

service php7.3-fpm restart

Install WordPress

You’ve done it! You’ve setup LEMP on Debian Buster. BOOYAH!

If you’re familiar with WordPress, you know that simply going to your domain name in a browser will kick off the install. I won’t go into detail on that here, but it’s pretty straight forward.

Bonus Configuration Files

I frequently use 8GB VPS setups at Linode (highly recommend them by the way). If you’re doing the above, here are configuration files that will save you some time beating your head against the wall. Trust me – the wrong configuration can make your server take 10 hours to do a task it could do in 40 seconds — I’m not kidding.

Just download this zip file, and replace the files on your new Debian 10 server. These adjust nginx, php-fpm and maria db. These assume php v7.3.

Configuration Files