How to Install WordPress with LAMP Stack on Debian 11 Bullseye

WordPress is the most dominant content management system written in PHP, combined with MySQL or MariaDB database. You can create and maintain a site without prior web development or coding knowledge. The first version of WordPress was created in 2003 by Matt Mullenweg and Mike Little and is now used by 70% of the known web market, according to W3Tech. WordPress comes in two versions: the free open source WordPress.org and WordPress.com, a paid service that starts at $5 per month up to $59. Using this content management system is easy and often seen as a stepping stone for making a blog or similar featured site.

In the following tutorial, you will learn how to install self-hosted WordPress using the latest LAMP Stack – Apache, MariaDB, and PHP versions available on Debian 11 Bullseye.

Prerequisites

  • Recommended OS: Debian 11 Bullseye
  • User account: A user account with sudo or root access.
  • Required Packages: listed throughout tutorial

Update Operating System

Update your Debian operating system to make sure all existing packages are up to date:

sudo apt update && sudo apt upgrade -y

The tutorial will be using the sudo command and assuming you have sudo status.

To verify sudo status on your account:

sudo whoami

Example output showing sudo status:

[joshua@debian~]$ sudo whoami
root

To set up an existing or new sudo account, visit our tutorial on Adding a User to Sudoers on Debian.

To use the root account, use the following command with the root password to log in.

su

Install CURL & UNZIP Package

The tutorial makes use of the curl and unzip command during certain parts. To make sure this is installed, run the following command in your terminal:

sudo apt install curl unzip -y

Install Latest Apache – (LAMP Stack)

To kickstart the LAMP stack installation, you will need to install the Apache 2 (HTTPD) webserver. By default, this is featured on Debian 11’s default repository. However, this can often be lagging in updates unless an urgent security update has been pushed.

To maintain the most up-to-date Apache web server, install the package from the  Ondřej Surý’s repository. Many Ubuntu users would know his PPA, and you can do the same in Debian.

In your terminal, use the following command to begin the installation.

curl -sSL https://packages.sury.org/apache2/README.txt | sudo bash -x

Now that you have installed the Apache repository and updated the repository list, install Apache2 with the following:

sudo apt install apache2

Example output:

How to Install WordPress with LAMP Stack on Debian 11 Bullseye

TYPE Y, then press the ENTER KEY to proceed and complete the installation.

Next, confirm the installation was successful by confirming the version.

sudo apache2 -v

Example output:

Server version: Apache/2.4.52 (Debian)
Server built:   2021-12-20T21:09:16

Now, make sure Apache is running by using the systemctl command:

systemctl status apache2

Example output:

How to Install WordPress with LAMP Stack on Debian 11 Bullseye

If Apache is not activated, to start the webserver application, use the following command:

sudo systemctl enable apache2 --now

Example output if successful:

Synchronizing state of apache2.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable apache2

Next, visit the page located at your server’s local IP address or external into your browser.

Example landing page:

How to Install WordPress with LAMP Stack on Debian 11 Bullseye

If you cannot reach this page without using UFW Firewall, use the following command to allow port 80.

sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT

Optional. Configure UFW Firewall for Apache

After installing Apache 2 web server, you will need to modify the UFW rules if you have UFW installed. To allow outside access to the default web ports. Luckily, during the installation, Apache registers itself with UFW to provide a few profiles that can be used to enable or disable access, making it easy and quick to configure.

If you would like to install the UFW firewall, run the following command:

sudo apt install ufw -y

Once UFW is installed, enable UFW to start and be active on system boot.

sudo ufw enable

Next, list the application profiles to see the Apache profiles that are available by the following command:

sudo ufw app list

Example output:

Available applications:
  Apache
  Apache Full
  Apache Secure

From the output above, you have three profile options to choose from. To break it down, Apache runs on port 80 (HTTP), Apache Secure runs on port 443 (HTTPS), and Apache Full is a combination of allowing both. The most common is either Apache Full or Apache Secure.

For the tutorial, since we have not set up SSL, we will enable (Apache) profile with the following command:

sudo ufw allow 'Apache'

Example output:

Rule added
Rule added (v6)

As above, the rules have been added for both IPV4 and IPV6. Later on, you can disable this profile and enable secure only or disable the Apache rule and use the Apache Full rule instead.

Install Latest MariaDB – (LAMP Stack)

The tutorial will recommend installing MariaDB constantly over MySQL due to performance more than anything else.

First, import the official MariaDB repository, 10.6 is the current stable, but 10.7 is the new version out but maybe not as stable.

