How to Install WordPress with Apache on Debian

WordPress powers millions of websites worldwide, from personal blogs to enterprise applications. Whether you need to host a business website, create an online store with WooCommerce, or build a portfolio site, WordPress provides the flexibility to accomplish these goals. By the end of this guide, you will have a fully functional WordPress installation running on a complete LAMP stack (Linux, Apache, MariaDB, PHP) with SSL encryption from Let’s Encrypt.

This guide covers installing WordPress with Apache, MariaDB, and PHP on Debian. Additionally, you will learn how to configure SSL certificates for HTTPS, set up UFW firewall rules, and troubleshoot common WordPress issues including redirect loops and PHP session errors.

Each Debian version includes different default PHP and MariaDB versions. Debian 13 (Trixie) uses PHP 8.4 and MariaDB 11.8, Debian 12 (Bookworm) uses PHP 8.2 and MariaDB 10.11, and Debian 11 (Bullseye) uses PHP 7.4 and MariaDB 10.5. The commands in this guide use version-specific package names where necessary.

Update Debian Before Installation

First, update your package index to ensure you install the latest available versions of all components:

sudo apt update && sudo apt upgrade -y

Install Apache on Debian

Apache serves as the first essential component of the LAMP stack. Therefore, to begin, install Apache with the following command:

sudo apt install apache2 -y

The -y flag automatically confirms the installation prompt. However, for those interested in a newer Apache version from a third-party repository, refer to our guide on upgrading Apache on Debian.

Verify Apache Installation

Subsequently, after installation completes, confirm Apache installed successfully by checking the version:

apache2 -v

Specifically, the output displays your installed Apache version:

Server version: Apache/2.4.x (Debian)
Server built:   2025-xx-xx

Next, verify that the Apache service is running:

systemctl status apache2

As illustrated, the output confirms Apache is active and running:

● apache2.service - The Apache HTTP Server
     Loaded: loaded (/lib/systemd/system/apache2.service; enabled; preset: enabled)
     Active: active (running) since xxx
       Docs: https://httpd.apache.org/docs/2.4/
    Process: 123 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
   Main PID: 456 (apache2)
      Tasks: 55 (limit: xxxx)
     Memory: 12.3M
        CPU: 50ms
     CGroup: /system.slice/apache2.service
             ├─456 /usr/sbin/apache2 -k start
             ├─457 /usr/sbin/apache2 -k start
             └─458 /usr/sbin/apache2 -k start

Conversely, if Apache is not running, enable and start the service:

sudo systemctl enable apache2 --now

Test Apache in Browser

Next, to confirm Apache is serving pages, open a web browser and navigate to your server’s IP address:

http://127.0.0.1
http://localhost

However, if you cannot access the page, you may need to configure firewall rules. The UFW firewall section later in this guide covers the complete setup.

Install MariaDB on Debian

MariaDB serves as the database backend for WordPress. Moreover, since Debian includes MariaDB by default, installation is straightforward. For those who prefer MySQL instead, consult our guide on installing MySQL 8.0 on Debian. Alternatively, to install newer MariaDB versions beyond the distribution defaults, follow our MariaDB installation guide.

Begin by installing the MariaDB server and client packages:

sudo apt install mariadb-server mariadb-client -y

Verify MariaDB Installation

Subsequently, once installation completes, verify MariaDB is working correctly:

mariadb --version

For instance, the output displays your MariaDB version (which varies by Debian release):

mariadb  Ver 15.1 Distrib 10.x.x-MariaDB, for debian-linux-gnu (x86_64) using  EditLine wrapper

Following that, confirm the MariaDB service is running:

systemctl status mariadb

The status output confirms MariaDB is active and running:

