Effortlessly deploy a Production-Ready WordPress on Ubuntu 26.04 using LAMP Stack

By Rajiv Raut July 13, 2026
Deployment of wordpress on ubuntu with apache and SSL with LetsEncrypt

Overview

If you want complete control over your WordPress website, hosting it on your own server is an excellent option. While managed hosting is convenient, running WordPress yourself lets you customize every part of the stack, optimize performance, and strengthen security to match your needs.

A proven setup is Apache, PHP-FPM, MySQL, and Let’s Encrypt on Ubuntu 26.04. This combination has been trusted in production environments for years, offering excellent stability, compatibility, and long-term support. Apache provides a powerful and flexible web server, PHP-FPM improves PHP performance, MySQL stores your website’s data, and Let’s Encrypt secures your site with free SSL/TLS certificates.

In this guide, you’ll start with a fresh Ubuntu 26.04 server and build a production-ready WordPress environment from the ground up. By the end, you’ll have a fully functional WordPress installation running over HTTPS with a configuration that’s suitable for personal websites, business sites, and production deployments.

Throughout this tutorial, example.com is used as a placeholder domain. Simply replace it with your own domain name wherever it appears.

Before You Start

Before getting started, make sure you have the following:

  • A fresh Ubuntu 26.04 server with root or sudo privileges
  • A registered domain name pointed to your server’s public IP address
  • Basic familiarity with the Linux command line

Software Stack

Throughout this guide, you’ll build a production-ready WordPress environment using:

  • Apache as the web server
  • PHP-FPM to execute WordPress’s PHP code, providing better performance and resource efficiency than the traditional mod_php module
  • MySQL as the database server for storing WordPress data
  • Let’s Encrypt to issue a free SSL/TLS certificate with automatic renewal, enabling secure HTTPS connections

Step 1: Update the Server

Before installing any software, update your server to ensure you’re working with the latest security patches and package versions.

sudo apt update
updating the local repo list
sudo apt upgrade -y
upgrading the updates
sudo reboot
rebooting the VPS

Rebooting the server ensures that any kernel or system-level updates are applied before you continue with the installation.

Step 2: Install and Enable Apache

Apache is the web server that will handle incoming HTTP and HTTPS requests for your WordPress site.

Install Apache and configure it to start automatically whenever the server boots:

sudo apt install apache2 -y
Installing the apache2 package
sudo systemctl enable --now apache2
Enabling the apache2 and setting it up as auto-startup

Verify that the service is running:

systemctl status apache2
verifying the apache2 status

If everything is working correctly, the status should show active (running).

Next, allow web traffic through Ubuntu’s firewall:

sudo ufw allow "Apache Full"
configuring the firewall to allow Apache

The Apache Full firewall profile opens both HTTP (port 80) and HTTPS (port 443), allowing visitors to access your website over either protocol.

Step 3: Install and Secure MySQL

WordPress stores all of its content, users, settings, and site configuration in a database. In this guide, we’ll use MySQL as the database server.

Install MySQL and configure it to start automatically whenever the system boots:

sudo apt install mysql-server -y
Installing the mysql-server package
sudo systemctl enable --now mysql
Enabling the mysql-server, setting it up as auto-startup and checking its status

After installation, run MySQL’s built-in security script to remove common security risks and harden the installation:

sudo mysql_secure_installation
configuring mysql security

For most production deployments, the following choices are recommended:

PromptRecommended Answer
Validate Password ComponentOptional, but recommended
Password PolicyMedium
Remove anonymous usersYes
Disallow remote root loginYes
Remove test database and access to itYes
Reload privilege tables nowYes

These settings help eliminate unnecessary accounts, disable insecure defaults, and improve the overall security of your MySQL installation.

Step 4: Create the WordPress Database

Rather than using the MySQL root account, create a dedicated database and user for WordPress. This follows the principle of least privilege, limiting access to only the resources WordPress requires.

Log in to the MySQL shell:

sudo mysql

Create the database and user:

CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Creating Database, Database User and granting it privileges

Replace StrongPassword123! with a strong, unique password. You’ll need these database credentials later when running the WordPress installation wizard, so keep them somewhere safe.

