Managing website deployments and databases is the single biggest issue for us with our ongoing website management. We keep our client’s websites up to date and upgrade the plugins for them. So once we had selected a web host that suited our needs, we needed to put a smart, time saving workflow in place.
Setting up a file structure in version control
We use a custom install of WordPress as a basis for all new sites, with a selection of plugins and settings, ready to go. This is maintained in a git repo that saves a copy of the database each time a commit is made. This means that any of our team can now spin up a new WordPress website in a matter of minutes.
All websites are in version control, using git. We like to keep all of the wp-content folder in the git repository for each project. That means that all dependencies (plugins, themes and custom code) are in version control and updating them is simply a git pull away for our local development sites. This might be overkill for some people, but it keeps it simple and ensures there is only ever one repo per project. We could look at using bower or another more capable dependancy management system but for the time being this approach works well for our small team.
This also allows us to create a new folder in the wp-content directory called avocadesign-mu-plugins, in which we store any custom code used to generate layout or other features for the website. That keeps those features outside the theme that the project is using in case we change in the future. We just use a small plugin loading file in the mu-plugins folder to include the contents of this new “avocadesign-mu-plugins” folder. It will be clearer why we didn’t just create a folder in mu-plugins once you’ve read about our grunt deployment via rsync.
Deploying changes to the live site with Grunt
There are a variety of ways to push code changes to the live site. In keeping with trying to streamline everything we were doing, we needed a automated alternative to deploying via FTP or sFTP. There are a number of automated services that will look at the git repo and push only the changes in a commit to the server for you (Beanstalk, Springloops etc). However, this would have meant increasing reliance on a third party service and ongoing cost for a key part of our business.
We chose to investigate Grunt.js instead.
What is grunt?
Grunt.js is a tool built on top of node.js to run tasks from the command line. It is extensible with all kinds of plugins, handling compiling SASS to CSS, ftp, rsync and a multitude of other uses. Smashing Magazine has a good primer on getting started with grunt. Go on, we’ll wait.
Our grunt setup
We use grunt to compile SASS files and deploy code to both staging and production servers. Our setup is largely based off a workflow from Matt Banks.
We have made it easier to get sites setup quickly by adding variables for the theme directory, server path and ssh user at the top of the gruntfile.js. This only has to be done once as it is stored in git so all members of the team benefit. Deployment ssh access is secured with ssh keys for password-less logins. This lets us retain control of who can publish code changes.
Because we are deploying the entire wp-content directory, the list of excluded files for rsync needs to include uploads, files relating to W3 Total Cache and the mu-plugins folder. We use Web Synthesis for our hosting and they include plugin functionality in the mu-plugins folder. If we didn’t exclude the mu-plugins folder (and keep all our custom code in avocadesign-mu-plugins) we would overwrite their code each time we made an update to a site. In order to run our custom plugin code we include a simple loader in the mu-plugins folder that we need to upload via sFTP the first time we setup the site. After that deploying to the live server is just a “grunt deploy:production” away.
Why not just use git?
There are plenty of examples of people using git, and great strategies like git-flow to manage deployments. For us, though, using grunt and rsync allow us to control what is deployed and exclude some files that are in the git repo such as the gruntfile.js which serves no purpose on the live server.
Taking care of the database with Migrate DB Pro
Step 1 -> Install Migrate DB Pro
Step 2 -> relax, it’s under control now
Migrate DB Pro is perhaps the single biggest change to our workflow. In a way it was a tiny change, install, sync, done. However, it has certainly had the biggest impact.
Manually dumping the database from phpMyAdmin on the server and importing in the local development environment it is a pain. Before we had an automated tool, we would do this infrequently. This often resulted in development websites that were not up to date with content on the staging or production server. This can really slow down the development time.
Now that we have a good tool, we sync the development site with the staging site at least once a day. That way we can give clients early access to the staging site. They upload content, which we download and everything “just works”.
When it comes time to setup the new website on the live server, the export features are fantastic. It’s super easy to create a SQL file for importing into the live website that has the url and file path replaced with the correct values for the live server. Another trip to phpMyAdmin saved.
Oh did I mention that it can download all the media too.
It saves us hours a month, it’s worth every penny!