Mastodon

How to Host Multiple WordPress Sites on One VPS with Nginx Server Blocks

  1. Home
  2. Guides
  3. How to Host Multiple WordPress Sites on One VPS wi...

Nginx server blocks let a single VPS serve multiple, completely separate websites, each with its own domain, its own WordPress install, and its own database, while sharing the same Nginx, PHP-FPM, and MariaDB installation underneath. This is how freelancers and agencies run several client sites on one server instead of paying for a separate VPS per client, and it works well as long as each site is kept properly isolated at the file and database level.

This guide adds a second WordPress site to a VPS that already has one running, covering the directory structure, database separation, and Nginx configuration needed to keep sites from interfering with each other. It assumes you have already deployed one WordPress site following the [guide to deploying WordPress with Nginx and PHP-FPM](/guides/deploy-wordpress-nginx-php-fpm), so Nginx, PHP-FPM, and MariaDB are already installed and working.

Step 1 - Creating a Directory and Database for the New Site

Each site needs its own directory under /var/www so its files never mix with another site's. Create one named after the new domain:

sudo mkdir -p /var/www/second-example.com
sudo chown -R www-data:www-data /var/www/second-example.com

Each site also needs its own database and database user; sharing a database between two WordPress installs, even with different table prefixes, is a mistake that makes backups, migrations, and troubleshooting far harder than they need to be. Log into MariaDB and create both:

sudo mysql
CREATE DATABASE second_example_wp;
CREATE USER 'second_example_user'@'localhost' IDENTIFIED BY 'a-strong-unique-password';
GRANT ALL PRIVILEGES ON second_example_wp.* TO 'second_example_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

The new site now has an isolated directory and an isolated database, with a dedicated database user that has no access to the first site's database. The next step is installing WordPress into that directory.

Step 2 - Installing WordPress Into the New Directory

Download and extract a fresh copy of WordPress core into the new site's directory:

cd /tmp
curl -O https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
sudo cp -a wordpress/. /var/www/second-example.com/
sudo chown -R www-data:www-data /var/www/second-example.com

Copy the sample config and edit it with the new site's database credentials:

cd /var/www/second-example.com
sudo cp wp-config-sample.php wp-config.php
sudo nano wp-config.php

Set DB_NAME, DB_USER, and DB_PASSWORD to the values created in step 1. WordPress core is now in place with a config pointing at its own dedicated database, fully separate from any other site on the server.

Step 3 - Creating an Nginx Server Block for the New Site

An Nginx server block is what tells the server which site to serve for a given domain name; without one, requests for the new domain will not resolve to the new WordPress install even once DNS points at the VPS. Create a new config file:

sudo nano /etc/nginx/sites-available/second-example.com

Add a server block scoped to the new domain and directory, matching the PHP-FPM configuration used by the first site:

server {
    listen 80;
    server_name second-example.com www.second-example.com;
    root /var/www/second-example.com;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

The server_name directive is what separates this site from every other site on the VPS; Nginx uses it to route each incoming request to the correct root directory based on the domain in the request. This config is scoped entirely to second-example.com and will not affect the first site's server block.

Step 4 - Enabling the Site and Testing the Configuration

Symlink the new config into sites-enabled to activate it:

sudo ln -s /etc/nginx/sites-available/second-example.com /etc/nginx/sites-enabled/

Test the Nginx configuration before reloading; a syntax error in any server block will stop Nginx from reloading at all, which would take down every site on the server, not just the new one:

sudo nginx -t

Output:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Once the test passes, reload Nginx to apply the new config without dropping existing connections to the first site:

sudo systemctl reload nginx

Nginx is now serving both sites from the same server, each fully isolated by directory, database, and server block.

Step 5 - Pointing DNS and Adding SSL

The new domain needs an A record pointing at the VPS's IP address before it will resolve to this server at all; the [guide to pointing a domain to your VPS](/guides/point-domain-to-vps-dns-a-records) covers creating and verifying that record. Once DNS is resolving correctly, issue an SSL certificate for the new domain following the [Let's Encrypt SSL guide](/guides/install-ssl-lets-encrypt-nginx), which handles a second domain on the same server exactly the same way it handled the first.

Adding Further Sites

Every additional site follows the same five steps: a new directory and database, a fresh WordPress install pointed at that database, a new server block scoped to the new domain, enabling and testing the config, then DNS and SSL. A modest VPS can comfortably run several low-to-moderate traffic WordPress sites this way; the main resource to watch as you add sites is RAM, since each site's PHP-FPM pool and any caching layer consumes memory independently. The [guide to monitoring VPS resource usage](/blog/monitor-vps-resource-usage-cpu-ram-disk) covers how to keep an eye on that as the server takes on more sites.

Your VPS Is Now Hosting Multiple Sites

You now have two isolated WordPress installs running on one VPS, each with its own files, database, and Nginx server block, with a repeatable process for adding more. From here, the same isolation approach applies whether you are adding a third client site or setting up a staging copy of an existing one under a separate subdomain.

Get a VPS

Follow along with your own server. Plans from £7.98/month.

View VPS Plans

More Guides

How to Migrate WordPress from Shared Hosting to a VPS

Move a live WordPress site from shared hosting to a VPS: database export with my...

Setting Up SSH Key Authentication on Ubuntu

How to set up SSH key authentication on Ubuntu and disable password logins to se...

Deploying WordPress on a Linux VPS with Nginx and PHP-FPM

Install WordPress on a Linux VPS with Nginx, PHP-FPM, and MariaDB. Complete step...