Step 5: Install PHP-FPM and Required Extensions

WordPress is built with PHP, so you’ll need PHP-FPM along with several extensions that provide database connectivity, image processing, XML support, internationalization, and other core functionality.

Install PHP-FPM and the required PHP extensions:

sudo apt install php-fpm php-mysql php-cli php-curl php-gd php-mbstring php-xml php-xmlrpc php-soap php-intl php-zip php-imagick libapache2-mod-fcgid unzip -y
Installing the php and its extensions required by the wordpress

After the installation completes, verify the installed PHP version:

php -v
checking installed php version
ls /run/php/
Finding the installed version of php-fpm socket

The output will include the installed PHP version and one or more PHP-FPM socket files, for example:

php8.4-fpm.sock

Make a note of the PHP version (such as 8.4), as you’ll use it in the next step when configuring Apache.

Step 6: Enable the Required Apache Modules

Apache requires several modules to communicate with PHP-FPM, support HTTPS, and enable features such as URL rewriting and HTTP/2.

Enable the required modules:

sudo a2enmod proxy_fcgi setenvif rewrite headers expires ssl http2
Enabling the required apache modules

Next, enable the PHP-FPM configuration that matches the version installed on your server. For example, if you’re using PHP 8.4:

sudo a2enconf php8.4-fpm
Enabling the php-fpm configuration
sudo systemctl restart apache2
reloading the apache2 package

Note: If your server installed a different PHP version (for example, PHP 8.5), replace php8.4-fpm with the appropriate version.

Step 7: Download WordPress

Download the latest stable release of WordPress directly from the official website, extract it, and move it into your web root.

cd /tmp
sudo wget https://wordpress.org/latest.zip
sudo unzip latest.zip
Downloading and unzipping the wordpress

Moving the wordpress files to the domain’s directory:

sudo mv wordpress /var/www/example.com
Moving the wordpress files to the domain directory

Using the latest official release ensures your installation includes the newest features, bug fixes, and security updates.

Step 8: Set File Permissions

Correct file ownership and permissions are essential for both security and functionality. Apache must be able to read your website files, while WordPress needs appropriate permissions to upload media, install themes, and apply updates.

Assign ownership of the WordPress directory to Apache’s web server user:

sudo chown -R www-data:www-data /var/www/example.com
Changing the directory's owner and group

Set recommended directory permissions:

sudo find /var/www/example.com -type d -exec chmod 755 {} \;
Changing the directory permissions

Set recommended file permissions:

sudo find /var/www/example.com -type f -exec chmod 644 {} \;
Changing the file permissions

These permissions strike a good balance between security and usability for most production WordPress deployments. Avoid granting overly permissive permissions such as 777, as they can expose your server to unnecessary security risks.

Step 9: Configure WordPress

Navigate to your WordPress installation directory and create the main configuration file from the provided template:

cd /var/www/example.com
cp wp-config-sample.php wp-config.php
Creating the main configuration file from the provided template
sudo vim wp-config.php
Configuring the wordpress configuration

Locate the database configuration section and update it with the credentials you created earlier:

define('DB_NAME', 'wordpress');
define('DB_USER', 'wpuser');
define('DB_PASSWORD', 'StrongPassword123!');
define('DB_HOST', 'localhost');

Replace StrongPassword123! with the password you assigned to the wpuser MySQL account

Generate Authentication Keys and Salts

WordPress uses unique security keys and salts to encrypt authentication cookies and protect user sessions.

Generate a fresh set by running:

curl -s https://api.wordpress.org/secret-key/1.1/salt/
Generating wordpress authentication salts

Copy the generated output and replace the existing placeholder key definitions in wp-config.php.

Using freshly generated keys improves the security of your WordPress installation and helps protect user authentication sessions.

Step 10: Create an Apache Virtual Host

Create a new Apache Virtual Host configuration for your domain:

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

Add the following configuration:

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

    DocumentRoot /var/www/example.com

    <Directory /var/www/example.com>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>
Creating the apache VIrtual Host

Save the file, then enable the new Virtual Host and disable Apache’s default site:

