UPDATED: I have updated this post recently (June 2017) to include a new way of handling the wp-config.php file, and also how to handle the transferring of database and media files.

This post is to run through a solid, proven dev and deployment process using MAMP, Wordpress, Github and GIT repos on remote servers.

This is part 2 of the 2 part tutorial. Part 1 can be read here.

In part 1 of this set of posts, I covered how to set up your local MAMP environment alongside customising your hosts files to give some great looking local URLs. This final post will cover the remote environment and deployment method, and how the process links together:

  • Set up your local development environment - check
  • Set up your hosts file so your computer can use domain name style addresses instead of IP addresses - check
  • Let MAMP (or other local server setup) know about your new hosts file change - check
  • Set up two GIT repos on your server which will contain your website, and a staging website for showing your clients the progress of the site, or view updates before they’re pushed live
  • Set up a repo on GitHub (or similar GIT hosting service) so you and your team have a central location to store your code
  • Set up your Wordpress environment to handle multiple config files

Again, it’s worth noting that this process is nuanced but is widely used. There are a lot of different approaches depending on your set up of remote server software/OS, Git repo choice and local machine OS/version of software. I’ll be covering my process which includes CentOS server, Github.com account, and MacOS with Terminal. You should be able to adapt for your set up easily enough.

Set up remote Git repos for your app or site

When adopting this process, your website can be deployed to a remote “live” or “staging” locations using Git and the Terminal. This makes it easy for developers to easily push test updates and live updates for people to view on the web by accessing a url such as staging.yoursite.com. This will go through setting up staging environment, but this process can be replicated for live environments also.

First step is to SSH into your server. You will need to check with your hosting provider to see if this is possible, if not then you may be better off using a service like Beanstalk. In your Terminal:

ssh [account-name]@[remote-ip] -p [special-port]

Once you’re in to your server, find the directory which is above the public_html/ directory of your [account-name] account (referenced above), and enter the following:

mkdir stage_[sitename]
cd stage_[sitename]
mkdir site.git
mkdir public_html
cd site.git
git init –-bare

I also now manually transfer my wp-config file on setup to the directory above my public_html. This is great for security, and Wordpress will automatically look for it there. The only thing is you’ll probably be pushing up your local wp-config file to the remove server too, so it needs to be removed in a the post-receive hook (see below).

When your local site is pushed to the server it will be pushed to a bare repo. This bare repo has no working tree, meaning it doesn’t track any files, but in this case is used to push the files you commit to it to another location. It will push the files to the public_html/ directory within the stage_[sitename] directory, using a post-receive hook which runs after each commit is received. To set this up, make sure you’re in the site.git directory:

cd hooks
nano post-receive

This will bring up a text editor, where you should enter the following:

git --work-tree=/home/[your-account]/stage_[sitename]/public_html  --git-dir=/home/[your-account]/stage_[sitename]/website.git checkout –f [branch]

rm /home/[your-account]/public_html/wp-config.php

#This is not mandatory, but if you have some sort of build process you'd like to run on the server, you can do it here
cd /home/[your-account]/public_html/wp-content/themes/[your-theme]/src/js/
npm install
npm run gulp-prod

Note how I am removing the wp-config file from the public_html directory on each push.

Now when you push up to your staging site’s bare repo, the post receive hook will copy all your files to the public_html directory.

You can set up access to this directory with add-on domains or subdomains, depending on your server OS and your preference. I like to have the staging site accessible via something like staging.mysite.com.

I am also optionally running my Gulp process which sorts out compression and minification. I’ll do a post on doing this in Webpack soon!

Then make the post-receive hook executable:

chmod +x post-receive

Further notes: If you’re using a build tool such as Webpack or Gulp, you can set up the post-receive hook to execute the build process on the server. This is useful because you generally don’t commit the final compressed/minified JS/CSS/image files to Git repos as it wastes space. This isn’t everyones preference but it’s mine, so I’d suggest running your Gulp process on the server. This will require having Node and NPM installed on the server, so you’ll need to contact server support for this if you’re on a shared hosting platform.

Set up central Git repo

Like you would with any project, it’s a good idea to have your code tracked by Github for many reasons, especially when working in a team where you’re all pushing/pulling from a central repo like Github.

I’d recommend having a Github.com account as this central location to share your code, and having one person in a team responsible for making commits to any remote/staging sites so there’s no confusion.

On your local project, if you haven’t one set up already:

git init

Then do an initial commit to your Github repo to check all is good:

git push origin master

You’ll then want to add the remote repo we created earlier to your local Git project:

git remote add staging ssh://[account-name]@[remote-ip]:[special-port]/home/[account-name]/stage_[client]/website.git

You’ll push to your remote staging area with:

git push staging master

Further notes: Although the above will transfer your code to the staging area, you’ll need to manually transfer the database from your local Wordpress site and import to the staging area, update the wp-options table on your staging site to match the new environment, and set up your remote config file to match the new DB credentials.

There’s an excellent plugin called WP Migrate DB which you can then install on the remote and local sites to automatically sync the databases with ease. This handles the transfer of SQL files, and the updating of the site settings in the wp-options. If you don’t have this, or a similar plugin, life will become a pain in the ass.

Set up Wordpress to handle wp-config.php files the right way

Probably the most important aspect of any dev ops solution is security, so ensure you’re not pushing your remote wp-config.php file to the Github.com repo. This shouldn’t be a problem as you should only be pushing your local copy to Github containing no server passwords.

One Also make sure you’re not overwriting your wp-config.php file, both locally by pulling from Github, or on your remote sites by pushing your version of the site up, so simply run the following command on remote and local environments when you have all the files in place:

git update-index --skip-worktree wp-config.php

This will ensure your config info for DB connections remain untouched. This may give you some issues when switching branches, but just stash your changes and you’ll be fine.

An alternative solution to the wp-config.php file issue is a setup by Studio24 which is available on Github, and is slightly more long winded but worth looking at if the approach in this post doesn’t quite meet your requirements.

Final comments

One large missing piece from the process outlined here is the transfer of the database and Wordpres media files. Most people will probably know this, but there’s a fantastic plugin called WP Migrate DB PRO by Delicious Brains. It will pretty much do the whole DB transfer for you and update the site URLs, all from within the Wordpress admin area.

The plugin does cost money, but if you’re not sure about how great the plugin is or just want to dabble, there’s a free version under a GPL licence from wp-sync-db on this Github account. It’s no longer kept up to date and I do ran in to some really minor issues every now and then when I used this, but it’s worth checking out. They also have a free add-on plugin to handle media file transfers!

One final thing to mention is that you may not want a staging site to be indexed on Google if it contains dev/prototype work, so be sure to add a robots.txt file to stop bots crawling your site.

Hopefully this has been worth a read for anyone new to the process. As I mentioned before, there are more modern ways to control deployment but I like this approach for beginners as it helps sharpen Git skills and gets people down to the metal with the Terminal and configuration.