● mariadb.service - MariaDB 10.x.x database server
     Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; preset: enabled)
     Active: active (running) since xxx
       Docs: man:mariadbd(8)
             https://mariadb.com/kb/en/library/systemd/
    Process: 123 ExecStartPre=/usr/bin/install ... (code=exited, status=0/SUCCESS)
    Process: 456 ExecStartPre=/bin/sh -c systemctl unset-environment ... (code=exited, status=0/SUCCESS)
    Process: 789 ExecStartPre=/bin/sh -c ... (code=exited, status=0/SUCCESS)
    Process: 999 ExecStart=/usr/sbin/mariadbd ... (code=exited, status=0/SUCCESS)
   Main PID: 1000 (mariadbd)
     Status: "Taking your SQL requests now..."

If MariaDB is not running, enable and start the service:

sudo systemctl enable mariadb --now

Use sudo systemctl stop mariadb to stop the service, sudo systemctl start mariadb to start it, and sudo systemctl restart mariadb to restart after configuration changes.

Secure MariaDB Installation

Fresh MariaDB installations include default configurations that may expose your system to unauthorized access. To address this, MariaDB provides a security script to harden these settings. Therefore, run the script with the following command:

sudo mysql_secure_installation

During the script execution, you will encounter prompts for the following security measures:

  • Set a password for the root accounts
  • Remove root accounts accessible from remote hosts
  • Remove anonymous user accounts
  • Remove the default test database

Consequently, for production servers, answer (Y) to all prompts to implement the recommended security enhancements:

$ sudo mysql_secure_installation

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

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

Switch to unix_socket authentication [Y/n] Y
Enabled successfully!

Change the root password? [Y/n] Y
New password: [Enter secure password]
Password updated successfully!

Remove anonymous users? [Y/n] Y
 ... Success!

Disallow root login remotely? [Y/n] Y
 ... Success!

Remove test database and access to it? [Y/n] Y
 ... Success!

Reload privilege tables now? [Y/n] Y
 ... Success!

All done!  Your MariaDB installation should now be secure.

Install PHP on Debian

PHP processes dynamic content and connects WordPress to MariaDB. Notably, each Debian version includes a different default PHP version. For specific versions or custom installations from the Sury repository, see our PHP installation guide for Debian.

Next, install PHP with the Apache module and extensions required by WordPress. Then, choose the command matching your Debian version:

For Debian 13 (Trixie), the default is PHP 8.4:

sudo apt install php libapache2-mod-php8.4 php8.4-cli php8.4-common php8.4-zip php8.4-curl php8.4-mysql php8.4-xml php8.4-mbstring php8.4-gd -y

Users of Debian 12 (Bookworm) should use PHP 8.2:

sudo apt install php libapache2-mod-php8.2 php8.2-cli php8.2-common php8.2-zip php8.2-curl php8.2-mysql php8.2-xml php8.2-mbstring php8.2-gd -y

Alternatively, Debian 11 (Bullseye) utilizes PHP 7.4:

sudo apt install php libapache2-mod-php7.4 php7.4-cli php7.4-common php7.4-zip php7.4-curl php7.4-mysql php7.4-xml php7.4-mbstring php7.4-gd -y

Verify PHP Installation

Afterwards, once installation completes, verify PHP is accessible from the command line:

php -v

The output shows your installed PHP version (example from Debian 13):

PHP 8.4.x (cli) (built: 2025-xx-xx) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.4.x, Copyright (c) Zend Technologies
    with Zend OPcache v8.4.x, Copyright (c), by Zend Technologies

The Apache PHP module loads automatically during installation. However, as a final step, restart Apache to apply the PHP configuration:

sudo systemctl restart apache2

If you need to switch PHP versions after installing from a third-party repository, disable the current version with sudo a2dismod php8.2, enable the new version with sudo a2enmod php8.4, then restart Apache.

Install WordPress Backend

Downloading WordPress

First, to begin, download the latest version of WordPress using the following permalink from WordPress:

wget https://wordpress.org/latest.tar.gz

Extract WordPress Directory