sudo a2ensite example.com.conf
Enabling the site
sudo a2dissite 000-default.conf
Disabling the default site
sudo apachectl configtest
Checking the apache virtual host configuration
sudo systemctl reload apache2
Reloading the apache web server

The apachectl configtest command checks your Apache configuration for syntax errors before the service is reloaded. Running this command is considered a best practice, as it helps prevent configuration mistakes from causing website downtime.

Step 11: Point Your Domain to the Server

To make your website accessible over the internet, update your domain’s DNS records at your domain registrar or DNS provider.

Create the following A records:

TypeHostPoints To
Aexample.comSERVER_IP
AwwwSERVER_IP

Replace SERVER_IP with your server’s public IPv4 address.

DNS A record

DNS changes are not applied instantly. Depending on your DNS provider and TTL values, propagation may take anywhere from a few minutes to several hours before your domain begins resolving to the new server.

Step 12: Secure Your Site with a Let’s Encrypt SSL Certificate

After your domain has finished pointing to the server, install Certbot and use it to obtain a free SSL/TLS certificate from Let’s Encrypt.

Install Certbot and its Apache plugin:

sudo apt install certbot python3-certbot-apache -y
Installing the certbot for LetEncrypt SSL

Request and install the certificate:

sudo certbot --apache
Obtaining LetsEncrypt SSL certificates through certbot

During the setup process, Certbot will ask whether you’d like to redirect all HTTP traffic to HTTPS. For a production website, choose Redirect, so visitors always access your site over a secure connection.

After the certificate has been installed, verify that automatic renewal is working:

sudo certbot renew --dry-run
Verifying the automatic renewal of SSL certificate

Let’s Encrypt certificates are valid for 90 days, but Certbot automatically configures scheduled renewals. Running a dry renewal test confirms that the renewal process will succeed before the certificate reaches its expiration date.

Step 13: Complete the WordPress Installation

Open your browser and navigate to:

https://example.com

You should be greeted by the WordPress installation wizard.

Wordpress installation page

Complete the setup by providing:

  • Your Site Title
  • An Administrator Username
  • A strong, unique Administrator Password
  • Your Email Address
wordpress site setting page

Once you’ve finished the installer, WordPress will create the necessary configuration and database tables, and your website will be ready to use.

wordpress installation success
wordpress login page
wordpress admin dashboard

Step 14: Verify That PHP-FPM Is Being Used

Although PHP-FPM has been installed and configured, it’s good practice to confirm that Apache is actually using it instead of the older mod_php handler.

Create a temporary PHP information page:

echo "<?php phpinfo(); ?>" | sudo tee /var/www/example.com/info.php
Creating test file to check server-API

Visit the following URL in your browser:

https://example.com/info.php

Verifying the Server API

Locate the Server API field on the page.

  • If it displays FPM/FastCGI, Apache is correctly processing PHP requests through PHP-FPM.
  • If it displays Apache 2.0 Handler, PHP is still being served by mod_php, and you should revisit Steps 5 and 6 to verify your PHP-FPM configuration.

After confirming everything is working correctly, remove the test file immediately:

sudo rm /var/www/example.com/info.php
removing the test file from the web server

The phpinfo() page exposes detailed information about your server’s PHP configuration, installed extensions, and environment. Leaving it publicly accessible is considered a security risk, so it should always be deleted once you’ve finished testing.

Hardening Your WordPress Server

At this stage, your WordPress site is live and accessible over HTTPS. However, a production server should be secured beyond the default installation. The following best practices will help improve security, reliability, and long-term maintainability.

Enable Automatic Security Updates

Keeping your operating system up to date is one of the simplest ways to protect your server from known vulnerabilities.

Install and enable unattended-upgrades so Ubuntu can automatically apply security patches:

sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure unattended-upgrades

This reduces the risk of leaving critical security updates unapplied.

Install Fail2Ban

Fail2Ban helps protect your server by monitoring log files and temporarily banning IP addresses that repeatedly fail authentication attempts.

Install it with:

sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban

Out of the box, Fail2Ban provides protection for services such as SSH. You can also configure it to help defend WordPress login pages and other internet-facing services.

Configure the Firewall

Use UFW (Uncomplicated Firewall) to restrict incoming connections to only the services your server actually needs.