Option 1 – Import MariaDB 10.6:

curl -LsS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash -s -- --mariadb-server-version=10.7 --skip-maxscale --skip-tools

Option 2 – Import MariaDB 10.7:

curl -LsS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash -s -- --mariadb-server-version=10.7 --skip-maxscale --skip-tools

Once you have picked a version, update your APT repository.

sudo apt update

Install MariaDB on Debian Desktop or Server

To install MariaDB, you will need to install the client and the server packages. This can be done as follows:

sudo apt install mariadb-server mariadb-client

Example output (MariaDB 10.7):

How to Install WordPress with LAMP Stack on Debian 11 Bullseye

Type Y and then press the ENTER KEY to proceed with the installation.

Confirm the installation of MariaDB by checking the version and build:

mariadb --version

Example output:

mariadb  Ver 15.1 Distrib 10.7.1-MariaDB, for debian-linux-gnu (x86_64) using readline EditLine wrapper

Remember, this is just an example. You can easily change the MariaDB as described at the start of the section.

Check MariaDB Service Status

Now you have installed MariaDB, and you can verify the status of the database software by using the following systemctl command:

systemctl status mariadb

Example:

How to Install WordPress with LAMP Stack on Debian 11 Bullseye

By default, you will find MariaDB status to be activated. If not, start MariaDB, use the following command:

sudo systemctl start mariadb

To stop MariaDB:

sudo systemctl stop mariadb

To enable MariaDB on system startup:

sudo systemctl enable mariadb

To disable MariaDB on system startup:

sudo systemctl disable mariadb

To restart the MariaDB service:

sudo systemctl restart mariadb

Secure MariaDB with Security Script

When installing MariaDB fresh, default settings are considered weak by most standards and cause concern for potentially allowing intrusion or exploiting hackers. A solution is to run the installation security script with the MariaDB installation.

First, use the following command to launch the (mysql_secure_installation):

sudo mysql_secure_installation

Next, follow below:

  • Setting the password for root accounts.
  • Removing root accounts that are accessible from outside the local host.
  • Removing anonymous-user accounts.
  • Removing the test database, which by default can be accessed by anonymous users.

Note, you use (Y) to remove everything.

Example:

[joshua@debian ~]$ sudo mariadb-secure-installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none): 
OK, successfully used password, moving on...

Setting the root password or using the unix_socket ensures that nobody
can log into the MariaDB root user without the proper authorisation.

You already have your root account protected, so you can safely answer 'n'.

Switch to unix_socket authentication [Y/n] Y <---- Type Y then press the ENTER KEY.
Enabled successfully!
Reloading privilege tables..
 ... Success!


You already have your root account protected, so you can safely answer 'n'.

Change the root password? [Y/n] Y <---- Type Y then press the ENTER KEY.
New password: 
Re-enter new password: 
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y <---- Type Y then press the ENTER KEY.
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y <---- Type Y then press the ENTER KEY.
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y <---- Type Y then press the ENTER KEY.
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y <---- Type Y then press the ENTER KEY.
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

Install Latest PHP – (LAMP Stack)

The last part of the tutorial will be to install PHP, which is the backend that communicates between Apache and MariaDB, the middle man. PHP 8.0 is becoming relatively stable, and the newer versions of PHP 8.1 are now available.

The tutorial will focus on importing Ondřej Surý’s latest PHP version, the maintainer for Debian PHP. This is always up to date even when new PHP versions are dropped.

Import Ondřej Surý PHP Repository

In your terminal, use the following command to begin the installation.

curl -sSL https://packages.sury.org/php/README.txt | sudo bash -x

This command will install the PHP repository and update your APT repository.

Example – Install PHP 8.0 or 8.1 with Apache Option

The option below will install either PHP 8.0 or 8.1. The exact process can be used to install the older stable 7.4 or, in the future, 8.2 8.3 and PHP 8.4.

The tutorial will cover both native PHP Apache module installation along the PHP-FPM. For most users, the native module is recommended over PHP-FPM.

Install Apache Module

To install the Apache module, enter the following command.

PHP 8.0:

sudo apt install php8.0 libapache2-mod-php8.0 php8.0-cli php8.0-common php8.0-mbstring php8.0-xmlrpc php8.0-soap php8.0-gd php8.0-xml php8.0-intl php8.0-mysql php8.0-cli php8.0-ldap php8.0-zip php8.0-mcrypt php8.0-curl php8.0-opcache php8.0-readline php8.0-xml php8.0-gd

PHP 8.1:

