Tutorial

How To Set Up Multiple WordPress Sites on a Single Ubuntu VPS

Published on August 22, 2013
How To Set Up Multiple WordPress Sites on a Single Ubuntu VPS

Status: Deprecated

This article covers a version of Ubuntu that is no longer supported. If you are currently operate a server running Ubuntu 12.04, we highly recommend upgrading or migrating to a supported version of Ubuntu:

Reason: Ubuntu 12.04 reached end of life (EOL) on April 28, 2017 and no longer receives security patches or updates. This guide is no longer maintained.

See Instead:
This guide might still be useful as a reference, but may not work on other Ubuntu releases. If available, we strongly recommend using a guide written for the version of Ubuntu you are using. You can use the search functionality at the top of the page to find a more recent version.

Introduction

WordPress is a popular CMS (content management system) that can help you get your site off of the ground quickly and easily. Sometimes, you need to host multiple, unrelated sites on the same server.

This guide will cover how to host two separate WordPress instances on one VPS. They will each have their own domain name. This is different from setting up multisite.

We will accomplish this through the use of virtual hosts. This guide will use an Ubuntu 12.04 VPS server, but other distributions should function in a similar way..

Prerequisites

This guide has a few requirements that are covered in-depth in some of our other articles. Before you begin, make sure you have completed the following:

At this point, you should have LAMP installed on Ubuntu and both of your domain names should be pointing to your droplet.

Ensure that this is the case by visiting your domain names in a web browser. Both domains should give you the same default Apache index page:

Default Apache index page

If your domains do not lead to this page, then either you need to wait for the DNS changes to propagate, or you have misconfigured something in the previous steps. Do not continue until this is resolved.

Download Wordpress

When you are ready, log into your server and change to your home directory. We will download the files here:

cd
wget http://wordpress.org/latest.tar.gz

Unzip and decompress the archive file by issuing the following command:

tar xzvf latest.tar.gz

Create Site Databases and Users

Before we continue, we need to configure an independent database and user for each site within MySQL. This will ensure that the site data is separate.

For the purposes of this guide, we will be using the following information:

Site Name firstsite.com secondsite.com
Database Name FirstDatabase SecondDatabase
Database User FirstUser SecondUser
Database Password FirstPassword SecondPassword

The table above is provided to give you context for the commands we will be using. Substitute your own information when you are filling out the commands that follow.

Log into MySQL using the administrator account you configured during the MySQL installation:

mysql -u root -p

You will be prompted for the MySQL root password and then you will be dropped into a MySQL prompt.

Create the two databases with the following commands:

CREATE DATABASE FirstDatabase;
CREATE DATABASE SecondDatabase;

Create a user that will be associated with each database:

CREATE USER FirstUser@localhost;
CREATE USER SecondUser@localhost;

Next, set up the password access for each account:

SET PASSWORD FOR FirstUser@localhost= PASSWORD("FirstPassword");
SET PASSWORD FOR SecondUser@localhost= PASSWORD("SecondPassword");

Finish up by granting privileges to the new users. This associates the database users with their respective databases and grants them appropriate permissions:

GRANT ALL PRIVILEGES ON FirstDatabase.* TO FirstUser@localhost IDENTIFIED BY 'FirstPassword';
GRANT ALL PRIVILEGES ON SecondDatabase.* TO SecondUser@localhost IDENTIFIED BY 'SecondPassword';

Refresh MySQL's privilege information to implement the changes:

FLUSH PRIVILEGES;

Exit out of MySQL to return to the shell session:

exit

Configuring Site Root Directories

We will be installing both of the sites within individual directories in the web root of our server.

Change to the "/var/www/" directory:

cd /var/www

Create a directory for each of our sites. These will store the site files:

sudo mkdir FirstSite
sudo mkdir SecondSite

Copy the sample configuration before we move the web contents into our folders:

cp ~/wordpress/wp-config-sample.php ~/wordpress/wp-config.php

Finally, copy the files to the directories you created under the web root of the server:

sudo rsync -avP ~/wordpress/ /var/www/FirstSite/
sudo rsync -avP ~/wordpress/ /var/www/SecondSite/

Give ownership of the directories to the Apache web user and then add your linux username to the web group:

sudo chown www-data:www-data * -R
sudo usermod -a -G www-data linux_user_name

WordPress Configuration

We will configure each site with the information about our sites.

First Site Configuration

Change directories to the first site's document root:

cd /var/www/FirstSite

Open the WordPress Configuration file for editing:

sudo nano wp-config.php

Find the section that contains the fields below and substitute the database, username, and password for your first site:

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'FirstDatabase');

/** MySQL database username */
define('DB_USER', 'FirstUser');