Allow SSH, HTTP, and HTTPS traffic:

sudo ufw allow OpenSSH

sudo ufw allow "Apache Full"

sudo ufw enable

Verify the active firewall rules:

sudo ufw status

For a typical WordPress server, only the following ports should be publicly accessible:

  • 22 — SSH
  • 80 — HTTP
  • 443 — HTTPS

Disable Directory Listing

Directory listing can expose your site’s file structure if an index file is missing.

To prevent this, ensure your Apache Virtual Host includes the -Indexes option:

<Directory /var/www/example.com>

Options -Indexes

AllowOverride All

Require all granted

</Directory>

After making changes, test the configuration and reload Apache:

sudo apachectl configtest

sudo systemctl reload apache2

Keep Your Software Updated

Security is an ongoing process, not a one-time task. Regularly update every component of your stack, including:

  • Ubuntu packages
  • Apache
  • PHP and its extensions
  • MySQL
  • WordPress core
  • Themes
  • Plugins

Promptly applying updates helps protect your server from newly discovered vulnerabilities and improves overall stability.

Maintain Reliable Backups

Backups are your last line of defense against accidental deletion, failed updates, hardware failures, and security incidents.

A complete backup strategy should include:

  • The WordPress files (/var/www/example.com)
  • The MySQL database
  • Configuration files, where appropriate

Just as importantly, periodically test your backups by restoring them in a staging environment. A backup that hasn’t been verified may not be usable when you need it most.

Troubleshooting

Even with a careful setup, it’s common to encounter a few issues during your first deployment. The following are some of the most common problems along with the steps to diagnose and resolve them.

Apache Won’t Start or Fails to Reload

If Apache refuses to start or reload, begin by testing its configuration:

sudo apachectl configtest

In most cases, this command identifies the configuration file and line number responsible for the error.

Common causes include:

  • Port 80 or 443 is already in use. Check which process is listening on these ports:
 sudo ss -tlnp | grep -E ':80|:443'
  • Another web server, such as Nginx, may already be using the required ports.
  • A syntax error in the Virtual Host configuration. Carefully review your example.com.conf file for missing closing tags, incorrect directives, or typographical errors.

Apache modules were enabled but the service wasn’t restarted. After running a2enmod or a2enconf, restart Apache to ensure the changes are applied:

sudo systemctl restart apache2

For more detailed information, monitor Apache’s error log in real time:

sudo tail -f /var/log/apache2/error.log

Port 80 or 443 Is Already in Use

If apachectl configtest succeeds but Apache still won’t start, another application is likely using one of the required ports.

Identify the process with:

sudo ss -tulpn | grep -E ':80|:443'

Alternatively, check a specific port:

sudo lsof -i :80

Common services that may cause conflicts include:

  • Nginx
  • Another Apache instance
  • Docker containers exposing ports 80 or 443
  • Other web services bound to those ports

Stop or reconfigure the conflicting service, then start Apache again.

The Virtual Host Isn’t Loading

If your browser continues to display the default Apache page or the wrong website, verify that your Virtual Host has been enabled.

List the enabled sites:

ls -l /etc/apache2/sites-enabled/

You should see a symbolic link to example.com.conf.

If it isn’t present, enable the site and reload Apache:

sudo a2ensite example.com.conf

sudo systemctl reload apache2

If the issue persists, verify that:

  • Your domain’s DNS records point to the correct server IP address.
  • The ServerName and ServerAlias directives match your domain.
  • The DocumentRoot points to the correct WordPress directory.
  • The default site (000-default.conf) has been disabled if it’s no longer needed.

PHP Files Download Instead of Executing

If visiting index.php causes your browser to download the file instead of displaying the page, Apache isn’t passing PHP requests to PHP-FPM.

First, verify that the PHP-FPM service is running:

systemctl status php8.4-fpm

If the service is running, ensure that Apache’s PHP-FPM configuration and required modules are enabled:

sudo a2enconf php8.4-fpm
sudo a2enmod proxy_fcgi setenvif
sudo systemctl restart apache2

Note: If your server is using a different PHP version, replace php8.4-fpm with the version installed on your system.

PHP-FPM Won’t Start

Check the current status of the PHP-FPM service:

