Dan Green-Leipciger
Dan Green-Leipciger

Reputation: 3932

Sync a wordpress site with git

With WordPress, what is the best way to sync a local test server with a staging server?

Upvotes: 0

Views: 477

Answers (3)

theking2
theking2

Reputation: 2838

From your question I deduce that you have three servers

  1. Local development
  2. Staging server
  3. Production server

My workflow is: install WordPress on all three, install the required WP plugins and clean away the unneeded pre-installed wordpress stuff. The only folder under source control is than the wp-content/themes/my-awesome-theme folder or the child-theme folder. After ready installing, clone the my-awesome-theme repo in the wp-content/themes folder.

Rationale

WordPress is not under source control. Theme development is. Just like the database, the wp-content/media folder also should not be under source control as they either cannot be source controlled or do not contain source files.

Most editors are fine with a sub folder under sc and will find the repo. If not, I've learned that, for instance in vscode, opening and closing a file in the theme folder hints the extension to start watching the folder.

Additional

What I also do normally is update the wp-config.php to work on the three difference locations somewhere after the WP_DEBUG define include:

define( 'WP_SITEURL', 'http://my-awesome-site.local' );
define( 'WP_HOME', 'http://my-awesome-site.local' );

And on stage/prod something like;

define( 'WP_SITEURL', 'https://my-awesome-site.tld' );
define( 'WP_HOME', 'https://my-awesome-site.tld' );

to prevent these from looked up in the database. You might have to do the same with the database connection setup further up.

Database select

To have different database settings for each of these versions use the name that was used to access the site. In wp_config.php change this:

switch($_SERVER['HTTP_HOST']) {
    default: /* production */
        define( 'DB_NAME',     'server-db-name');
        define( 'DB_USER',     'server-dbuser-name');
        define( 'DB_PASSWORD', 'server-dbuser-pass');
        break;
    case 'stage.my-awesome-site.tld':
        define( 'DB_NAME',     'stage-db-name');
        define( 'DB_USER',     'stage-dbuser-name');
        define( 'DB_PASSWORD', 'stage-dbuser-pass');
        break;
    case 'my-awesome-site.local':
        define( 'DB_NAME',     'local-db-name');
        define( 'DB_USER',     'local-dbuser-name');
        define( 'DB_PASSWORD', 'local-dbuser-pass');
        break;
}


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

If using PHP 8.x you could use some fancy match() {} construct.

Alternatively you want to keep the db config nice and tidy in one easy location you could settle with a parse_ini_file() construct:

$ROOT = $_SERVER['DOCUMENT_ROOT'];
$settings = parse_ini_file($ROOT.'/db.conf', true);
define( 'DB_NAME',     $settings['db']['name'] );
define( 'DB_USER',     $settings['db']['user'] );
define( 'DB_PASSWORD', $settings['db']['passwort'] );
define( 'DB_HOST',     $settings['db']['server'];

with this db.conf file:

[db]
server = localhost
name = db_name
user = db_user
passwort = 'db_password'

Make sure db.conf is made not accessible with a .htaccess (!). it would cause an extra file opening performance hit (probably negligible with all the magic WP is doing).

Notes

Including the whole WordPress folder in SC and then manually gitignore the one's I don't need sounds like the wrong way around. And probably is not future proof; who knows what the WordPress developers add to the installation.

Upvotes: 1

Slam
Slam

Reputation: 3335

Dan's script is working for me with a few modifications:

  1. The PHP script was giving me errors at mysql_connect() so I had to make the following insert at line 14: $host = "localhost:3306"; $user = "root"; $pass = "root";, which are the default settings for MAMP.
  2. the bash profile should read push-wordpress() { php SCRIPT_LOCATION/dumpsite.php DB_NAME LOCAL_URL REMOTE_URL DUMP_LOCATION ; cd LOCAL_REPO_DIRECTORY; git commit -a -m 'Database Updated'; git push origin master; }. The first time you run it, it will not add the dumped database, and you will need to either manually run a git add . and commit again, or add git add . ; before the git commit in the bash script.

Upvotes: 1

Dan Green-Leipciger
Dan Green-Leipciger

Reputation: 3932

This works with git and assumes that you have already set up a repository with GitHub etc.

This assumes you are using Linux or OSX.

1) Download this php script and store it somewhere on your local machine.

2) Put this into your local machine's ~/.bash_profile

push-wordpress() { php SCRIPT_LOCATION/dumpsite.php tshirt_wp LOCAL_URL REMOTE_URL DUMP_LOCATION ; cd LOCAL_REPO_DIRECTORY; git commit -a -m 'Database Updated'; git push origin master; }

3) Put this into your remote machine's ~/.bash_profile

pull-wordpress() { cd REMOTE_REPO_DIRECTORY; git stash; git pull; chmod -R 755 REMOTE_REPO_DIRECTORY*; mysql -u DB_USERNAME --password=DB_PASSWORD DB_NAME < backup-DB_NAME.sql; }

4) On your local machine, run push-wordpress

5) On your remote machine, run pull-wordress

It should work 'out of the box' but it may take some tweaking.

Upvotes: 1

Related Questions