Introduction to automated WordPress deployments

I gave an introduction to automated WordPress deployments at WordCamp Miami 2017. This is the companion article that I wrote for it. If you’re just looking for the slides, click here.

How do you feel when you have to update the code on a client’s WordPress site? Do you feel confident that everything will be ok? Or are you filled with dread as if you were about to play a round of Russian roulette?

For a lot of us, it’s a lot closer to the Russian roulette! We press the upload button of our favourite FTP client. We then spend the next minute refreshing the home page in our browser hoping not to see a white screen of death. (Followed by a sigh of relief when everything loads as it should!)

This is a pretty stressful way to work. You shouldn’t have to feel this way each time that you want to update the code of a WordPress site. It should be something that you can do as often as you want without worrying that you broke your site in the process.

And that’s where the idea of automated WordPress deployment comes in. As the name implies, it’s all about automating this process of updating a WordPress site. This, in turn, makes this risky process safer. (But keep in mind that this isn’t a bulletproof solution!)

Gone are the days where you’re playing Russian roulette each time that you want to make a change! You can now update your client’s WordPress site with a lot more confidence. This lets you focus on shipping bug fixes (yay bugs!) and new features.

That said, there are a lot of different ways of automating your WordPress deployments. We’ll go over what makes a successful automated WordPress deployment workflow. We’ll also look at a lot of different tools that you can use to achieve it.

What is automated deployment?

Let’s start with defining the concept of automated deployment. Automated deployment is part of a larger set of practices called DevOps. The goal of DevOps is to increase the collaboration between developers (a.k.a you!) and IT professionals (a.k.a. the people running your server).

Automated deployment itself is the process of moving code between deployment environments. For most us, that means taking code that we’ve worked on our computer and moving it to a server. We’ve been doing this for almost as long as we’ve used WordPress, we just hadn’t automated it.

This is a rough diagram of what automated deployment looks like in practice. On one side, we have our code that we’ve stored in a version control system. For most us, that’s a git repository hosted on GitHub.

On the other side, we have our server. This could be a production server, but it could also be a testing or staging server. It doesn’t really matter which it is. What matters is that this is where the code that we have in our version control system needs to go.

Automated deployment acts as a bridge between our version control system and our server. Its job is to ensure that our code makes it from one point to the other without breaking anything. That’s all there is to it!

The workflow

Now, there’s no question that you’ll need tools to automate your WordPress deployments. After all, it’s the tools that’ll do the work for you! That said, it’s also important to think about the workflow surrounding automated deployments.

In this context, a workflow is just a set of good habits. They maximize the chances that you’ll be successful implementing automated WordPress deployments. (Again, it’s worth pointing out that automated deployments aren’t a bulletproof solution.)

Use a version control system

We alluded to this one earlier, but it’s worth mentioning it again. You should use a version control system to store your WordPress code. It doesn’t have to be git either. Subversion (SVN) and Mercurial are also popular options. (For example, WordPress core uses Subversion.)

The primary reason for using a version control system isn’t workflow related per say. It’s because a lot of the tools that we’ll see require it. There are a few exceptions as always. But that’s why our earlier diagram had a version control system in it.

But that’s not the only reason why you should use a version control system. (That’d be pretty lame otherwise!) There are some other benefits to it that synergize well with an automated deployment system.

Code history

First, it gives you a history of the changes that you’ve made to your code. Or, if you look at it another way, it gives you specific snapshots of your code at specific points in time. This is useful when you want to revert a deployment.

This is what you do when something bad happens after a deployment. (And it’s going to happen even with automated deployments.) Reverting a deployment lets you go back to the previous working deployment. This is an important feature of automated deployments.

It’s still possible to do this without a version control system, but it’s not as systematic. That’s because it’s not tied to the code history. You’re just putting back the code that was there in the previous deployment. (This can be good enough for some, but it’s far from ideal.)

Code storage