systemctl status php8.4-fpm

If the service is stopped, start it and configure it to launch automatically during boot:

sudo systemctl start php8.4-fpm
sudo systemctl enable php8.4-fpm

If PHP-FPM still fails to start, inspect its system log for the underlying error:

sudo journalctl -u php8.4-fpm

A common cause is an invalid configuration in the PHP-FPM pool configuration file:

/etc/php/8.4/fpm/pool.d/www.conf

Correct the reported error, then restart the service.

WordPress Displays a Blank White Page

A completely blank page—often referred to as the White Screen of Death (WSOD)—usually indicates that PHP encountered a fatal error that isn’t being displayed in the browser.

Enable WordPress debugging by adding the following lines to your wp-config.php file immediately above the line that says “That’s all, stop editing! Happy publishing.”:

define('WP_DEBUG', true);

define('WP_DEBUG_LOG', true);

define('WP_DEBUG_DISPLAY', false);

This configuration writes PHP errors to a log file without exposing them to visitors.

Monitor the debug log with:

sudo tail -f /var/www/example.com/wp-content/debug.log

Common causes include:

  • A faulty or incompatible plugin
  • A broken or incompatible theme
  • An insufficient PHP memory limit
  • A missing or disabled PHP extension
  • PHP version compatibility issues

After resolving the problem, disable debugging by setting WP_DEBUG back to false. Leaving debug mode enabled on a production website may expose sensitive information and is not recommended.

Apache Is Using mod_php Instead of PHP-FPM

If the phpinfo() page from Step 14 reports Apache 2.0 Handler instead of FPM/FastCGI, Apache is still processing PHP with mod_php rather than PHP-FPM.

Begin by disabling the mod_php module:

sudo a2dismod php8.4
sudo systemctl restart apache2

Note: Replace php8.4 with the PHP version installed on your server if necessary.

Next, ensure the PHP-FPM configuration is enabled:

sudo a2enconf php8.4-fpm
sudo systemctl restart apache2

Finally, verify that the socket referenced in Apache’s PHP-FPM configuration matches the socket created by the running PHP-FPM service.

List the available sockets:

ls /run/php/

Then compare the output with the socket configured in:

/etc/apache2/conf-available/php8.4-fpm.conf

The socket names must match. If they don’t, update the Apache configuration to reference the correct PHP-FPM socket and restart Apache.

“Error Establishing a Database Connection”

This error usually indicates that WordPress cannot connect to the MySQL database.

The most common causes are:

MySQL isn’t running. Check its status:

sudo systemctl status mysql

If necessary, start the service:

sudo systemctl start mysql
  • Incorrect database credentials. Verify that the following values in wp-config.php exactly match those created in Step 4:
    • DB_NAME
    • DB_USER
    • DB_PASSWORD
    • DB_HOST

The database user lacks sufficient privileges. Log in to MySQL and run the GRANT statement again, followed by:

FLUSH PRIVILEGES;

To verify the database credentials independently of WordPress, attempt to connect directly from the command line:

mysql -u wpuser -p wordpress

If this connection fails, the problem lies with the MySQL configuration or credentials rather than WordPress itself.

After logging in successfully, you can verify that both the database and user exist:

SHOW DATABASES;
SELECT User, Host FROM mysql.user;

MySQL “Access Denied” Error

If MySQL returns an error similar to:

ERROR 1045 (28000): Access denied for user

the database user’s privileges may be incorrect or missing.

Reconnect to MySQL as an administrative user and reapply the required permissions:

GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';

FLUSH PRIVILEGES;

After updating the privileges, try connecting again using the wpuser account. If the connection succeeds, WordPress should also be able to connect to the database successfully.

Certbot Fails to Issue an SSL Certificate

Before Certbot can obtain a certificate, your domain must resolve to the server and HTTP traffic on port 80 must be accessible from the internet.

If certificate issuance fails, work through the following checks.

Verify DNS Resolution

Confirm that your domain resolves to your server’s public IP address:

dig +short example.com

The command should return your server’s IP address. If it doesn’t, DNS propagation is still in progress. Wait for the changes to propagate before running Certbot again.

Verify Firewall Rules

