1

How do I setup 3 different Wordpress installations on 3 different servers, all of which connect to a single database and also share the same data?

I'd like to set up 3 different servers. One for development, QA/Staging, and Production. Each site should be isolated from the other and they are simply used to display the same data from the database, meaning:

  • Developers will be working in the development server, meaning that this installation will be in a state of constant change.
  • The QA/Staging server will be in less of a state of change as QA folks will be testing functionality added from the development team.
  • Production will only be updated periodically from tested and working code thats vetted through the QA/Staging server

Please not that sharing "upload" resources is not an issue as I plan on using AWS S3 service to store all of my resources (ex. images), while also using AWS CloudFront to act as a CDN to serve all said resources.

8
  • You can put the same database details in each installs wp-config.php but you're going to run into other problems that will require non-WordPress solutions, e.g. if someone uploads an image in staging, production and dev will be updated, but only staging has the image. Perhaps you should look into database replication or daily backups
    – Tom J Nowell
    Jun 22, 2016 at 0:48
  • Also, can you edit your question so that it can have a concrete answer? This is a Q&A site not a discussion forum and you need to be able to mark an answer as correct
    – Tom J Nowell
    Jun 22, 2016 at 0:49
  • Hi @TomJNowell thanks for the response. I edited my question to hopefully correct the issue you pointed out, such that it can now be marked as correct. I also added clarification to the other issue you pointed out regarding the storage of resources/assets by detailing that I'll offload storage from the servers to AWS S3/CloudFront as a means of storing resources/assets (S3) and serving it through a CDN (CloudFront).
    – Corey
    Jun 22, 2016 at 0:59
  • @TomJNowell I was able to use the same database details (ex. hostname, user name, user password, db name) BUT I had to change the table prefix. Meaning that each installation connects to the same DB but each installation creates it's own tables (hence the differenct table prefix for each one), which is not the desired result. I also explicitly defined the WP_HOME and WP_SITEURL in my wp-config.php file and that didn't help either.
    – Corey
    Jun 22, 2016 at 1:06
  • a suggestion, instead of worrying multiple databases/domains/installs you could isolate code changes to child themes so you can switch between those on a per user/role basis for testing/development..?
    – majick
    Jun 22, 2016 at 2:21

2 Answers 2

0

To elaborate on my suggestion, here is some working code:

// hook in before theme is loaded
add_action('plugins_loaded','custom_maybe_switch_themes');
function custom_maybe_switch_themes() {
    if (!is_user_logged_in()) {return;}
    if (!current_user_can('manage_options')) {return;}

    // check for query request eg. ?usertheme=theme-slug
    if (isset($_REQUEST['usertheme'])) {
        // sanitize request
        $usertheme = strtolower(sanitize_title($_REQUEST['usertheme']));
        global $current_user; $current_user = wp_get_current_user();

        // maybe reset user meta stylesheet
        if ($usertheme == 'reset') {delete_user_meta($current_user->ID,'stylesheet'); return;}

        // validate theme
        $theme = wp_get_theme($usertheme);
        if ($theme->exists()) {
             delete_user_meta($current_user->ID,'stylesheet');
             add_user_meta($current_user->ID,'stylesheet',$usertheme);
        }
    }
}

// add filter to stylesheet option
add_filter('pre_option_stylesheet', 'get_user_stylesheet');
function get_user_stylesheet($stylesheet) {
    if (!is_user_logged_in()) {return $stylesheet;}
    if (!current_user_can('manage_options')) {return $stylesheet;}

    // check user meta stylesheet
    global $current_user; $current_user = wp_get_current_user();
    $userstylesheet = get_user_meta($current_user->ID,'stylesheet',true);
    // if we have a value use it instead
    if ($userstylesheet) {return $userstylesheet;}
    return $stylesheet;
}

To switch to a theme on a user basis, use ?usertheme=theme-slug

...and to reset just use ?usertheme=reset

Since all the theme code is loaded dependant on the stylesheet used, you could set up Child Themes directories for Live, Staging and Development (with the same Parent Template) and switch between themes really easily as a developer and see the results immediately on the same domain. :-)

The only caveat I can think of is testing major plugin updates, you would still need a development environment for that purpose and maybe sync the database across to test them with the current database content. This is only because you don't know if they will change their options database table structure (though rare, there is no going back so you could break a live site that way.)

Something further would be needed to test the site output for logged out users, but that could be done with a different querystring for one-off loads, or with cookies instead of user meta for a similar persistent result.

Anyway, the advantage of being able to have code snippets organized in files for testing in development and staging on the same domain, making pushing new changes between them really easy, and to not have to worry about database syncing all the time (though that's another workable approach) makes this a very convenient way of doing things I think.

2
  • This is a great idea... I'm not sure if this solves all of my problems but I think its a great idea that solves the majority of my issues. It seems the only real solution is to create multiple staging areas that connect individual WP environments to their own independent databases. Meaning that I'd have to sync each database. That said, thank you again your suggestion is very helpful.
    – Corey
    Jun 26, 2016 at 17:20
  • just had a bit of a look around and found this by @Rarst that is a properly threshed out toolbar for doing this, with capability options and cookies: github.com/Rarst/toolbar-theme-switcher :-) as for having a test development setup also for the other things, you might want to look around for bash or wp cli scripts that do the syncing for you, eg: github.com/jplew/SyncDB
    – majick
    Jun 27, 2016 at 2:48
0

You can use subdomains for your dev and QA installs. Such as qa.domain.com and dev.domain.com. When the subdomains are created sub directories are usually created too. You can install an additional wordpress in each subdomains directory. Then create 2 additional databases. Backup the production database and load it to the 2 new databases. Set up your config.php files for these new database and you have 2 new servers. You will have to make some updates to the databases. At least two location home and site_url in the _options table. I usually open the .sql file in a text editor and seek and replace domain.com with sub.domain.com.

4
  • When you say that sub-directories are usually created when the sub-domains are created, what do you mean by that? Are you referring to the directories that the virtual host would point to? Meaning that all of the Wordpress installations would be on the same server?
    – Corey
    Jun 22, 2016 at 2:52
  • Yes thats exactly what i meant
    – stoi2m1
    Jun 22, 2016 at 4:07
  • Thank you for the suggestion but as I said the installations are on different servers, so this isn't really an option.
    – Corey
    Jun 22, 2016 at 10:49
  • Ah, I see that now as I read more closely. Are these your servers or servers provided by a host? You will need to now the address of the mysql servers. You can either ask your host what this is or if these are your servers we can get into more details for that later.
    – stoi2m1
    Jun 24, 2016 at 9:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.