To keep a history of your code, a version control system also needs to store your code. By default, it only stores it on your computer. But you can also use a service like Bitbucket, GitHub or GitLab to store your code in the cloud. We call a repository hosted on those services (or elsewhere) a remote repository.

A lot of automated deployment systems need one of these services to work. It’s because they need a place to go to get a copy of the files that they’ll deploy to your server. You can’t send them an email with the files you want to deploy! (That’d be too easy!)

Better collaboration

This ability of version control systems to store code elsewhere has another benefit. It allows you to collaborate better with other developers. It eliminates the need to share your files to other developer files using dropbox or some other method.

But it’s also important with automated deployment. One of the main reasons for using automated deployment is that anyone can use them to deploy their code. This removes an element of friction in a team’s development process.

It’s possible that letting anyone deploy code sounds crazy to you! (That’s ok!) But, if you have to wait for someone to deploy your code to a production server, that person becomes a dependency. This slows your development process down on top of not scaling well as your team grows.

An automated deployment system removes this gatekeeper from your development process. But it also makes a version control system necessary at the same time. Without it, your developers don’t have an easy way to share their code changes with each other.

Have a testing process

It’s common for an automated deployment workflow to include a testing process. This could a unit test suite that you have to run before deploying your code. Or it could be a more traditional quality assurance process where someone does the testing. (It could also be both!)

The point of adding testing to your automated deployment workflow is to derisk it. You want to have confidence that there won’t be any problems with the code that you’re deploying. That’s because one of the goals with automated deployment is to make you deploy your code more often.

But an automated deployment system isn’t a foolproof solution. It only prevents mistakes when updating the code of a WordPress site. It doesn’t prevent you from deploying bad code.

That said, there are some automated deployment systems that can mitigate this issue. They can do a basic test to see that your WordPress site is working after deploying code. If it isn’t working, they’ll revert it to the previous version that you’d deployed.

This isn’t a reason to not have a testing process, though! If anything, this makes having a testing process more important. An automated deployment system that fails all the time means that your code has quality issues. A testing process will help with that!

Having multiple environments

This brings us to the concept of environments. A lot of us have heard of testing and staging environments. A testing environment is often a server where you deploy a version of your code for testing purposes.

Meanwhile, a staging environment is often a server that mirrors your production server. We use it to test high-risk operations like migration scripts. But also as an environment where clients can approve changes before we deploy them to the production server.

Using such environments ensures that you’ll run into fewer problems. Your code will have fewer bugs in it due to the testing environment. And clients appreciate being able to preview changes before they go live.

Automated deployment makes it a lot easier to maintain such environments. Deploying to more than one server requires almost no extra effort. This wouldn’t be the case if you had to maintain all these environments by hand.

Implementing automated deployment

So this pretty much covers the important elements of an automated deployment workflow! The next step is to look at how you can put in place such a system yourself. There are a lot of options for you to pick from.

To simplify things, we’re going to separate all these options into four categories:

  • Hosts
  • Services
  • Plugins
  • Do it yourself

These categories group most of the options available to you. But they also allow you to look at them from a price or technical requirement angle as well. This gives you a lot of information to make your decision.

Hosts

The easiest option is using a host that supports automated deployments. That said, it also tends to be the costliest option. The hosts that we’re going to see support automated deployments using git.

How do hosts work?

The diagram above is an attempt to show how deploying with these hosts works. We have a local repository where we store on our code. This local repository always resides on our computer. (That’s why we call it local!)

On the bottom left, we have a remote repository that we’re hosting on GitHub. We picked GitHub, but it could be any of the services that we discussed earlier. This is where we store our code so that we can collaborate with other developers.

It’s worth pointing out that using a service like GitHub isn’t necessary. You don’t actually need it to deploy code with these hosts. That said, these services often come with useful features such as an issue tracker. This can make it worthwhile to use anyways.

On the bottom right, we have another remote repository. Your host will provide you with that one. Unlike our other remote repository, this one is necessary. It’s from that repository that your host will get the code that it’ll deploy for you.