The downloaded file is a compressed tar.gz archive. Therefore, use the tar command to extract its contents. This step is vital as it unpacks all the necessary WordPress files needed for installation:

sudo tar -xzvf latest.tar.gz -C /var/www/html/

Setting Permissions and Ownership

Crucially, setting the correct permissions and ownership for the WordPress directory is essential. This configuration ensures the web server can correctly access and modify files for updates, plugin installations, and other operations.

Changing Ownership

Specifically, the chown command changes the ownership of all files and directories within WordPress to the web server user, which is typically www-data. This step is critical for WordPress to function correctly on the server:

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

Modifying Permissions

Additionally, setting the right permissions is crucial for security and functionality. For this purpose, the chmod command sets directory permissions to 755 and file permissions to 644. As a result, this configuration allows WordPress to operate securely and efficiently:

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

Creating a Database for WordPress

WordPress requires a database to store all site data. Accordingly, in this section, you will create a new database and user for WordPress using MariaDB.

Accessing the MariaDB Shell

To start, log into MariaDB as the root user. This step allows you to create and manage databases and users:

sudo mariadb -u root

Alternatively, if you prefer MySQL:

sudo mysql -u root

Creating the WordPress Database

Once logged in, execute the SQL command to create a new database named WORDPRESSDB. Replace WORDPRESSDB with your desired database name. This database will hold all WordPress data:

CREATE DATABASE WORDPRESSDB;

Creating a Secure Database User

Moreover, for enhanced security, create a unique user for WordPress. This practice limits access and reduces attack vectors. Replace ‘WPUSER’ and ‘PASSWORD’ with your chosen username and password:

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

Note: WPUSER and PASSWORD can be whatever you desire. Ensure any further commands reflect what you set at this point when dealing with the database side of installing WordPress with LAMP.

Granting Privileges

Next, assign necessary privileges to the new user for managing the WordPress database. This step is crucial to ensure that WordPress can interact with its database:

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

Applying Changes

Finally, flush the privileges to apply changes and exit the MariaDB shell:

FLUSH PRIVILEGES;
EXIT;

Configuring WordPress

Now set up the WordPress configuration by editing the wp-config.php file. This involves specifying database details and other configurations.

Navigate to WordPress Directory

First, change to the WordPress installation directory:

cd /var/www/html/wordpress/

Configuring wp-config.php

Then, rename the sample configuration file and edit it to include your database details:

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

Next, 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

Specifically, update the file with your database name, user, and password. You can also set the database charset and collation:

// ** 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', 'WPUSER' );

