Overview
Setting up WordPress on Apache using virtual hosts lets you host multiple independent WordPress sites on a single server, each with its own domain name, SSL certificate, and isolated database. This is the standard method for running more than one WordPress installation on a VPS or dedicated server, giving you fine-grained control over performance, security, and resource allocation per site. This tutorial walks through the complete process on Ubuntu 24.04 LTS, from installing the LAMP stack and PHP-FPM through configuring Apache virtual hosts, deploying WordPress, and securing each site with Let's Encrypt SSL.
Why Use Apache Virtual Hosts for WordPress?
Apache virtual hosts let you map different domain names to separate directories on the same server so each WordPress site runs independently without interfering with the others. Without virtual hosts, Apache serves a single site from its default document root, which limits you to one WordPress installation per server IP address.
For developers, small businesses, and agencies managing multiple client sites, virtual hosts solve a real constraint: you don't need a separate server for every website. Each virtual host gets its own configuration block in Apache, its own log files, and its own SSL certificate. WordPress sites are completely unaware of each other, sharing only the underlying server resources.
This setup also matters for performance tuning. With virtual hosts, you can allocate different PHP memory limits, adjust caching strategies, or set different security policies for each site. A WordPress blog might need aggressive page caching while a WooCommerce store on the same server needs more PHP memory for checkout processing.
What You Need Before Running Any Commands
Confirm you have the following before starting:
- A Linux server running Ubuntu 24.04 LTS with root or sudo access
- At least one domain name pointed to your server's public IP via DNS A records
- SSH access to your server from your local machine
- A terminal or command-line interface for executing server commands
- Basic comfort navigating Linux directories and editing files from the terminal
If your server runs CentOS, Rocky Linux, or AlmaLinux instead of Ubuntu, the package manager commands differ (using dnf rather than apt) and some package names change. On CentOS-based systems, if you encounter the "Not enough cached data to install" error during package operations, the default repository mirrors may be outdated. The fix involves replacing the repository configuration with a working mirror and rebuilding the package cache—see this RAKsmart knowledge base article for the specific commands: The error message "Not enough cached data to install".
Step 1: Update Your Server and Install the LAMP Stack
Start with a fully patched system, then install Apache, MariaDB, and PHP in sequence.
sudo apt update && sudo apt upgrade -y
sudo apt install apache2 mariadb-server \
php libapache2-mod-php php-mysql php-curl php-gd \
php-mbstring php-xml php-zip php-intl -y
Enable the Apache rewrite module, which WordPress needs for clean permalinks:
sudo a2enmod rewrite
sudo systemctl restart apache2
Verify Apache is running:
sudo systemctl status apache2
Secure the MariaDB installation by running the interactive script:
sudo mysql_secure_installation
Follow the prompts to set a root password, remove anonymous users, and disallow remote root login. This step takes about two minutes and closes several default security gaps.
Step 2: Install PHP-FPM for Better Performance
PHP-FPM (FastCGI Process Manager) handles PHP requests as a separate process from Apache, which improves performance under load and gives you more control over PHP worker configuration. On Ubuntu 24.04, the default PHP version is 8.3, which WordPress fully supports.
sudo apt install php8.3-fpm -y
sudo systemctl enable php8.3-fpm
sudo systemctl start php8.3-fpm
Enable the PHP-FPM module in Apache and restart:
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.3-fpm
sudo systemctl restart apache2
PHP-FPM runs as its own service, so if you need to restart PHP after changing php.ini values—like increasing memory_limit—you restart the PHP-FPM service rather than Apache itself:
sudo systemctl restart php8.3-fpm
Step 3: Create a MySQL Database for WordPress
Each WordPress site needs its own database. Log into MySQL and create one for your first site:
sudo mysql -u root -p
CREATE DATABASE wp_site1_db;
CREATE USER 'wp_site1_user'@'localhost' IDENTIFIED BY 'a_strong_random_password';
GRANT ALL PRIVILEGES ON wp_site1_db.* TO 'wp_site1_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
For a second site, repeat with different names:
CREATE DATABASE wp_site2_db;
CREATE USER 'wp_site2_user'@'localhost' IDENTIFIED BY 'another_strong_password';
GRANT ALL PRIVILEGES ON wp_site2_db.* TO 'wp_site2_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Using separate databases and separate database users for each site is not optional—it is a security boundary. If one site is compromised, the attacker does not automatically gain access to the other site's data.
Step 4: Configure the Apache Virtual Host
This is the step that separates a single-site setup from a multi-site server. You will create a separate virtual host file for each domain, pointing each one to its own directory under /var/www/.
Create the directory structure:
sudo mkdir -p /var/www/site1.com
sudo mkdir -p /var/www/site2.com
Create the virtual host configuration for your first site:
sudo nano /etc/apache2/sites-available/site1.com.conf
Add this configuration:
<VirtualHost *:80>
ServerName site1.com
ServerAlias www.site1.com
DocumentRoot /var/www/site1.com
<Directory /var/www/site1.com>
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/site1_error.log
CustomLog ${APACHE_LOG_DIR}/site1_access.log combined
</VirtualHost>
Repeat for the second site, changing the directory path, domain name, and log file names. Then enable both sites and disable the default:
sudo a2ensite site1.com.conf
sudo a2ensite site2.com.conf
sudo a2dissite 000-default.conf
sudo systemctl reload apache2
The AllowOverride All directive is critical. It allows WordPress to use its .htaccess file for permalink management and plugin-defined URL rules. Without it, WordPress permalinks will return 404 errors and several plugins will stop functioning correctly.
Step 5: Download WordPress and Set Permissions
Download WordPress into each site's directory:
cd /tmp
sudo wget
sudo tar -xzf latest.tar.gz
sudo cp -a /tmp/wordpress/. /var/www/site1.com/
sudo cp -a /tmp/wordpress/. /var/www/site2.com/
Set ownership to the web server user:
sudo chown -R www-data:www-data /var/www/site1.com
sudo chown -R www-data:www-data /var/www/site2.com
Copy the sample configuration file for each site and edit it:
sudo cp /var/www/site1.com/wp-config-sample.php /var/www/site1.com/wp-config.php
sudo nano /var/www/site1.com/wp-config.php
Update DB_NAME, DB_USER, and DB_PASSWORD to match the database credentials you created in Step 3. Visit the WordPress Salt Generator at api.wordpress.org/secret-key and paste the generated security keys into your config file, replacing the placeholder values. Repeat the same process for site2.com.
Step 6: Complete Installation in Your Browser
Open your browser and navigate to `. WordPress will display its installation wizard. Fill in the site title, administrator username, password, and email address, then click "Install WordPress." Log in to the dashboard to confirm everything is working.
Repeat the browser-based process for `.
At this point, both WordPress sites are running on the same server, each with its own database, files, and Apache virtual host configuration. Traffic routes to the correct site automatically based on the ServerName directive in each virtual host.
Step 7: Secure Your Sites with SSL Using Let's Encrypt
Running WordPress over plain HTTP exposes login credentials and session data to anyone monitoring the network. Install Certbot and obtain free SSL certificates for both domains:
sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache -d site1.com -d www.site1.com
sudo certbot --apache -d site2.com -d www.site2.com
Certbot automatically modifies your Apache virtual host files to add SSL configuration and redirects all HTTP traffic to HTTPS. It also sets up a systemd timer that renews certificates before they expire, so you don't need to manage renewal manually.
Verify that HTTPS is working by visiting ` in your browser and checking for the padlock icon in the address bar.
Troubleshooting Common Issues
Even with careful configuration, problems arise. This table covers the errors most specific to virtual host setups on Apache.
| Error or Symptom | Likely Cause | Solution |
|---|---|---|
| Browser shows default Apache page instead of WordPress | Virtual host not enabled, or DNS not pointing to your server | Run sudo a2ensite site1.com.conf and reload Apache. Verify DNS with dig site1.com. |
| 404 on WordPress permalinks | AllowOverride not set to All in the virtual host config |
Edit the virtual host file and set AllowOverride All inside the <Directory> block. Restart Apache. |
| "Error establishing a database connection" | Wrong credentials in wp-config.php or MariaDB is not running |
Verify DB_NAME, DB_USER, DB_PASSWORD match what you created. Check MariaDB: sudo systemctl status mariadb. |
| SSL certificate not issued by Certbot | DNS not propagated, or port 80 blocked by firewall | Wait for propagation (use dig to check). Ensure port 80 is open: sudo ufw allow 'Apache Full'. |
| PHP-FPM errors or white screen | PHP-FPM service stopped or misconfigured | Check status: sudo systemctl status php8.3-fpm. Review logs: sudo tail -50 /var/log/php8.3-fpm.log. Restart the service. |
| One site works but the other shows the same content | Both virtual hosts share the same DocumentRoot or ServerName conflict |
Confirm each virtual host file points to a different directory and has a unique ServerName. |
Post-Installation Checklist: Securing Each WordPress Site
After both sites are running, work through this list before considering either site production-ready:
- Change the default WordPress database table prefix from
wp_to something unique per site inwp-config.php - Disable XML-RPC unless you specifically need it for remote publishing or Jetpack connectivity
- Install a security plugin that limits login attempts and monitors file changes
- Enable automatic updates for WordPress core, themes, and plugins
- Configure off-site backups for each site independently, covering both database and files
- Remove default themes and plugins that you do not plan to use
- Set file permissions to
755for directories and644for files - Review the WordPress Site Health dashboard under Tools for remaining recommendations
- Verify that each site's PHP memory limit is adequate (256 MB is a reasonable starting point for most WordPress installations)
When to Consider Managed Hosting
A manual Apache virtual host setup gives you full control and is excellent for learning how server infrastructure works. However, it also means you are responsible for every security patch, every PHP update, every Apache restart, and every backup. For a single developer managing a few sites, that overhead is manageable. For a growing business or an agency with multiple client sites, the time cost compounds quickly.
A managed WordPress hosting plan or a VPS with a pre-built control panel can reduce that burden significantly. Providers like RAKsmart offer VPS and dedicated server options where you can select your operating system and stack, balancing hands-on control with reduced infrastructure management. If your priority is building content and growing your audience rather than maintaining server configurations, managed hosting is worth evaluating as your next step.
FAQ
How many WordPress sites can I host on one Apache server using virtual hosts?
There is no hard technical limit to the number of virtual hosts Apache can run. The practical constraint is your server's resources—RAM, CPU, disk space, and bandwidth. A VPS with 2 GB of RAM and a modern CPU can comfortably run three to five low-to-medium traffic WordPress sites. Beyond that, monitor resource usage with tools like htop and consider upgrading or distributing sites across multiple servers.
Can I use Nginx instead of Apache for this same virtual host setup?
Yes. Nginx uses a similar concept called server blocks instead of Apache virtual hosts, and it generally handles high concurrent connection loads more efficiently. The trade-off is that Nginx does not support .htaccess files, so all URL rewrite rules must be configured at the server level. Apache is often easier for WordPress administrators because WordPress manages its own .htaccess rules automatically.
What PHP version should I install for WordPress on Apache?
PHP 8.2 or 8.3 is the current recommendation. WordPress 6.x requires a minimum of PHP 7.4, but older versions lack recent security patches and run significantly slower. Ubuntu 24.04 ships with PHP 8.3 by default, which is the best choice for new installations.
How do I add a third WordPress site to my existing Apache server?
Create a new database and database user in MySQL, create a new directory under /var/www/, write a new virtual host configuration file in /etc/apache2/sites-available/, enable it with a2ensite, download WordPress into the new directory, set file ownership, and obtain an SSL certificate with Certbot. The process is identical to the steps above—each site is an independent unit.
Do I need to configure a firewall if my server is behind a cloud provider's security group?
Yes, defense in depth matters. Cloud provider security groups filter traffic at the network level, but a host-based firewall like UFW adds a second layer of protection directly on the server. If someone misconfigures a security group rule, UFW still blocks unauthorized access. Keep both layers active.
Conclusion
Running multiple WordPress sites on a single Apache server with virtual hosts is a practical, cost-effective approach that gives you independent control over each site's configuration, database, and security. The key steps—setting up the LAMP stack, installing PHP-FPM for modern PHP processing, creating separate databases, configuring Apache virtual hosts with AllowOverride All, deploying WordPress to isolated directories, and securing each domain with Let's Encrypt SSL—establish a production-ready foundation for any number of sites on one machine.
Once your sites are running, the post-installation checklist helps you close the security and performance gaps that a fresh WordPress installation leaves open. And if the ongoing maintenance overhead of managing Apache configurations, PHP updates, and backups starts to outweigh the benefits of doing it yourself, exploring managed WordPress hosting plans is a practical way to reclaim your time without sacrificing the control you have built.