Some hosts will deploy your code the moment you push new changes to their repository. Others will delay doing it until you tell them to in their administration panel. The latter option offers a good tradeoff between safety and automation.

In practice, it doesn’t matter that much which of the two options you have. You’ll often push your changes and go press on the deploy button right away. This makes the safety benefits of the latter option pretty irrelevant.

Available hosts

So what hosts offer automated deployment using git? This can be a pretty narrow or broad category depending on how you judge it. A lot of hosts say that they offer git support.

That said, most of them don’t have automated deployment using git set up for you by default. You have to set it up yourself. Most of them have documentation on how to do it too. (And we’ll look at that type of setup a bit later.)

But it still defeats the purpose of talking about hosts that offer automated deployment if you have to set it up yourself. So we’re only going to cover the ones that do offer it already set up for you. This leaves us with two hosts: Pantheon and WP Engine.

Pantheon

Pantheon is one of the newest hosts in the WordPress scene. They started off as a Drupal host before supporting WordPress. One of their angles is to be the hosting solution with the best developer tools.

This is why deploying code using git is the preferred way of working with Pantheon. All your changes get pushed to a development environment at first. You then have to tell it to deploy those changes to your production server using their dashboard.

WP Engine

WP Engine is another high-end WordPress host. Unlike Pantheon, they only do WordPress hosting and nothing else. But they’re the only such host to offer automated deployments using git.

Deploying code using git isn’t central to WP Engine like it is with Pantheon. That’s why their automated deployment setup is simpler. They offer repositories for each environment. When you push code to them, they’ll deploy the new code right away even for the production environment.

Services

The major issue with using one of the two hosts that we just saw is that they’re pretty costly. Not everyone can pay $25 or more per month per site. A cheaper alternative is to use an automated deployment service.

An automated deployment service lets you deploy code on any host as long as they have FTP. This gives you the flexibility to chose which host you want to use. This makes it a much more attractive and cheaper option for most people.

How do services work?

Here’s a diagram to show you what deploying with an automated deployment service looks like:

You’ll notice that we again have a local and a remote repository on GitHub like in our earlier diagram. But, unlike in our earlier diagram, using a service like GitHub isn’t optional here. Our automated deployment service needs that repository to deploy our code.

On the right, we have our server. This is where the automated deployment service will send our code. As we mentioned earlier, this server can be on any hosting provider that you want as long as you have FTP access.

Meanwhile, the automated deployment service sits in the center. It acts as an intermediary between your code in your GitHub repository and your server. Its job is to transfer your code from the GitHub repository to your server.

These services have the same behaviour as the hosts that we saw earlier. You can configure the service to deploy your code whenever you push changes to your GitHub repository. Or you can do it by hand by telling the service to deploy your code whenever you want it deployed.

Some of these services also let you do more complex deployments. What do mean by that? Well, for example, you could want to use Amazon S3 to store some of your files. These services can upload new versions of your files to S3 at the same time as they deploy a new version of your code.

Available services

Now that we’ve taken a look at how these automated deployment services work. Let’s go over the services themselves. There are a few of them out there, but we’re going to focus on these two:

These two services offer all the features that we talked about in the previous section. That said, there are a few differences between the two. These might impact which one you decide to use.

From a price perspective, DeployBot is the most expensive of the two. It also doesn’t offer a free tier if you want to try the service out. This is perhaps the biggest reason to choose DeployHQ over it. (If you’re new to this, there’s a good chance you want some time to get the hang of things.)

Another reason that you might want to pick DeployHQ over DeployBot is if you don’t use git. DeployBot only works with git repositories. Meanwhile, DeployHQ also works with Subversion and Mercurial on top of git.

Plugins

Let’s say that you don’t want to use one of the hosts or services that we’ve seen so far. What else can you use? Well, there are also plugins that you can use to automate your deployments.

