WordPress Deployment Part 3: Deploying WordPress Using Git
In my last article, we looked at deploying WordPress using some different command line (CLI) tools. In this article, we’re going to look at how we can deploy WordPress using Git, both manually via the CLI and also automatically when you push code to your remote repository.
Use Git & Composer
In the first article in this series, I briefly mentioned that you should be using Git and Composer to manage your WordPress site and your plugins and themes. For the purpose of this article, I’m going to assume that you already have your WordPress site stored in a hosted Git repo (I’m going to be using GitHub). If you need a pre-made repo to use as an example you can use this skeleton repo I prepared which is based on my Managing Your WordPress Site With Git And Composer series.
As was the case in my last article, I’m also going to assume you have a destination server ready for your deployment. All of these examples will require SSH access to this server.
So without further ado, let’s get deploying!
Manual Deployment using Git Push
First, we’re going to look at the simplest way to deploy your WordPress site using Git: by pushing to a remote repo hosted on your server. The idea here is that there will be a copy of your repo hosted on your server that you will push to whenever you want to deploy changes to your WordPress site (in the same way as you would push code changes to your hosted repository). This is going to be similar to the
rsync commands we looked at in the last article in that it works over SSH.
Using my skeleton repo as an example, let’s first clone the site on the remote server so that we have a remote repo to push to.
ssh email@example.com cd /sites git clone https://github.com/gilbitron/wordpress-skeleton.git example.com
Now we have our repo set up on the remote server in the
/sites/example.com directory. Make sure and change the SSH details and paths in the commands above for your server.
Next, we need to add a new Git remote to our local repo. Git remotes are simply versions of your repo that are hosted on the internet or network somewhere. Normally your repo will have a single
origin remote where your repo is hosted (GitHub in our example). You can see the remotes for a repo by running
git remote -v.
So back in our local repo let’s add our new remote repo:
git remote add live ssh://firstname.lastname@example.org/sites/example.com
Here we named the remote “live” but you can call it whatever you want. To check the remote has been added, run
git remote -v and you should see an output similar to this:
live ssh://email@example.com/sites/example.com (fetch) live ssh://firstname.lastname@example.org/sites/example.com (push) origin https://github.com/gilbitron/wordpress-skeleton.git (fetch) origin https://github.com/gilbitron/wordpress-skeleton.git (push)
Finally, we can push changes to “live” to deploy our WordPress site. Simply run:
git push live master
Here “live” is the name of the remote and “master” is the name of the branch you want to push. From now on, every time you want to deploy any changes to your site you can just run the above command. Simples!
A note for Git purists: while I’ve just cloned the whole repo on the server for simplicity, some people will argue you should use a “bare” repo for this purpose. This is one of those “it’s up to you” decisions 🤷♂️
Automatic Deployment using Webhooks
Manually pushing changes to a remote repo to deploy your WordPress site is a simple solution. However, it still requires that you push to two different remotes (the “origin” repo and the “live” repo). We could improve this workflow by removing the extra step of pushing to the “live” repo by automatically triggering a pull on the “live” repo after you push to the “origin” repo. How do we do this? Using Webhooks.
Most hosted repository services offer a way to send a payload to a specific URL when a certain event happens on a repo (a push in our case). Normally these are called webhooks and are a nice way of triggering actions when an event happens on your repo.
How you handle the Webhook payload is entirely up to you. In most cases, it will make sense to set up a script on your site to handle the payload, do any security checks and eventually run
git pull on the remote repo on your server (be aware that many hosts might not let PHP run a CLI command like
git so you’ll probably need to use a server where you can manage these permissions). Payload URLs have to be publicly accessible (or at least accessible by the hosted service you are using) so most services offer a way of setting a secret so your script can verify the webhook has come from the correct source.
When it comes to the actual script you use to handle the payload and trigger the
git pull, this can be almost anything you want, in any language. As WordPress is written in PHP it’s safe to assume your server will have PHP installed and so it makes sense to use a script written in PHP. This git-deploy script is a good template/example of how we might achieve this using PHP.
If you’re wanting to go the DIY route with your script, the GitHub Webhook docs offer plenty of information on how to handle the webhooks sent by GitHub.
Automatic Deployment using Continuous Integration
An alternative to using Webhooks is to use an external Continuous Integration (CI) service to trigger a deployment on your remote git repo. The main purpose of CI services is to run tests and checks on your code after pushing your code to the origin repo. Once the checks pass the CI can then be configured to deploy your code. In our case, we don’t really need to worry about running tests at this point, but we can still use a CI to deploy our code.
There are a couple of options you have when using CI deployments:
- The CI will push to a remote repo hosted on your server (the same process as our manual deployments above, just triggered by the CI instead).
- The CI can fire off a request to a remote server script (basically emulating the Webhook solution we just looked at).
- The CI can SSH into your server and run
git pullon your repo.
Let’s see how we could use the popular Travis CI service to trigger a deployment via option 1 (pushing to a remote repo).
To get started with Travis CI you need to add a
.travis.yml file to the root of your repo. This file will contain and commands you need to run to deploy your WordPress site using Git. Our
.travis.yml file will simply contain a
deploy: - provider: script script: bash deploy.sh on: branch: develop
This tells Travis to run the
deploy.sh script (which we would add to the root of our repo). Our
deploy.sh would contain a script like the following:
eval "$(ssh-agent -s)" #start the ssh agent chmod 600 .travis/deploy_key.pem # this key should have push access ssh-add .travis/deploy_key.pem git remote add live ssh://email@example.com/sites/example.com git push live master
For this script to work you will need to generate an SSH key (stored at
.travis/deploy_key.pem in your repo) and make sure the public key has been added to the
~/.ssh/authorized_keys file on your remote server so that Travis can SSH to your server. Storing a private key in a Git repo isn’t a great idea (even if the repo is private) so you should probably read up on Travis’ docs on encrypting files for best practices on keeping your information safe.
The last two lines in the script are exactly the same as what we did in our manual deployments using git push.
Finally, you need to enable your repo in Travis CI (it’s free for public repos) then commit your
.travis/deploy_key.pem files to your repo and push them to GitHub. Travis will automatically pick up the new script and run the deployment. Success!
Git-ing my Groove On
Hopefully, by this point, you’ve got a reasonable understanding of how to deploy your WordPress site using Git, both manually and automatically. In the end, it essentially boils down to running
git push or
git pull either manually via the CLI or automatically via some kind of trigger.
In my next article, we’re going to look at some other services and CI tools that allow you to configure a much more powerful and flexible build and deployment pipeline, which will build on the concepts we’ve looked at in this article.
Do you use Git and Composer to manage your WordPress site? Have you tried deploying WordPress using Git in the past? Do you have any tips or tricks for deploying WordPress using Git? Let us know in the comments.