/** MySQL database password */
define('DB_PASSWORD', 'FirstPassword');

Save and exit.

Second Site Configuration

Change directories to the second site's document root:

 cd /var/www/SecondSite

Open the WordPress Configuration file for editing:

sudo nano wp-config.php

Find the same section you edited for the previous site. You will be entering information for the second site this time.

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'SecondDatabase');

/** MySQL database username */
define('DB_USER', 'SecondUser');

/** MySQL database password */
define('DB_PASSWORD', 'SecondPassword');

Save and exit.

Apache Virtual Host Configuration

We need to configure Apache to direct traffic from each domain to their respective directories. We will do this by creating separate virtual host files for each domain.

Change the directory to Apache's available sites directory:

cd /etc/apache2/sites-available

Create a new virtual host file for each site by copying the default virtual host file:

sudo cp default FirstSite
sudo cp default SecondSite

First Site Virtual Host Configuration

Open the first file you copied to configure the virtual host for the first site:

sudo nano FirstSite

Change the information in the file to match the following. Remember to substitute the information in red to match your first site:

<VirtualHost *:80>
	ServerAdmin your_email_address
	ServerName firstsite.com
	ServerAlias www.firstsite.com
	
	DocumentRoot /var/www/FirstSite
	<Directory />
		Options FollowSymLinks
		AllowOverride None
	</Directory>
	<Directory /var/www/FirstSite>
		Options Indexes FollowSymLinks MultiViews
		AllowOverride None
		Order allow,deny
		allow from all
	</Directory>
. . .
. . .

If you need to enable pretty permalinks, you can change the "AllowOverride None" within the "<Directory /var/www/FirstSite>" block to "AllowOverride All". You can learn more about the requirements for pretty permalinks here.

After making the changes, save and close the file.

Second Site Virtual Host Configuration

Open the second virtual host file for editing:

sudo nano SecondSite

Change the information to reflect your second site's information:

<VirtualHost *:80>
	ServerAdmin your_email_address
	ServerName secondsite.com
	ServerAlias www.secondsite.com
	
	DocumentRoot /var/www/SecondSite
	<Directory />
		Options FollowSymLinks
		AllowOverride None
	</Directory>
	<Directory /var/www/SecondSite>
		Options Indexes FollowSymLinks MultiViews
		AllowOverride None
		Order allow,deny
		allow from all
	</Directory>
. . .
. . .

Save and close the file.

Final Configuration

There are a few more steps necessary to get our sites working.

First, WordPress needs an extra PHP module installed in order to function correctly. Install it by typing:

sudo apt-get install php5-gd

Next, enable the virtual host files that we created by typing:

sudo a2ensite FirstSite
sudo a2ensite SecondSite

Finally, reload Apache so that it reads our changes:

sudo service apache2 reload

Seeing the Results

In order to see your new WordPress sites, simply navigate to your domain names in a web browser.

If you have configured everything correctly, you should be greeted by a page that looks like this:

WordPress Initial Login

You can now log in and configure each site independently. These sites are completely separate and can be administered as if they exist on two entirely different VPS servers.

By Justin Ellingwood

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Justin Ellingwood
Justin Ellingwood
See author profile
Category:
Tutorial

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
40 Comments
Leave a comment...

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

I have a question regarding where the WordPress files are located after this step:

Download Wordpress When you are ready, log into your server and change to your home directory. We will download the files here:

I have looked elsewhere for “best practices” for installing WordPress to handle multiple blogs and I need enlightenment.

Can someone explain why software such as WordPress is not installed into a subdirectory of /usr/bin ? MySQL lives at /usr/bin/mysql

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
August 25, 2013

@billmarel: MySQL is binary software. WordPress is just a bunch of php scripts – a regular website. Websites shouldn’t be stored in /usr/bin.

I hope that clears stuff up :]

Not really:

I have a question regarding where the WordPress files are located after this step:

Download Wordpress When you are ready, log into your server and change to your home directory. We will download the files here:

Why does WP need to be installed in my home directory?

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
August 25, 2013

@billmarel: WP doesn’t need to be installed in your home directory. You can install it <em>anywhere</em> you like. However, installing it in your home directory is the easiest way to do it without having any permissions issues et al.

I had mucho problemo making none default permalinks work in WordPress. After much hair pulling, I found this article:

http://wordpress.org/support/topic/pretty-permalinks-problem-not-found?replies=15

In that post the author rem’d out AllowOverride to make permalinks work

After reading this on apache: http://httpd.apache.org/docs/2.2/mod/core.html#allowoverride I elected to set the AllowOverride to All.