Now, there’s a big difference between the solutions that we’ve seen so far and plugins. Plugins aren’t able to deploy entire WordPress sites. They can only manage the deployment of individual plugins or themes.

For some, that’s ok! Deploying entire WordPress sites like we’ve done so far doesn’t quite fit their workflow. They’d rather do automated deployments for specific plugins or themes. That’s why we’re covering them.

How do plugins work?

Alright, so let’s look at how these plugins work! Plugins have a unique way of working compared to the other options that we’ve seen so far. (And also the ones that we’ll see later!) The big reason for that is that plugins have to run inside WordPress which makes things more complex.

So here’s a diagram explaining how these plugins work. As you can see, it’s larger and more complicated than our previous diagrams. Still, it should help you visualize and understand what’s going on.

To the right, we have WordPress. WordPress is where the automated deployment plugin resides. But it’s also where all the other plugins and themes on your WordPress site reside as well.

The job of the automated deployment plugin is to create connections. It wants to connect a plugin or theme to a remote repository on a service like GitHub. If the plugin or theme isn’t installed, it’ll install it at the same time as it creates the connection for it.

Making updates automatic

But even with a connection, the automated deployment plugin still can’t do automatic updates for you yet. You can only update plugins and themes by clicking a button. (And that’s pretty lame!) This will tell the automated deployment plugin to go get a new version from the connected remote repository.

Now, it’s possible for the automated deployment plugin to do automatic updates. (Otherwise, why talk about them!?) But to enable them, you need to make a change to each connected remote repository. Each of them needs to have a webhook pointing back to the automated deployment plugin.

Above is a diagram that shows the flow of events when you’re using a webhook. Whenever you push changes to a connected remote repository (GitHub here), the webhook sends a signal to the automated deployment plugin. The plugin will then make a request for the code from GitHub and install the code returned in the response.

This is what makes automatic updates possible. It allows a connected remote repository to communicate with the automated deployment plugin. Without the webhook, the automated deployment plugin is blind to what’s going on inside the connected remote repository.

But, with the webhook, it’s not blind any longer! So now, when you push new code to the connected remote repository, it’ll also tell the automated deployment plugin. And it can just fetch the new version without you having to tell it to.

Available plugins

And that’s it for the inner workings of automated deployment plugins! You should have a pretty good idea of how these plugins work now. So this brings us to the plugins themselves. There are two of them:

Both plugins are pretty much identical feature-wise. Both of them support:

  • The three major git services that we’ve talked about in the article. (Despite one using GitHub in its name!)
  • Deploying plugins and themes.
  • Automatic updates using a webhook.

There are a few differences between the two plugins. For example, GitHub updater requires special headers for plugins and themes while WP Pusher doesn’t. But overall, these differences are pretty minor.

That said, there’s one major difference between the two plugins. It’s the price. GitHub updater is a free and open source plugin. Meanwhile, WP Pusher is a paid and commercial plugin.

Doing it yourself

Now, you might be someone who prefers to get their hands dirty and do things on their own. Well, this last set of options is for you! We call them the “Do it yourself” options.

There are automated deployment solutions that you have to implement yourself. They’re more complicated than what we’ve seen so far. But they’re also all free. (And we, developers, love free options!)

Automated deployment tools

At this point, almost every language has a tool for deploying code to a server. Capistrano is the better-known one. It’s written in Ruby, but you can use it with PHP projects like Symfony.

These projects often require a specific directory structure on your server. Regular WordPress hosts don’t support such a directory structure. That’s why you often have to configure your own server to use automated deployment tools.

That’s why we’re going to look at two server configuration projects. We’re looking at these two projects for a specific reason. They’re the only ones who configure your server so that you can use an automated deployment tool.

How does it work?

Automated deployment tools like Capistrano deploy code in a different way that we’ve seen so far. It’s not as complicated as what we saw with automated deployment plugins. But it’s unique enough that it’s worth looking at it. (And we’ve done it for everyone else so far!)

