A quick intro

In this article, we will delve into the specifics of turning a running WordPress Multisite in production into a well organised, development-ready, version control, dev/staging environnment, as well as the deployment process (not automatic for now).


Recently, I had to create a local/staging/production environnement for a rather large WordPress Multisite instance. The process was not that obvious at first so I created documention for it here, for my future self, as well as for probably other people in similar situations.

Since the instance was already running in production, with Woocommerce and large amount of custom plugins, I had to be careful not lose any data and to ensure the deployement process would be as smooth as possible.


The production server is a solid baremetal server with enough capacity to run 3 to 4 time the production site, so I decided to keep the staging on the same server, which is probably the best for testing.

An alternative would have been to virtualize the whole thing and have 2 virtual machines, one for production and one for staging, that could then be moved around and run on nearly any infrastructure, but I did not have time for that, and also, if virtualizing anything, I’d rather try to evolve toward Docker- but this come with complexities of its own and right now that was rulled out.

For the local version, I used Vagrant/Homestead (see more about it here or later in the article)

The whole thing is working with Nginx

So in short we have :

  • Original instance on server (so that we have a fall back if we f-up anything on the way)
  • Staging instance on server
  • Production instance on server
  • Local Instance on Homestead VM

Overall process

Let’s just go over the whole process to understand what is going to happen before devling into the details of each step.

1. Create a test composer-based local version

  • Dump production database
  • Save uploads
  • Set up locally
  • One time process to composerify the wordpress install (this is taking some time, get ready)

2. Create staging from local version

On production

  • Dump production database
  • Save uploads

On staging

  • Set up nginx
  • git clone the dev version
  • composer install
  • db import
  • copy uploads from prod.
  • set up local-config.php
  • update url: wp search-replace prod-domain test-domain --network (run it twice in a row)
  • update db : wp core update-db --network
  • update woocommerce : for loop to do wp wc update --url="https://network/url";
  • Check everything workds

3. First time creation of production from staging version & original site

On original production site

  • Dump production database
  • Save uploads

On new production site

  • git clone the dev master version
  • composer install
  • rsync uploads from prod.
  • set up local-config.php
  • no need to update url (will be same domain)
  • import db from production
  • update db : wp core update-db --network
  • update woocommerce : for loop to do wp wc update --url="https://network/url";
  • Check everything workds
  • Set up nginx (copy from staging)
  • Backup nginx comfig from original file
  • Restart Nginx & pray
  • Check everything works
  • Congratulation!

4. Setting up semi-automation scripts

  • script 1: Production to Local data import
  • script 2: Production to Staging data import
  • script 3: Staging to Production deployment
  • script 4: Database and Backup script

Now let’s get into details.

1.Create a test composer-based local version

1.1 Move data from production to local development environment

  • Step 1 : Dump produnction database
bash> $ mysqldump -u db_user -p DB_prod > backup/latest.sql

where :

  • db_user is your db user.
  • DB_prod is the database user
  • backup/latest.sql whatever location you want for you db dump.

Personally, I created a ‘backup’ directory at the root of the wordpress install and I dump it there, and use latest.sql which is replaced each time there is a new DB dump.

We are going to use the same user for staging and production - for convenience.

  • Step 2 : Tarball the upload directory

  • Step 3 : create staging db

While logged in as db_user

mysql> $ CREATE DATABASE staging;
  • Step 3 : import dump into staging db
shell> $ mysql -u db_user -p staging_db < ./backup/latest.sql

2) Copy files to staging

bash> $ cp -r /var/www/prod/web /var/www/staging/web

or even better

 rsync -av -P /var/www/prod/web/wp-content/uploads /var/www/staging/web/app/content/

This is assuming you are creating the staging on the same server.

You might need to double check files have proper access for nginx www-data

bash> $ chown -R www-data:www-data /var/www/staging/web

3) Set up nginx file to support web access to wordpress staging version

Copy your existing nginx file from /etc/nginx/sites-available/production.vhost to /etc/nginx/sites-available/staging.vhost

and fix the domain stuff

Here is a sample of what it could be - but best is to stick to your existing one.

*Add link to nginx example

4) Update your wp-config.php

Connect details :

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

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

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

/** MySQL hostname */
define('DB_HOST', 'localhost');

// Domain for staging
define( 'DOMAIN_CURRENT_SITE', 'staging.domain.com' );

4) wp search replace

Make sure your wpcli us up to date.

then run

shell> $ sudo -u www-data wp search-replace "domain.com" "staging.domain.com"
sudo -u www-data  wp core update
sudo -u www-data  wp plugin 

4) local copy using homestead

Install homestead from here

map your project:

    - map: ~/code/project1
      to: /home/vagrant/project1

certbot-auto certonly –nginx staging.2serv.eu –dry-run certbot-auto certonly –nginx staging.2serv.eu


https://wpackagist.org/ https://getcomposer.org/


wp core update-db –network

wp search-replace “/wp-content/uploads” “/content/uploads” –network