sudo apt install php8.1 libapache2-mod-php8.1 php8.1-cli php8.1-common php8.1-mbstring php8.1-xmlrpc php8.1-soap php8.1-gd php8.1-xml php8.1-intl php8.1-mysql php8.1-cli php8.1-ldap php8.1-zip php8.1-mcrypt php8.1-curl php8.1-opcache php8.1-readline php8.1-xml php8.1-gd

Example output:

How to Install WordPress with LAMP Stack on Debian 11 Bullseye

Type Y, then press the ENTER KEY to proceed.

The module should be loaded automatically after the installation. However, if you need to load the module, use the following command.

sudo a2enmod php{version}

Example:

sudo a2enmod php8.1

Example output:

How to Install WordPress with LAMP Stack on Debian 11 Bullseye

As above, PHP 8.1 was already enabled, but these commands will come in handy in the future.

Once installation is complete, restart your Apache server to load the new PHP module.

sudo systemctl restart apache2

Note, to disable the module to re-enable another version, for instance swapping between 8.0 and 8.1, and you would first install the PHP packages and use the following.

Disconnect PHP 8.0 using the following command.

sudo a2dismod php8.0

Then enable PHP 8.1 module.

sudo a2enmod php8.1

Restart your Apache server to load the new PHP module.

sudo systemctl restart apache2

Make sure the PHP Apache module is disabled if you are going to use the following method of installing PHP-FPM with Apache.

Alternative Option – Install Apache PHP-FPM

Install Apache with PHP-FPM

PHP-FPM (an acronym of FastCGI Process Manager) is a hugely popular alternative PHP (Hypertext Processor) FastCGI implementation.

To install PHP-FPM with the following commands.

Option 1 – PHP-FPM 8.0:

sudo apt install php8.0-fpm libapache2-mod-fcgid php8.0-cli php8.0-common php8.0-mbstring php8.0-xmlrpc php8.0-soap php8.0-gd php8.0-xml php8.0-intl php8.0-mysql php8.0-cli php8.0-ldap php8.0-zip php8.0-mcrypt php8.0-curl php8.0-opcache php8.0-readline php8.0-xml php8.0-gd

Option 2 – PHP-FPM 8.1:

sudo apt install php8.1-fpm libapache2-mod-fcgid8.1 php8.1-cli php8.1-common php8.1-mbstring php8.1-xmlrpc php8.1-soap php8.1-gd php8.1-xml php8.1-intl php8.1-mysql php8.1-cli php8.1-ldap php8.1-zip php8.1-mcrypt php8.1-curl php8.1-opcache php8.1-readline php8.1-xml php8.1-gd

Note, by default, PHP-FPM is not enabled for Apache.

Example with PHP-FPM 8.1:

How to Install WordPress with LAMP Stack on Debian 11 Bullseye

Now enable it by the following command.

Example with PHP-FPM 8.1:

sudo a2enmod proxy_fcgi setenvif && sudo a2enconf php8.1-fpm

Lastly, restart Apache.

sudo systemctl restart apache2

Verify that PHP-FPM is working:

sudo systemctl status php8.1-fpm

Example output:

How to Install WordPress with LAMP Stack on Debian 11 Bullseye

To disable PHP-FPM for Apache, use the following command example with PHP-FPM 8.1 as the example again.

sudo a2dismod proxy_fcgi setenvif && sudo a2disconf php8.1-fpm

Next, restart the service.

sudo systemctl restart apache2

Now you can re-enable the PHP module Apache extension.

sudo a2enmod php8.1

Install WordPress Backend

Download WordPress

Visit the WordPress.org download page and scroll down to find the latest.zip download link. Then using the wget command, download the file.

wget https://wordpress.org/latest.zip

Create Folder Structure for WordPress

Now you have the archive downloaded, proceed to unzip it and move it to your www directory.

Create the directory for WordPress:

sudo mkdir -p /var/www/html/wordpress

Unzip WordPress to the www directory:

sudo unzip latest.zip -d /var/www/html/

You must set the directory owner permissions to WWW, or else you will have trouble with WordPress write permissions.

Set chown permission (important):

sudo chown -R www-data:www-data /var/www/html/wordpress/

Set chmod permission (important):

sudo find /var/www/html/wordpress -type d -exec chmod 755 {} \;
sudo find /var/www/html/wordpress -type f -exec chmod 644 {} \;

Create Database for WordPress

WordPress requires a database to run hence why you had to install MariaDB. Before continuing further, you need to create a database for WordPress using MariaDB. First, bring up the terminal console and type the following.