Check that Ubuntu’s firewall allows HTTP and HTTPS traffic:

sudo ufw status

You should see either the Apache Full profile or explicit rules allowing ports 80 and 443.

If you’re using a VPS provider such as AWS, DigitalOcean, Azure, or Google Cloud, also verify that any provider-level firewall or security group allows inbound traffic on ports 80 and 443. These network firewalls operate independently of UFW and can prevent Let’s Encrypt from validating your domain.

Run Certbot in Verbose Mode

For more detailed diagnostic information, rerun Certbot with verbose logging enabled:

sudo certbot --apache -v

The additional output often provides enough information to identify the exact cause of the failure.

The Site Loads Over HTTP but Not HTTPS

If your website is accessible over HTTP but HTTPS doesn’t work—or the browser displays a certificate warning—verify the following:

Check the installed certificates:

sudo certbot certificates

Ensure that:

  • A valid certificate has been issued for your domain.
  • The certificate has not expired.
  • The Apache SSL module is enabled.
  • Apache was restarted after Certbot completed its configuration.

If HTTPS works but your browser displays a mixed-content warning (for example, a padlock with a warning icon), some resources are still being loaded over HTTP.

In the WordPress dashboard, navigate to:

Settings → General

Verify that both of the following URLs begin with https://:

  • WordPress Address (URL)
  • Site Address (URL)

If your site was originally configured over HTTP, you may also need to update hard-coded HTTP URLs stored in the database.

403 Forbidden

A 403 Forbidden error usually indicates a permissions or Apache configuration problem.

The most common causes are:

  • Incorrect file or directory permissions (see Step 8).
  • The Require all granted directive is missing from the Virtual Host configuration.
  • The DocumentRoot points to the wrong directory.

Verify that your Virtual Host includes the following directory configuration:

<Directory /var/www/example.com>

    AllowOverride All

    Require all granted

</Directory>

After making any changes, test the Apache configuration and reload the service:

sudo apachectl configtest
sudo systemctl reload apache2

If the configuration test succeeds and the DocumentRoot and permissions are correct, the site should become accessible.

The Site Loads but CSS or Styling Is Missing

If your website loads but appears as plain, unstyled HTML, the web server is usually working correctly. In most cases, the issue is related to WordPress configuration rather than Apache or PHP.

