Using the same database for development and staging environments with WordPress Network

Here at Dude, we use the same database for the site’s all development and staging environments. With this neat arrangement, we always have the latest content shared between our developers, which is crucial as the team might be working on the same project at the same time. No need for database migrations or moving dump files. Backend developer can just tell to frontend developer that the new page is there and needs styling.

And as stated, the client and project manager sees the exact same content right away on a staging environment. Some might wonder, does this not cause problems? In fact, it reduces those because developers do see right away the real content clients update to their soon-to-be new site. We can spot any issues quickly and if the client reports a bug, there’s no need to do all the database migration jazz. Sharing the databases has proven to be a vital part of our processes and increased our efficiency.

The problem with WordPress Network

Normally our Dudestack takes care of fixing the URL’s based on the current environment.

Unfortunately, this does not work with WordPress Network installation, because WordPress handles domains and URL’s bit differently when Network functionalities are enabled. For this reason, we have separated development and staging databases previously when working with WP Network projects.

It’s something we have lived with for some time and get used to. The annoyance has been bugging on my head nevertheless. Currently, we are working with a very large WP Network project and not sharing the database would have caused many many problems. So I really had to put some proper thought on getting WP Network to work with a shared database.

Finding a solution

After some digging and testing, changes needed to get WP Network working with shared database and different domains were quite small.

In this project, we are having the sites on sub-directories and using sunrise.php to map the URL to the correct site. Those sunrise.php files might, and probably will be different on each project, so following lines of code won’t necessarily work on all setups.

In the database, domain for our sites is project.test and staging environment domain is project.vaiheessa.fi. Sunrise makes database query to match the domain and path to determine on which site the user is. So, logically the first step is to get the sunrise to detect sites also with staging environment domain which is set by DOMAIN_CURRENT_SITE constant. This is done by running simple string replacement to $domain value between defining it and actually using it for the first time.

if ( 'production' !== getenv( 'WP_ENV' ) ) {
  $domain = str_replace( DOMAIN_CURRENT_SITE, 'project.test', $domain );
}

That trick makes the site work to some extent, but permalinks and few other things are still bit broken because WP still finds the project.test domain from the database in some situations. To fix all the permalinks and other stuff pulling the wrong domain, we are going to leverage the WordPress filter system to replace the domain with the correct one.

function _ss_fix_dev_stage_url( $url ) {
  return str_replace( [ 'project.test', 'project.vaiheessa.fi' ], DOMAIN_CURRENT_SITE, $url );
}

// Fix the domain for shared dev and stage
if ( 'production' !== getenv( 'WP_ENV' ) ) {
  add_filter( 'get_site', function( $site ) {
    $site->domain = DOMAIN_CURRENT_SITE;
    return $site;
  }, 1, 1 );

  add_filter( 'network_home_url', '_ss_fix_dev_stage_url', 1, 1 );
  add_filter( 'home_url', '_ss_fix_dev_stage_url', 1, 1 );
  add_filter( 'option_home_url', '_ss_fix_dev_stage_url', 1, 1 );
  add_filter( 'option_siteurl', '_ss_fix_dev_stage_url', 1, 1 );
  add_filter( 'network_site_url', '_ss_fix_dev_stage_url', 1, 1 );
}

The full sunrise.php used can be found from this Github Gist.

Hopefully, this helps someone who is having the same problem. Though sharing databases between environments is supposedly a quite rare approach.