Justin Ellingwood
DigitalOcean Employee
DigitalOcean Employee badge
August 29, 2013

I’ve updated the article to mention that AllowOverride must be set to “All” if you need pretty permalinks to work. Thanks for the suggestion!

Permalinks in wordpress works with .htaccess files. They are special config files for single website.

If you want to learn more about them you can find a nice read here: http://net.tutsplus.com/tutorials/other/the-ultimate-guide-to-htaccess-files/

chown www-data:www-data * -R

Nooo! Use suexec / suphp / mod_ruid2 for security reason.

@digi I followed this guide and all was fine but reading what you wrote: chown www-data:www-data * -R Nooo! Use suexec / suphp / mod_ruid2 for security reason. Could you explain what should be done inside this Howto to use mod_ruid2 ? I searched on Google but didn’t find any clear howto I could use.

Done. Thank you for this guide! Some follow-up questions for what happens after…

Correct me if any of the following steps are wrong…

  1. Let’s say that FirstSite was originally hosted on Dreamhost. First I’m going to add all the necessary DNS records to DigitalOcean.

  2. Then I am going to log in to the domain registrar and change the DNS servers to point to NS1.digitalocean.com / NS2… / NS3…

  3. Then what? My understanding is that now the database is full of values like “http://xx.xx.xx.xx/firstsite.com” when I want it to be “http://firstsite.com” . I find this to be a problem - I don’t think that Wordpress will just up and solve that on its own - so what should be done?

…I hit enter too early. Should steps 1 and 2 of my comment be completed before performing the site installation?

When I attempt to log into Site2, it’s actually logging me into Site1. Any ideas why the URL is changing to the first domain?

Correction, all links on Site2 show the Site1 domain in the URL before I click them, clicking on them does indeed attempt to take me to Site1. Is there a setting to prevent this?

For those interested, I found it helpful to change the URL in the database.

http://www.lanexa.net/2011/08/how-to-change-the-wordpress-site-url-using-mysql-command-line/

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
October 1, 2013

@Andrew: Is it working fine now?

Hi ! After install, if there is still a problem with pretty links, try this to enable mod rewrite with this command line :

sudo a2enmod rewrite

then reload apache with this :

sudo service apache2 reload

works fine 4 me.

Would it not be better to change the ownership/permissions as so:

sudo chown _R $USER:www-data *

Where $USER is the non-root user you use to FTP/SFTP and * is the directory such as /var/www/domain.com/htdocs.

It doesn’t seem a good idea to me to have Apache user (www-data) own the files. It would seem better to chown as above and then change the permissions on directories and files as follows:

Directories: 755 Files: 644

In specific cases where Apache needs to write to directories and files (such as in wp-uploads, the .htaccess file and wp-config) then change the files to 664 and directories to 775.

I can’t think why that setup wouldn’t work and it would seem a more ‘secure’ setup, with Apache limited in it’s write access to only the files it needs.

Temporary changes could be permitted as needed to allow Wordpress auto updates by temporarily setting:

sudo chown _R www-data:www-data *

…and then changing back once done. Yes it’s slightly more work (a couple commands) but it seems it would be a ‘safer’ setup, right?

Actually, I suppose going one better in terms of locking thing down could possibly be:

sudo chown -R $USER:$USER *

on the htdocs directory and

sudo chown -R $USER:www-data for ONLY the wp-content folder and below and allow temporary ownership when writing to wp-config.php or .htaccess

Directory and file permission as in the above comment (755 and 644 on all then 775 and 664 for wp-content) but then…

You could use the following permissions to make these two files more ‘secure’:

.htaccess = 644 wp-wonfig.php = 600

You’d have to update .htaccess and wp-config.php manually as well as do any wordpress updates manually with this though right?

What do you think, would this setup be ‘better’ security wise?

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
October 19, 2013

@heff101: It’s definitely more secure than just allowing write access to all of the files however keep in mind you won’t be able to use Wordpress’s auto-updating feature if you don’t allow it to write to its files.

I have configured a site1, it works quite well. I now want to create a site2 then just do the steps on the secondsite it?

I did all the steps above, but when i access the domain i see a list of files & directories under /var/www/

I’VE FIGURED IT OUT!

you forgot to do this:

sudo a2ensite example.com

When reviewing the follow ing section"sudo usermod -a -G www-data linux_user_name" is this creating the username or what user name would this be

When this is computed it doesnt pull up the wordpress config page. What am i missing

linux_user_name would be root if you are using the default settings and haven’t created any new user.

Regards

Abhay

Thanks for the response. I used root for this but received database connections error and this is the droplet info - LAMP on Ubuntu 12.04

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
February 8, 2014