The most common causes are:

  • Incorrect WordPress URLs. In the WordPress dashboard, navigate to Settings → General and verify that both the WordPress Address (URL) and Site Address (URL) use the correct domain and protocol (for example, https://example.com).
  • Mixed-content issues. After enabling HTTPS, browsers will block stylesheets, JavaScript, images, and other assets that are still being requested over http://. Inspect your browser’s developer console for mixed-content warnings and update any outdated URLs.
  • Incorrect file permissions. If the active theme or the wp-content directory cannot be read by the web server, CSS and other assets may fail to load.
  • Browser cache. Browsers often cache stylesheets aggressively. Perform a hard refresh (Ctrl + F5 or Ctrl + Shift + R) or test the site in a private/incognito window before investigating further.

File Uploads or Plugin/Theme Installation Fails

If WordPress reports errors such as “Unable to create directory” or requests FTP credentials when installing plugins or themes, the web server likely doesn’t have permission to write to the WordPress directory.

Reapply the recommended ownership and permissions:

sudo chown -R www-data:www-data /var/www/example.com
sudo find /var/www/example.com -type d -exec chmod 755 {} \;
sudo find /var/www/example.com -type f -exec chmod 644 {} \;

In most cases, ensuring that the www-data user owns the WordPress files resolves these issues and allows WordPress to install updates, themes, plugins, and media uploads without requesting FTP credentials.

A 500 Internal Server Error after enabling pretty permalinks is usually caused by an Apache configuration issue or an invalid .htaccess file.

First, verify that your Apache Virtual Host allows .htaccess overrides:

<Directory /var/www/example.com>

    AllowOverride All

    Require all granted

</Directory>

Without AllowOverride All, WordPress cannot use its rewrite rules, which may result in broken permalinks or server errors.

Next, ensure that Apache’s rewrite module is enabled:

sudo a2enmod rewrite
sudo systemctl restart apache2

If the problem persists, inspect Apache’s error log:

sudo tail -f /var/log/apache2/error.log

A malformed .htaccess file or an invalid Apache directive will typically be reported in the log, making it much easier to identify and resolve the underlying issue.

Where to Look: Log Locations

When troubleshooting a WordPress server, knowing where each component writes its logs can save a significant amount of time. The following locations are the first places to check when diagnosing problems.

ComponentLog Location
Apache Error Log/var/log/apache2/error.log
Apache Access Log/var/log/apache2/access.log
PHP-FPMjournalctl -u php8.4-fpm
MySQLjournalctl -u mysql
System Logsjournalctl -xe
UFW Firewalljournalctl -u ufw
WordPress Debug Log (when WP_DEBUG_LOG is enabled)/var/www/example.com/wp-content/debug.log

Note: If you’re using a different PHP version, replace php8.4-fpm with the version installed on your server.

Handy Diagnostic Commands

These commands are useful for quickly checking the health and configuration of your server.

PurposeCommand
Check Apache statussystemctl status apache2
Check PHP-FPM statussystemctl status php8.4-fpm
Check MySQL statussystemctl status mysql
Test Apache configurationapachectl configtest
List enabled Apache modulesapachectl -M
List installed PHP modulesphp -m
Show listening portsss -tulpn
Display firewall rulesufw status
Verify DNS resolutiondig example.com
View installed SSL certificatescertbot certificates
Check PHP versionphp -v
View disk usagedf -h
View memory usagefree -h
Monitor running processestop or htop

General Debugging Workflow

When something isn’t working, avoid changing multiple settings at once. A structured troubleshooting process makes it much easier to identify the root cause.

  1. Validate the server configuration.
    Before restarting Apache, verify that its configuration contains no syntax errors:
sudo apachectl configtest
  1. Verify that all required services are running.
    Check the status of Apache, PHP-FPM, and MySQL:
systemctl status apache2
systemctl status php8.4-fpm
systemctl status mysql
  1. Review the logs.
    Examine the Apache error log, PHP-FPM journal, MySQL logs, or the WordPress debug log (if enabled) for detailed error messages.
  2. Verify network connectivity.
    Confirm that:
    1. DNS resolves to the correct server.
    2. Ports 80 and 443 are reachable.
    3. Firewall rules allow incoming web traffic.
  3. Check file ownership and permissions.
    Ensure the WordPress directory is owned by www-data and that directories and files use the recommended 755/644 permission scheme.
  4. Test each component independently.
    Isolate the problem by testing one layer at a time:
    1. Apache
    2. PHP-FPM
    3. MySQL
    4. WordPress
  5. This approach is far more effective than assuming the issue originates in WordPress.
  6. Restart or reload services after making changes.
    Many configuration changes don’t take effect until the corresponding service has been restarted or reloaded.

Following this workflow helps you quickly determine whether the issue lies with the web server, PHP, the database, networking, or WordPress itself. By isolating each layer individually, you’ll spend less time chasing symptoms and more time resolving the actual cause of the problem

Wrapping Up

Congratulations—you now have a production-ready WordPress server running on Ubuntu 26.04. Your stack combines Apache as the web server, PHP-FPM for efficient PHP processing, MySQL for reliable data storage, and Let’s Encrypt for automatic HTTPS encryption. Together, these components provide a stable, secure, and widely adopted foundation for hosting WordPress in production.

While setting up your own server requires more effort than using a managed hosting provider, the trade-off is complete control over your environment. You can fine-tune performance, implement your preferred caching strategy, strengthen security, and customize the server to meet your specific requirements—all without the limitations that often come with shared or managed hosting.

As your website grows, remember that maintaining a server is an ongoing responsibility. Keep your operating system and software up to date, monitor logs regularly, verify that backups are working, and review your security configuration from time to time. Consistent maintenance will help ensure your WordPress site remains fast, reliable, and secure for the long term.

With your server configured and WordPress installed, you’re ready to start building your website—whether it’s a personal blog, business website, portfolio, or a full-featured content platform.

R
Rajiv Raut

eHostingServer team member.

Leave a Reply

Your email address will not be published. Required fields are marked *