The unique aspect of an automated deployment tool is that your computer is the one doing all the work. It’s the one deploying your code by connecting to the server and running commands on it. The commands will handle fetching the code from the remote repository on GitHub. (Or any other service like it.)

For this to work, your server will need to have access to the remote repository that you want to deploy code from. With GitHub and similar services, the standard way of doing this is with deploy keys. A deploy key is an SSH key that has access to a specific remote repository.

There are security tradeoffs to using a deploy key. But, by default, a deploy can only read the repository that you give it access to. It also can’t access any other repository. This is good because it allows us to implement the principle of least privilege. (Well, it’s good as long as you don’t need to deploy more than one repositories at once!)

It also negates the need to use our own SSH key for deploying our code. In most cases, the deploy key is the SSH key of the server and not our own. This allows us to use more complex automated deployment workflows if we want to.

Available projects

There are two server configuration projects that offer automated deployment. You have DebOps for WordPress which is a server configuration project that I maintain. The other one is Trellis which the Roots team maintains.

Let’s start with the major difference between both projects. It’s the type of WordPress projects they support. One tries to support all of them. The other limits itself to a single project type.

One of the underlying goals of DebOps with WordPress is to try to let you work the way you want to. It’s for that reason that it tries to support all types of WordPress projects. So far, it only supports standard WordPress projects and Bedrock ones.

And speaking of Bedrock, that’s the only type of project that Trellis support. This is the project structure that the Roots team developed. It’s an excellent project structure for automated deployment. In fact, they conceived Bedrock with automated deployment in mind.

The other difference between both projects is the tools used to deploy your code. DebOps for WordPress uses Deployer which is a PHP version of Capistrano. Meanwhile, Trellis lets you deploy code using either Ansible or Capistrano. (Capistrano works, but they don’t maintain it anymore except for bug fixes.)

Doing like hosts and services

Now, you might not want something as involved as a server configuration project. Well, there’s another set of “Do it yourself” options that you can use. They let us build alternatives to the automated deployment hosts and services that we saw earlier.

Use a remote repository on a server

The first option is to configure a remote repository on your server. You can push code to it and it’ll update your live site. This lets you deploy code like you would with one of the automated deployment hosts.

The only problem with doing something like is that you need to use a host that’ll let you do it. This isn’t as difficult as finding a host that already has this configured for you. But it’s still something that limits your options.

If you’re looking for a guide on how to do this, Media Temple (they’re one of the hosts that support this.) wrote a good one. The whole process takes 30 minutes according to them. That said, it’s not a pretty short guide so there’s a good chance it doesn’t take that long.

Use a webhook to deploy code

The other option is to create a webhook endpoint that can deploy the code for you. This option is closer to the automated deployment services that we saw earlier. It also requires a service like GitHub to work.

It works by installing a custom webhook endpoint on your server. (This can be as small as a PHP file.) Whenever you push changes to a remote repository, it’ll send a message to that custom webhook endpoint. Your custom endpoint will then pull the changes from the remote repository and deploy them.

This option also depends on your host and whether it supports such a setup. For example, Rarst wrote a guide that walks you through this kind of setup on SiteGround. But you could also use the guide to set this up on another host if you wanted.

Taking the stress out of WordPress deployments

So this wraps up all the options for automating the deployment code to a WordPress site. As you can see, there are a lot of options available to you. And most of them aren’t that complicated!

Of course, a lot of WordPress experts use tools like these. But the truth is that you don’t need to be an expert to use them. That’s why it’s a shame that it still isn’t a popular way to work.

So, if you’re not using something like this yet, take a leap of fate! There’s a good chance that it’ll be a transformative experience. And you’ll never have to fear deploying code ever again.

Slides