Bring up MariaDB shell as root:

sudo mariadb -u root

Second alternative command:

sudo mysql -u root

Next, create the database. This can be any name you want. For the guide, you will name it “WORDPRESSDB.”

Create WordPress database:

CREATE DATABASE WORDPRESSDB;

After the database has been created, you should create a new WordPress site user.

This is done as a security measure, so every database has a different user. If one username is compromised, the attacker doesn’t access all the other website’s databases.

Create the WordPress database user:

CREATE USER 'WPUSER'@localhost IDENTIFIED BY 'PASSWORD';

Replace WPUSER and PASSWORD with whatever username or password you desire. Do not copy and paste the default user/pass above for security purposes.

Now assign the newly created user access to the WordPress website database only below.

Assign database to the created WordPress user account:

GRANT ALL PRIVILEGES ON WORDPRESSDB.* TO WPUSER@localhost IDENTIFIED BY 'PASSWORD';

With all database configuration settings complete, you need to flush the privileges to take effect and exit.

Flush Privileges:

FLUSH PRIVILEGES;

Exit MariaDB:

EXIT;

WordPress Configuration Setup

You need to set some settings in the wp-config-sample.php file. Below, you will see how to rename the sample file and enter the required information.

First, rename the configuration file.

Go to the WordPress directory:

cd /var/www/html/wordpress/

Rename configuration file:

sudo mv wp-config-sample.php wp-config.php

Using a text editor, bring up the newly renamed wp-config.php file. In our example, we will use nano.

sudo nano wp-config.php