/* 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', '' );

Furthermore, you can add configurations for direct file edits, memory limits, and table prefixes:

/* 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_';

Setting WordPress Security Keys

Following this, generate unique authentication keys for WordPress. Visit the WordPress secret-key API and replace the placeholder lines in the wp-config.php file with your generated keys.

Configuring Apache for WordPress

Next, set up a virtual host for your WordPress site in Apache. This step is crucial for directing web traffic to your WordPress installation.

Creating the Virtual Host File

First, begin by creating a new configuration file for your WordPress site:

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

Then, configure the file with your domain, document root, and necessary directives:

<VirtualHost *:80>
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com
    DocumentRoot /var/www/html/wordpress
    <Directory "/var/www/html/wordpress">
        AllowOverride All
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/wordpress.error.log
    CustomLog ${APACHE_LOG_DIR}/wordpress.access.log combined
</VirtualHost>

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

sudo apache2ctl configtest

Successful output:

Syntax OK

Given that the virtual host configuration has no errors, you can now enable your virtual host.

sudo a2ensite example.com.conf

Finally, restart your Apache service to apply the changes:

sudo systemctl restart apache2

Install WordPress Frontend

Accessing the Installation Address

Finally, to initiate the WordPress installation, navigate to your website’s domain. Use either of these URLs:

  • https://www.yoursite.com
  • https://www.yoursite.com/wp-admin/install.php

Immediately, upon accessing the site, you’ll encounter the language settings page. Here, you can select the preferred language for your WordPress installation.

Setting Up Admin Account

Then, create your admin account. This is a crucial step as it sets up your username and password, which you’ll use for future logins. Remember, these credentials are changeable at any point.

Configuring Search Engine Visibility

Additionally, for websites under construction, it’s advisable to prevent search engines from indexing your site. Select the option “strongly discourage search engines from indexing this site” during setup. This step ensures that search engines like Google and Bing do not index your work-in-progress (WIP) website. You can change this setting once your site is ready for public viewing.

Completion of WordPress Installation

Finally, once these steps are completed and you log in, your WordPress site, powered by the LAMP Stack on Debian, is successfully installed and ready for customization and content creation.

Create a Let’s Encrypt SSL Free Certificate

Furthermore, for enhanced security on Debian, using Let’s Encrypt SSL certificates with your WordPress Apache installation is highly recommended. Let’s Encrypt is a free, automated certificate authority provided by the Internet Security Research Group (ISRG). As a result, it boosts your site’s credibility by enabling HTTPS, a protocol for secure communication over a computer network.

Installing Certbot for SSL Integration

First, install Certbot, which is a software tool that automates obtaining and installing SSL certificates. Install Certbot using the following command:

sudo apt install python3-certbot-apache -y

Generating SSL Certificate

Subsequently, after installing Certbot, generate an SSL certificate with this command:

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

Remember to customize you@example.com and www.example.com with your email and domain. This step secures your site with HTTPS redirects, Strict-Transport-Security headers, and OCSP Stapling, thereby ensuring enhanced security.

Automatic Renewal of SSL Certificate

Certbot automatically configures a systemd timer to handle certificate renewal. Let’s Encrypt certificates are valid for 90 days, and Certbot attempts renewal when certificates are within 30 days of expiration. Verify the renewal timer is active:

sudo systemctl status certbot.timer

Successful output confirms the timer is enabled and waiting:

● certbot.timer - Run certbot twice daily
     Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; preset: enabled)
     Active: active (waiting) since xxx; xxxx ago
    Trigger: xxx (in yyyy)
   Triggers: ● certbot.service

Additionally, to test the renewal process without actually renewing, run a dry run:

sudo certbot renew --dry-run

Transitioning to HTTPS

Once these configurations are complete, your site will use HTTPS, redirecting all HTTP traffic to a secure HTTPS connection. As a result, this ensures data encryption between your server and users’ browsers.

Setting Up UFW Firewall for LAMP Stack

Typically, when running Apache with your LAMP Stack, configuring the Uncomplicated Firewall (UFW) is important. UFW simplifies firewall management and is essential for controlling access to your server’s services.

Installing UFW

However, if UFW is not yet installed, first add it with:

sudo apt install ufw -y

Warning: Before enabling UFW, allow SSH access to prevent being locked out of your server. Run sudo ufw allow ssh first if you connect remotely.

sudo ufw allow ssh
sudo ufw enable

Configuring Apache Profiles in UFW

Apache integrates with UFW and provides several profiles. To list these, use:

sudo ufw app list

For example, the output displays profiles like ‘Apache’ (HTTP), ‘Apache Secure’ (HTTPS), and ‘Apache Full’ (both HTTP and HTTPS). Choose the appropriate profile according to your setup.

Enabling UFW Profiles

Initially, for a basic setup without SSL, enable the Apache profile:

sudo ufw allow 'Apache'

Alternatively, for HTTPS traffic (after setting up SSL), enable ‘Apache Secure’:

sudo ufw allow 'Apache Secure'

Finally, to allow both HTTP and HTTPS, use:

sudo ufw allow 'Apache Full'

Troubleshoot Common WordPress Issues

Resolving PHP Session Errors

Unfortunately, PHP session errors, which are often encountered when using specific WordPress plugins, are commonly due to incorrect permissions in the /var/lib/php/sessions/ directory.

Consequently, to resolve this, run the following command:

sudo chown -R www-data:www-data /var/lib/php/sessions/

This command changes the ownership of the sessions directory to the www-data user and group. As a result, WordPress gains the necessary permissions to write session data, which is crucial for plugins handling automated tasks like social media integrations. Rectifying PHP session errors therefore enhances your website’s performance and user experience.

Addressing HTTPS Redirect Loop in WordPress

An HTTPS redirect loop in WordPress, which typically occurs after enabling HTTPS, can be fixed by editing the wp-config.php file. This loop happens when WordPress continually redirects to HTTPS, but the process never completes.

Modifying the wp-config.php File

Therefore, to resolve this issue, insert these lines into your wp-config.php:

define('FORCE_SSL_ADMIN', true);

if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
    $_SERVER['HTTPS'] = 'on';
}

Explanation of the code:

  • The FORCE_SSL_ADMIN line ensures all admin pages utilize HTTPS.
  • The subsequent code checks the HTTP_X_FORWARDED_PROTO header for ‘https’. When detected, it sets the HTTPS server variable to ‘on’, signaling a secure connection.

Implementing these changes should resolve the HTTPS redirect loop, thereby ensuring the smooth operation of your WordPress site with its secure connection.

Fixing Domain Name Redirect Loop

Redirect loops in WordPress can also arise from discrepancies between the domain name in the wp-config.php file and your site’s actual domain.

Verifying the wp-config.php File

Check and adjust the domain name in your wp-config.php:

define('WP_HOME','http://example.com');
define('WP_SITEURL','http://example.com');

Ensure the domain name here matches your website’s actual domain. If the problem persists despite correct domain settings, the issue might stem from server configurations. In such cases, contacting your hosting provider for further assistance is advisable.

Remove WordPress and LAMP Stack

If you need to remove WordPress or the complete LAMP stack from your Debian system, follow these steps depending on how much you want to uninstall.

Remove WordPress Files and Database

Specifically, to remove WordPress while keeping the LAMP stack for other projects, delete the WordPress directory and remove the database:

Warning: The following commands permanently delete all WordPress files and database content. Back up any files or exports you want to keep before proceeding.

sudo rm -rf /var/www/html/wordpress/

Then, remove the WordPress database and user from MariaDB:

sudo mariadb -u root
DROP DATABASE WORDPRESSDB;
DROP USER 'WPUSER'@localhost;
FLUSH PRIVILEGES;
EXIT;

Replace WORDPRESSDB and WPUSER with the actual database and username you created during installation.

Remove Apache Virtual Host

Subsequently, disable and remove the WordPress virtual host configuration:

sudo a2dissite example.com.conf
sudo rm /etc/apache2/sites-available/example.com.conf
sudo systemctl reload apache2

Completely Remove LAMP Stack (Optional)

Finally, to completely remove all LAMP components from your system, uninstall Apache, MariaDB, and PHP:

sudo apt remove apache2 mariadb-server mariadb-client php libapache2-mod-php
sudo apt autoremove

Alternatively, to also remove configuration files, use purge instead of remove:

sudo apt purge apache2 mariadb-server mariadb-client php libapache2-mod-php
sudo apt autoremove

Conclusion

Your WordPress site now runs on a complete LAMP stack with Apache, MariaDB, and PHP on Debian. The SSL certificate from Let’s Encrypt provides encrypted HTTPS connections, and UFW protects your server from unauthorized access. Regularly update your WordPress installation, themes, and plugins to maintain security and performance.

If you encounter redirect loops, PHP session errors, or database connection issues, refer to the troubleshooting section. For related server configurations, see our guides on securing Apache with Let’s Encrypt on Debian and configuring unattended upgrades on Debian for automatic security updates.

3 thoughts on “How to Install WordPress with Apache on Debian”

Leave a Comment