Photo credit: Consolidated Construction

  • Jeff Cleverley

    Just watched the livestream. Great. I’ve set up sg-git with some shared hosting on Siteground, which was okay, documentation was pretty clear and their support are awesome. I know it’s shared hosting, but the value for money with SG keeps me a customer – version control, backups, staging and rollback, and seriously fast customer service. I’m going to have a look through the media temple documentation you recommended.

    I’ve got a couple of projects on Cloudways but haven’t set up version control there yet, but I’m also very interested in using automated deployment with a site I set up using the debops-wordpress project, will you be updating the (very good) setup documentation?

    • Yup, I hope to finish the release of the next version with updated documentation next month. Just doing a lot of travelling for the next two weeks.

      • Jeff Cleverley

        Excellent news, look forward to it. Happy Travelling!

  • Impressive and documented article. I’m using Trellis on one side and DeployHQ on the other side, but I’ll have a look at Debops. Thanks !!

    • Thanks! I hope to have the documentation ready for this next month! 😀

  • Kevin W. Hoffman

    Nice overview. I’m interested to hear where you think build processes should occur. If a project requires gulp to generate minified scripts and styles, it’s my opinion that those generated files should be ignored from version control and built at the time of deployment. This is one of the key differences between DeployBot, which includes a build process prior to deployment, and DeployHQ, which does not. A free, open source solution is PHPloy, which also allows for CLI commands to run prior to deployment. Questions for you:

    1. At what point in this workflow should a build process take place?
    2. Should generated scripts and styles be part of your Git repository?

    • Hey Kevin! <3

      Good questions! It really varies based on your architecture and platform that you're using.

      In other frameworks (Symfony for example), building, combining and minifying assets is part of the deploy process. There's command line to do it. And they're run on the server as part of the deploy steps.

      But, for example, Trellis will copy the assets from your local folder to the server if you use sage. I don't think that's especially good.

      If you use S3 or other file storage layer, building assets on the server doesn't always make sense. Having DeployBot do it and then send them to S3 is an option there.

      That said, regardless of how you do it, it's generally better to not commit the generated scripts. But it's possible that it's the only option that you have. So you'll have to do it.

  • I’ve built a simple tool for myself as well 🙂

    https://gitpull.io/

  • Tobias Schmidt

    If you are using something like wordpress as your choice of CMS, in 99% of use cases, save yourself from the headache of setting up and maintaing a CI pipeline. Furthermore, any automatic deployment without database migrations is useless in my opinion. Also, git is always a good idea but almost never for pushing changes to live servers.

  • Craig Byrd

    This is a very well written and formatted article.
    I use https://buddy.works -> that lets you automate all these actions on a single push to the repository:

    * Generate CSS and minify files and run unit tests with Grunt
    * Deploy plug-ins and themes to the live server
    * Monitor client websites for downtimes and update WP/plug-ins automatically

    You’re 100% right about FTP, but you can always use SSH keys to secure SFTP deployments and scripts executions.

    They also have a guide on how to use BUDDY with WordPress:

    https://buddy.works/guides/how-introduce-continuous-deployment-to-wordpress

    Check and let me know, especially since you’re a seasoned WP developer.

    • I have Buddy lined up for a continuous integration talk/article. I think services that offer full pipelines like that didn’t quite fit here even though you could use them for that. 🙂

      • Awesome news Carl, let us know if you need any info/resources for the upcoming feature! Also, great work with the article – we try to deliver guides on regular basis, too, and know how much time, research, and insight it all takes. Big shout out from the Buddy team!

        • Thanks! I look forward to trying everything out when I work on that article. 😀

  • Yuriy Gerasimov

    Great overview! For deployment tools you can also check phing. It is php based.

    Anther part of deployment that is easy to set up is automatic visual regression testing. Idea is that you make screenshots of web pages and compare them. Fo example you can easily compare your production vs staging environments, or prod before and after the release. This helps to catch CSS bus as well as php errors on pages.

    There are plenty open source tools. If you like a quick start (just provide list of URLs) welcome to try backtrac.io that is SaaS platform.

    • I don’t use any visual tools for testing. But I’d be tempted to use something like Behat for that if I did. 🙂