Next, you will enter the database name, user account with a password, host IP address if different than localhost.

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */ 
define( 'DB_NAME', 'wordpressdb' );
/* MySQL database username */ 
define( 'DB_USER', 'wpuser1' );
/* MySQL database password */
define( 'DB_PASSWORD', 'YOUR PASSWORD' );
/* MySQL hostname, change the IP here if external DB set up */ 
define( 'DB_HOST', 'localhost' );
/* Database Charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8' );
/* The Database Collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );

While you are in this file, adding extra settings will make your WordPress easier to manage, such as direct file saving instead of using FTP and increased memory size limits.

##Save files direct method##
 define( 'FS_METHOD', 'direct' );

##Increase memory limit, 256MB is recommended##
 define('WP_MEMORY_LIMIT', '256M');

##change Wordpress database table prefix if wanted##
 $table_prefix = 'wp_';

Set WordPress Security Salt Keys

It would be best to visit WordPress secret-key API to generate your own. The address salt key generator can be found at https://api.wordpress.org/secret-key/1.1/salt/. Replace the example lines with the codes from the generator.

DO NOT COPY THE EXAMPLE BELOW, AND IT’S JUST FOR REFERENCE.

define('AUTH_KEY',         '<3yfS7/>%m.Tl^8Wx-Y8-|T77WRK[p>(PtH6V]Dl69^<8|K86[_Z},+THZ25+nJG');
define('SECURE_AUTH_KEY',  'bN#Qy#ChBX#Y`PE/_0N42zxgLD|5XpU[mu.n&:t4q~hg<UP/b8+xFTly_b}f]M;!');
define('LOGGED_IN_KEY',    'owpvIO-+WLG|,1)CQl*%gP1uDp}s(jUbYQ[Wm){O(x@sJ#T}tOTP&UOfk|wYsj5$');
define('NONCE_KEY',        '8=Vh|V{D<>`CLoP0$H!Z3gEqf@])){L+6eGi`GAjV(Mu0YULL@sagx&cgb.QVCbi');
define('AUTH_SALT',        '%TX*X$GE-;|?<-^(+K1Un!_Y<hk-Ne2;&{c[-v!{q4&OiJjQon /SHcc/:MB}y#(');
define('SECURE_AUTH_SALT', '=zkDT_%}J4ivjjN+F}:A+s6e64[^uQ<qNO]TfHS>G0elz2B~7Nk.vRcL00cJoo7*');
define('LOGGED_IN_SALT',   '{$-o_ull4|qQ?f=8vP>Vvq8~v>g(2w12`h65ztPM(xo!Fr()5xrqy^k[E~TwI!xn');
define('NONCE_SALT',       'a1G(Q|X`eX$p%6>K:Cba!]/5MAqX+L<A4yU_&CI)*w+#ZB+*yK*u-|]X_9V;:++6');

Apache Virtual Host Configuration

Now, you are almost ready to install WordPress through the WEB UI. However, you need to configure your virtual host now.

First, create a new server configuration file with the following command replacing the example with your domain name,

sudo nano /etc/apache2/sites-available/example.com.conf

Below is an example only.

NOTE: Make sure to change www.example.com and example.com and the root path.

<VirtualHost *:80>       
        ServerName www.example.com
        ServerAlias example.com

        DocumentRoot /var/www/html/wordpress/

        #This enables .htaccess file, which is needed for WordPress Permalink to work. 
        <Directory "/var/www/html/wordpress/">
             AllowOverride All
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/wordpress.error.log
        CustomLog ${APACHE_LOG_DIR}/wordpress.access.log combined
</VirtualHost>

Next, you will need to enable the Apache configuration file from “sites-available”. To do this, you will create a symlink to “sites-enabled” as follows.

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

Make sure to replace “example.conf” with your configuration file name.

Next, run a dry test of your virtual host using the following command.

sudo apache2ctl configtest

Example output:

Syntax OK

As above, the virtual host configuration has no errors, so you can now enable your virtual host.

sudo a2ensite example.com.conf

Lastly, restart your Apache service.

sudo systemctl restart apache2

Situational Option – PHP-FPM Configuration

Skip this part IF YOU ARE NOT USING PHP-FPM.

Before moving onto the web UI installation part, you should adjust your PHP for optimal use for WordPress. These settings are more of a guide, and you can increase, decrease as you see fit.

First, bring up your php.ini configuration file. Note that your location may differ depending on your PHP version number.

sudo nano /etc/php/{PHP-VERSION NUMBER}/fpm/php.ini

PHP 8.0 PHP-FPM EXAMPLE:

sudo nano /etc/php/8.0/fpm/php.ini

WordPress media files can be pretty significant, and the default can be too low. You can increase this to roughly what you think your most extensive file size will be. Find the following lines below and adjust to your needs.

##increase upload max size recommend 50 to 100mb## 
 upload_max_filesize = 100MB

##increase post max size recommend 50 to 100mb##
 post_max_size = 100MB

## increase max execution time recommend 150 to 300##
 max_execution_time = 300

## increase GET/POST/COOKIE input variables recommend 5000 to 10000##
max_input_vars = 10000

## increase memory limit recommend 256mb or 512mb##
memory_limit = 256M

For Apache PHP-FPM users, use the following command.

sudo systemctl restart php{version}-fpm

Install WordPress Frontend

Now that all the backend setup and configuration are complete, you can go to your domain and begin installing.

##go to installation address##
 https://www.yoursite.com
##alternative url##
 https://www.yoursite.com/wp-admin/install.php

The first page you will see is creating a username and password and some site details. This will be your future admin login account, and you can change this later on as well.

How to Install WordPress with LAMP Stack on Debian 11 Bullseye

If you are building a website, enabling “strongly discourage search engines from indexing” prevents Google or Bing or any other “good/reputable search engine bot” from indexing a WIP website. Once finished, you will come to the next screen with a login.

How to Install WordPress with LAMP Stack on Debian 11 Bullseye

Congratulations, you have successfully installed the latest version of WordPress with LAMP Stack.

Optional – Secure Apache with Let’s Encrypt SSL Free Certificate

Ideally, you would want to run your Apache on HTTPS using an SSL certificate. The best way to do this is to use Let’s Encrypt, a free, automated, and open certificate authority run by the nonprofit Internet Security Research Group (ISRG).

First, install the certbot package as follows:

sudo apt install python3-certbot-apache -y

Once installed, run the following command to start the creation of your certificate:

sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --email you@example.com -d www.example.com

This ideal setup includes force HTTPS 301 redirects, a Strict-Transport-Security header, and OCSP Stapling. Just make sure to adjust the e-mail and domain name to your requirements.

Now your URL will be HTTPS://www.example.com instead of HTTP://www.example.com.

If you use the old HTTP URL, it will automatically redirect to HTTPS.

Do not forget to change this in the Settings area of your website with the HTTP to HTTPS.

Comments and Conclusion

WordPress offers a fantastic ability to create quick websites with templates and plugins, and the plugin store hosts a tremendous amount of options. However, to unlock the full potential of most themes and add-ons, they are all paywall, but most are affordable.

Self-hosting WordPress is quite a bit of fun. However, making sure you keep up with security and updating is essential. WordPress is the most targetted CMS on earth by attackers, and your site will, in its first day without even being listed will be scanned for exploits, and brute force attempts will begin.



Follow LinuxCapable.com!

Like to get automatic updates? Follow us on one of our social media accounts!