In this tutorial, we'll learn how to install and manage WordPress multisite on Ubuntu 24.04 server.
Introduction
When we need to host multiple WordPress sites under one roof, a Multisite network on our own KVM VPS delivers both flexibility and efficiency. Instead of installing WordPress over and over, we maintain a single codebase—streamlining updates for themes, plugins, and core itself.
In this hands-on tutorial, we’ll walk through every step on Ubuntu 24.04: from provisioning and hardening our VPS, through configuring Apache, MariaDB, and PHP, to enabling Multisite and securing the network with Let’s Encrypt wildcards. By the end, our network will be performant, secure, and ready to scale, whether we’re managing client blogs, team intranets, or educational portals. Let’s dive in and turn our KVM instance into a powerhouse for hosting many sites with minimal overhead.
Prerequisites
Before starting, make sure our new Ubuntu server is ready. The following components should be installed and configured:
- A Ubuntu 24.04 installed dedicated server or KVM VPS.
- A root user or normal user with administrative privileges.
- A domain name pointing A record to server IP.
Install and Manage WordPress Multisite on Ubuntu
1. Prepare the VPS Environment
Update and upgrade system packages
sudo apt update && sudo apt upgrade -y
Set the hostname and timezone
It’s good practice to give our server a descriptive hostname and ensure the clock is correct:
sudo hostnamectl set-hostname wp-multisite
sudo timedatectl set-timezone Etc/UTC
Create a non-root administration user
For security, we avoid operating routinely as root:
sudo adduser admin
sudo usermod -aG sudo admin
Then switch over:
su - admin
2. Install LAMP Stack
WordPress thrives on the classic Linux-Apache-MySQL-PHP stack, so let’s lay that foundation.
Install Apache
sudo apt install apache2 -y
Apache’s mod_rewrite
module is crucial for WordPress permalinks:
sudo a2enmod rewrite
sudo systemctl restart apache2
Install MariaDB (MySQL-compatible)
sudo apt install mariadb-server mariadb-client -y
sudo systemctl enable --now mariadb
Secure the installation:
sudo mysql_secure_installation
We’ll set a strong root password, remove anonymous users, and disallow remote root login.
Install PHP and extensions
sudo apt install php php-{cli,fpm,mysql,curl,gd,xml,mbstring,zip} -y
Confirm PHP-FPM is running (even though Apache will use mod_php by default, having FPM ready helps scalability):
php -v
3. Configure the Database for Multisite
Log in to MariaDB
sudo mysql -u root -p
Create a database and user
CREATE DATABASE wp_network CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'StrongPasswordHere';
GRANT ALL ON wp_network.* TO 'wp_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
We choose utf8mb4
to ensure full emoji support and best compatibility.
4. Download and Configure WordPress
Fetch the latest WordPress release
cd /var/www
sudo wget https://wordpress.org/latest.tar.gz
sudo tar -xzf latest.tar.gz
sudo mv wordpress multisite
sudo chown -R www-data:www-data multisite
sudo chmod -R 755 multisite
Configure Apache Virtual Host
Create /etc/apache2/sites-available/multisite.conf
with:
nano /etc/apache2/sites-available/multisite.conf
Add following content:
<VirtualHost *:80>
ServerName example.com
ServerAlias *.example.com
DocumentRoot /var/www/multisite
<Directory /var/www/multisite>
AllowOverride All
Require all granted
</Directory>
# Log files
ErrorLog ${APACHE_LOG_DIR}/multisite_error.log
CustomLog ${APACHE_LOG_DIR}/multisite_access.log combined
</VirtualHost>
Then enable and reload:
sudo a2ensite multisite.conf
sudo systemctl reload apache2
Point DNS to the VPS
We configure a wildcard A-record (*.example.com) pointing to our VPS IP. This allows all subdomains to resolve automatically.
5. Configure Firewall
If you have enabled UFW firewall, open HTTP and HTTPS ports:
sudo ufw allow 'Apache Full'
sudo ufw reload
6. Secure and Optimize Our Network
Enable HTTPS with Let’s Encrypt
sudo apt install certbot python3-certbot-apache -y
When we request a wildcard certificate (e.g. for *.example.com), Let’s Encrypt cannot verify ownership by a simple HTTP request—there’s no way to serve a challenge out of every possible subdomain’s folder.
To secure example.com and *.example.com, we must prove domain control via DNS (DNS-01 challenge). Here’s how we adapt our workflow:
6.1 Choose or Install a DNS Plugin
Depending on where our DNS is hosted, Certbot has a matching plugin:
Cloudflare
sudo apt install python3-certbot-dns-cloudflare
6.2 Create API Credentials
Cloudflare example
In Cloudflare dashboard, create a API Token scoped to Zone:DNS:Edit for our domain.
Save the token to /etc/letsencrypt/cloudflare.ini
nano /etc/letsencrypt/cloudflare.ini
with permissions locked down:
# /etc/letsencrypt/cloudflare.ini
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef0123
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
6.3. Run Certbot with the DNS Plugin
With our credentials in place, we request a certificate using DNS-01:
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d example.com \
-d '*.example.com' \
--preferred-challenges dns-01 \
--agree-tos \
--no-eff-email \
--email admin@example.com
certonly
tells Certbot to obtain but not auto-configure Apache.--dns-cloudflare
picks our Cloudflare plugin; swap for --dns-digitalocean, etc., as needed.--preferred-challenges dns-01
ensures no HTTP challenge is attempted.- Upon success, our fullchain and private key land in
/etc/letsencrypt/live/example.com/
.
Automate Renewal
Because DNS-01 requires API calls, we must ensure renewal can run unattended:
# /etc/cron.d/letsencrypt-dns-renew
0 3 * * * root certbot renew \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
--preferred-challenges dns-01 \
--quiet \
&& systemctl reload apache2
We’ll automatically renew certificates and secure all sub-sites.
Create the SSL site configuration
By default, certbot do not create ssl.conf file, because we have user certonly. You can try without certonly, we did try it. So we need to create it manually.
Open a new file in /etc/apache2/sites-available/
, for example:
sudo nano /etc/apache2/sites-available/multisite-ssl.conf
Paste in this content (adjust example.com and paths if needed):
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName example.com
ServerAlias *.example.com
DocumentRoot /var/www/multisite
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
<Directory /var/www/multisite>
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/multisite_ssl_error.log
CustomLog ${APACHE_LOG_DIR}/multisite_ssl_access.log combined
</VirtualHost>
</IfModule>
Save and exit (in nano: press Ctrl+O, Enter, then Ctrl+X).
2. Enable the SSL module and site
sudo a2enmod ssl
sudo a2ensite multisite-ssl.conf
Harden PHP and Apache
In /etc/php/8.2/apache2/php.ini
, set:
expose_php = Off
memory_limit = 256M
upload_max_filesize = 128M
Disable unused Apache modules:
sudo a2dismod status autoindex
sudo systemctl restart apache2
7. Initial WordPress Setup
Complete the web installer
- Browse to
http://example.com/
- Fill in database details (wp_network, wp_user, password)
- Create the first super-admin account
Enable Multisite in wp-config.php
Above the line that says /* That's all, stop editing! */, add:
define('WP_ALLOW_MULTISITE', true);
Save and reload the Dashboard.
Set up the network
- In the Dashboard under Tools → Network Setup, choose Sub-domains
- Give our network a title, accept the suggested edits, and click Install
Apply the provided code snippets
- WordPress will show two code blocks—one for wp-config.php, one for .htaccess.
- Copy the wp-config.php additions just above WP_ALLOW_MULTISITE.
- Replace WordPress’s default .htaccess in /var/www/multisite/ with the provided rules to handle rewrites.
8. Troubleshooting
- If you got Error establishing a database connection then check wp-config.php file.
- If you got The page isn’t redirecting properly then check .htaccess file and adjust it.
9. Managing Our Multisite Network
Add new sites
- At the top of the admin panel beside WordPress logo there is "My Sites" hover it and you will see "Network Admin", go to Sites → Add New
- Provide site address (subdomain), title, and admin email
- Click Add Site
Install themes and plugins network-wide
- In Network Admin, navigate to Themes or Plugins
- Install once, then Network Enable to make available to all sites
User and role management
- Manage users from Users → Network Users
- Assign global roles or let individual sites manage their own editors and authors
Performing core, theme, and plugin updates
- Updates are applied centrally in Network Admin under Dashboard → Updates
- We back up our database and files before major version leaps, using tools like WP-CLI or rsync
Backup strategy
Schedule daily database dumps:
mysqldump -u wp_user -p wp_network | gzip > /backup/wp_network_$(date +%F).sql.gz
Archive uploads and themes directory with tar or your preferred backup agent
Scaling considerations
- If traffic grows, we can split the database off to a managed DB service
- Use load balancers and multiple web servers behind a reverse proxy like HAProxy or Nginx
Wrapping Up
In this tutorial, we've learnt how to install and manage WordPress multisite on Ubuntu 24.04 server. By following these steps, our KVM VPS on Ubuntu 24.04 will host a robust WordPress Multisite network—easy to maintain, cost-effective, and ready to scale as our needs grow.
We’ve covered everything from the initial server hardening, classic LAMP stack setup, enabling multisite, to best practices for security, backups, and performance. Now, our network is ready to welcome many sites under one umbrella, letting us focus on content and growth rather than repetitive maintenance.