@shawn.knutson: Did you install MySQL? Is it running <pre>sudo netstat -plutn | grep 3306</pre>

So how do I set this up so I can upload using ftp with my user account that I setup?

Hi Jake, Did you ever figure this out? I get the error

Unable to locate WordPress Content directory (wp-content)

Which I am assuming is related to this.

I followed the tutorial steps for Ubuntu Server 12.04 and Apache2.

I downloaded the WordPress files and copied them to two separate directories:

/var/www/blog1 /var/www/blog2

I copied the wp-config-sample.php file to wp-config.php in each of these two directories.

I created the two separate MySQL databases and in each of the wp-config.php files added in the that matched the MySQL database host, database name, password, user information.

When I access the sites’ internal URLs I keep getting an error: Error establishing a database connection

I can log in to the MySQL databases just fine using the $mysql -u username -p just fine.

I double-checked that the above sites were running by temporarily putting a default.html file in each and a web page showed up just fine.

Any other steps that I might be missing appreciated!

Tony.

More to this. When I ran the install.php file in the blog1 directory i got this error: Can’t select database We were able to connect to the database server (which means your username and password is okay) but not able to select the BVCWORD database.

Are you sure it exists? Does the user bvcword have permission to use the BVCWORD database? On some systems the name of your database is prefixed with your username, so it would be like username_BVCWORD. Could that be the problem? If you don’t know how to set up a database you should contact your host. If all else fails you may find help at the WordPress Support Forums.

In MySQL I ran mysql> show databases like ‘blog1’; ±-------------------+ | Database (blog1) | ±-------------------+ | blog1 | ±-------------------+ 1 row in set (0.00 sec)

  • so I can see the database is created

I fixed it! In the wp-config.php file the database name is case-sensitive. I had put in the database name in upper case. I changed it to lower case and I am up and running:

  1. dyndns used for my dyn dns service
  2. ip aliasing to setup multiple ip addresses on one interface
  3. using router port forwarding so I can use multiple port numbers to listen on

So, I have public-facing wp blogs:

www.blog1.com:8080 [router fwds to internal 192.168.1.90 listening on 8080] www.blog2.com:8081 [router fwds to internal 192.168.1.91 listening on 8081] www.blog3.com:8083 [router fwds to internal 192.168.1.92 listening on 8082]

Good tutorial, everything worked out great! But have a questioning can i add a third or more wordpress later on following the same steps?

Hi, Can you please help me to differentiate the two installations while I haven’t tied a domain to them yet? Now, if I go to http://my.ip.add.ress, I get to the first website - the installation for it is completed. But I am not sure how to get to the second website, since no domains are set for either of them, and the installation hasn’t been completed yet (second database is empty). Could you please give me a hint on how to do something like http://my.ip.add.ress/FirstWebsite and http://my.ip.add.ress/SecondWebsite to access them both, or some other way?

Thanks!

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
April 5, 2014

@info: Yes!

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
April 5, 2014

@wphacker: You can manually add the domains to your local hosts file until you update the DNS records.

I can’t get my permalinks working… I have set my virtual host to AllowOverides All and added the wordpress .htaccess but still not working.

Anyone have any tips?

Thanks for the tutorial. How many wordpress can I install on a 1gb ram server with nginx? Please let me know.

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
April 10, 2014

@tislam100: You can host as many wordpress websites as you want, however, depending on how many and what kind of plugins you have, the traffic you get, what webserver you’re using, and many other factors, you might be limited by performance. There’s no hard limit on how many websites you can host on a single droplet, but once you host “too many” websites on a single droplet, you will start to see performance drops. So it’s more of a trial and error.

Hi, if someone could help me, I can’t for the life of me work this out.

I have followed the instructions and looked at instructions on the internet and can’t seem to get a positive result.

I have set my virtual host to look like

<VirtualHost *:80> ServerAdmin webmaster@domain.com ServerName domain.com ServerAlias domain.com

    DocumentRoot /var/www/domain.com
    <Directory />
            Options FollowSymLinks
            AllowOverride None
    </Directory>
    <Directory /var/www/domain.com>
            Options Indexes FollowSymLinks MultiViews
            AllowOverride None
            Order allow,deny
            allow from all
    </Directory>

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
            AllowOverride None
            Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
            Order allow,deny
            Allow from all
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined

Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">

    Options Indexes MultiViews FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
    Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>

</VirtualHost>

So basically it is the the default config, but with the domain name changes.

Now the problem occurs, if I browse to www.domain.com, it points me to the folder /var/www/domain.com. But if I browse to http://domain.com it points me to /var/www.

From everything I have read, I have setup both ServerName and ServerAlias correctly. If anyone could shed some light I would be grateful.

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.