How do I configure a CMS installation like WordPress or Drupal, to run on multiple websites as a replicate of one main CMS installation. Owned and managed by different server accounts all hosted on the same server.
My setup is similar to the following:
- Webserver software:
nginx
running together withapache2
(VestaCP) - Document Root:
/home/user/example.com/public_html/
What do I mean with, “a replicate of one CMS installation”:
As described in the diagram all users owning a folder where DocumentRoot is pointed at, will be able to replicate/create an instance of/use the CMS installation.
You probably need the following files to run the CMS installation:
- DocumentRoot/configuration.php – specify with what data the CMS should load.
- DocumentRoot/index.php – Call and render the specified output.
WordPress
To sort out what approach will work out the best I could come up with these two different scenario’s:
- where there is only one symbolic linked folder, this folder includes the wordpress core files.
- all the wordpress core files and folders are symbolically linked.
In both scenario’s the setup is trying to require their own config file (my-config.php
), so not the one what’s symbolically linked.
1: Symbolic linked wordpress folder:
wordpress/wp-config.php
<?php
require_once( ROOT_PATH . 'my-config.php');
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
require_once(ABSPATH . 'wp-settings.php');
wordpress/test.php
<?php echo 'Path is '.getcwd(); ?>
DocumentRoot/index.php
<?php
define('ROOT_PATH', dirname(__FILE__) . '/');
require('wordpress/index.php');
DocumentRoot/my-config.php
Contains everything except the code inside wordpress/wp-config.php
<?php
define('WP_HOME', ... );
define( 'WP_CONTENT_URL', ... );
etc..
The symbolic link is as following
ln -s /path/to/wordpress/ .
My results
- [Visited URL] – [Testing results]
- ../ – Redirect to: ../wp-admin/install.php + 404
- ../wp-admin/ – 404
- ../wordpress/ – WSOD
- ../wordpress/wp-admin/ – WSOD
- ../wordpress/test.php – Output: Path is /path/to/wordpress
2: Another approach could be something like this:
wordpress/wp-config.php
<?php
require_once('my-config.php'); // So DocumentRoot/my-config.php
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
require_once(ABSPATH . 'wp-settings.php');
wordpress/test.php
<?php echo 'Path is '.getcwd(); ?>
DocumentRoot/my-config.php
The same as the DocumentRoot config file used in scenario 1.
The symbolic links are as following
ln -s /path/to/wordpress/* .
My results
- [Visited URL] – [Testing results]
- ../ – Redirect to: ../wp-admin/install.php + WSOD
- ../wp-admin/ – WSOD
- ../test.php – Output: Path is /home/user/example.com/public_html
Conclusion WordPress
In both scenario’s the main index file redirects to the installation file. This normally happens when the connection to the database has been made but the database is still empty, so by following the installation instruction you will insert your first data. But then why does it give a WSOD?
The test file (test.php
) clears things up a bit. In the scenario 1 the path to the wordpress directory becomes the absolute path for the wordpress core files. For the scenario 2 the DocumentRoot’s path becomes the absolute path for the wordpress core files… or not?
Although not for the sub directories in the wordpress directory, as we can learn from scenario 1. For example the wp-admin
directory, files what call getcwd()
should output /path/to/wordpress/wp-admin
right? If so then it means, all calls to files within those directories will never find the file. Because the file /home/user/example.com/public_html/wp-admin/file.php
doesn’t exists! It’s not symbolically linked and so it’s only accessible via /path/to/wordpress/wp-admin/file.php
.
It’s actually fairly easy to do this, the key of course is your index files. MVC frameworks, and I’m just tossing wordpress in to that category very loosely, all have a single entry point. Obviously the entry point for most of these is the index file.
Really what it amounts to is that the only file requested is the index file, it’s really the only code that is called. The rest of the stuff that gets ran is routed because the index file is hard linked to code that knows how to do that.
So all you have to do is point the index file back to the code it’s pointed at when you move it. It doesn’t matter to the webserver where any of the files are because it doesn’t route anything to them only the index. PHP can access the files as long as the system user it is using can access the files.
It may be more difficult to have separate config files for each one, for example if you want to use a separate database. Most CMS or MVC frameworks don’t allow you to tell them where the config file is, it’s just in some arbitrary location. The hitch you will have in wordpress is that in the general settings you have the site url, and wordpress url. These unfortunately are in the database, which makes it harder to change them. Also you probably don’t want exactly the same menu for each site.
So really using the wordpress example you will have to include the config files elsewhere by piping them into the actual config file
Load it when WordPress wants it to load:
. I think your example config file is on the right track, but you will have to use separate databases, because of the site url and wordpress url..This fact actually makes it harder to maintain not easier, because wordpress wont necessarily update the right database when doing upgrades to the core.
The site url needs to be the actual domain.
The wordpress url is where your admin script is accessed from. So there is that part too to sort out, wp-admin.
Anyway good luck, and make sure to change those settings in the general tab in the WordPress admin area.
UPDATE
What I would suggest doing is making a really simple router out of the orignal config file, it doesn’t have to be fancy. You can tell on a per-request basis using
$_SERVER[HTTP_HOST]
what domain is doing the requesting. With that information you could do something as simple as this (PSUDO CODE)Then inside each site’s respective folders place a config file for the site_url, database, and what have you in the normal wp-config.
Excreta, then it’s just a matter of working out if you want to give access to the admin area to each instance of the site.
This ( only changing the original config and not wp-load.php ) might be easier to maintain because it relatively trivial to find each config file at a later point, and you are making as little impact on the wordpress core code as possible. Granted it’s unlikly wp-load would change, but is it a natural place to look for something custom to each site.
My concern with admin area is that you have to run it through wp-admin.php and not the index page. I am not that familiar WordPress’s architecture, in how it relates to loading the admin area to say for sure, but there may be some tweaking needed there..
Is this what you’re looking for?
http://jason.pureconcepts.net/2012/08/wordpress-multitenancy/
Finally!
I found a way to use one set of WordPress core files to run multiple websites on without using WP Multisite or any significant changes to the core files.
This example is based on the following structure:
At
/var/core/wp-config.php
make the following changes:Leave all other core files as you wish, you might want to add some plugins or themes to this core directory’s wp-content to make them globally available for all sites/instances.
Now we can setup an instance of this our WP MultiPress core. Below you can see the
/var/sites/alpha/wp-config.php
of the alpha site. Commonly you only have to define the Unique Keys and Salts and your MySQL settings. Next to that you can also configure a custom name for your wp-content directory.Next up is the index of the instance, have a look at the contents of
/var/sites/alpha/index.php
below.Make sure all files in
/var/core/
are available for reading, for all processes running the sites. Also don’t forget to create the symbolic links (shown with->
in the structure example).That should do it!