It’s taken me a bit of time to figure out the best way to version and deploy sites with WP Engine. I still don’t have a perfect solution, but it’s now much better than using an SFTP GUI to move the files from local to staging.
Version Control
In terms of version control, I like to have the active theme in its own repository. This is generally where the bulk of custom development work happens, and this makes it easy to view the commit history, open issues, and reference code. If custom plugins are needed for the site, I also like to have those in their own repositories for the same reason.
For everything else on the site (WordPress core, third-party plugins, and media) I think it’s important to have backup points (especially before plugin/core upgrade in case a rollback is required), but I don’t necessarily need to have that versioned with something like Git.
If you’re not like me and prefer to have the entire site versioned in one repository, then git deploys work great with WP Engine. You can even set the gitignore file to ignore specific third-party plugins, media, and core so it just tracks your custom plugins and themes- but those all still need to be in one single repository that is tracked from the root of the WordPress directory.
Workflow
If I had shell access with WP Engine, my development/deploy process would look something like this:
- Clone the “Live Environment” to “Staging” using the built in WP Engine tools
- Rsync “Staging” to Local
- Do custom theme/plugin development locally in individual repositories and push changes to GitHub
- Rsync changes back to “Staging” (or ssh directly to staging and git pull specific repos)
- Use the built-in WP Engine tools to deploy “Staging” to “Local”
However, since WP Engine doesn’t provide shell access, an alternative to rsync or ssh is needed to move the individual custom theme/plugin repositories to staging.
The obvious answer is to just use SFTP, but this can be a bit tedious. Updating all the files (rather than just an rsync) takes a bit longer. Copy/pasting the SFTP commands or using a SFTP GUI also takes time and is prone to user error.
Automate SFTP Deploys
To try and automate the SFTP transfers, I started to look at various deployment services. There’s a number out there: Dploy, DeployHQ and CodeShip are just a few examples. These services help you auto-deploy straight from GitHub as well as provide command line tools. They look to be quick, efficient and would definitely solve the problem, but $10-$15/mo also seemed a bit expensive just to move code from GitHub to a server via SFTP.
Grunt Task
I finally landed on an an SFTP-deploy Grunt task. I already use Grunt for theme development, so adding an additional task was pretty quick.
To make it work, I simply had to add a a definition to my Gruntfile.js:
'sftp-deploy': { build: { auth: { host: '11.111.111.111', port: 22, authKey: 'staging' }, cache: 'sftpcache.json', src: '/Users/Me/Local/Site/wp-content/themes/active-theme', dest: 'wp-content/themes/active-theme', exclusions: ['.ftppass', '.git', '.gitignore', 'node_modules', '.sass-cache', 'npm-debug.log', '.DS_Store', 'assets', '.sftpcache.json'], serverSep: '/', concurrency: 4, progress: true } }
Add a grunt task at the bottom:
grunt.registerTask( 'deploy', [ 'sftp-deploy' ]);
Create a .ftppass file:
{ "staging": { "username": "server-user", "password": "server-password" } }
And make sure the .ftppass and sftpcache file were excluded from the git repository by adding this to the .gitignore:
# Grunt Deploy .ftppass sftpcache.json
To deploy the theme (in this case) so staging, just run the command:
grunt deploy
After the first deploy, an the sftpcache file keeps track of the file timestamp and will only upload items that have changed- which makes it just as efficient as rysnc.
Final Thoughts
It would definitely be easier to version the entire site and use Git deploys since WP Engine supports them- so if you’re not too nitpicky about having clean single use repositories for themes and plugins, that’s probably the way to go.
However, if you’re already using Grunt in your themes and plugins and get frustrated with using command line or GUI SFTP, this Grunt task works pretty well.
Perhaps there is another solution for deploying multiple unique repositories to a server where you don’t have shell access? If so, I’d love to hear it.
Great Article!
Where do you put the .ftppass file?
It goes in the root. Same directory as your Gruntfile.js.