There are many ways to deploy WordPress, but I’m going to cover a process that should work for most people, provides security, and makes life easier. I’ll be covering each part and how to implement it:
- Track the entire WordPress install with
git
- Automatically deploy changes as they happen
- Use the
master
branch as production - Automatic updates
Track The Entire Install With Git
Use a git repository to hold the entire install, everything inside htdocs
/public_html
. This way, to deploy your site on a server, you run git clone *repo url goes here* .
in the public_html
folder.
If you need to make changes, you can do the same in a local developer environment, with the same command, make the changes, then commit and push them to github/etc. To deploy the changes, run git pull
on the server.
As a bonus, git can see when files change on the server. If your site gets hacked, git
knows exactly which files have changed, and can show you by running git status
or git diff
. It can even undo the changes for you.
Additionally, you can go back in time to older commits if a change breaks the site, and you have full version control, showing who did what and when.
Finally, the git repository acts as a backup of all the code on your site. Should your site be destroyed, you can do a git clone
on a new server and have the code ready to go waiting for content.
Using master
for Production
Now that we have a git repository, we can assign branches to environments. Using VIP Go as an example, the master
branch is always used for production.
As soon as code arrives in the master
branch it is immediately deployed, and arrives via pull requests so that code changes can be reviewed and tested. Other branches such as develop
are auto-deployed to other environments such as develop
or preprod
for testing purposes.
Developers working on a site never have to touch the server, and can do everything with a git add
, git commit
, and git push
. Moving changes from pre-production to live involves just a pull request.
Automatically Deploying Changes
Nobody has time to SSH into a machine and run git pull
, so why not automate it? You can even add parameters to do a hard reset and flush any file changes there might be. There are several methods that let you do this:
- webhooks
- cronjobs
Web Hooks
In GitHub and other services, you can create web hooks. Create a web hook, and tell it to ping a script on your server. This script can then run a git pull
, updating the site almost immediately after the changes are pushed up.
For example, a script at example.com/gitpull.php
may look like this:
<?php
$gitpath = '/usr/bin/git';
header("Content-type: text/plain"); // be explicit to avoid accidental XSS
// change to the folder we cloned to
chdir('/srv/www/example.com/htdocs');
echo system("/usr/bin/env -i {$gitpath} pull 2>&1");
echo system("/usr/bin/env -i {$gitpath} submodule init 2>&1"); // set up submodules
echo system("/usr/bin/env -i {$gitpath} submodule update 2>&1");
echo "\nDone.\n";
The major advantage of this approach, is that it is much easier to set up, and works on more hosts. The downside is that this script has to run in the PHP time limits, preventing it from doing too many things.
Cron Jobs
You can create a cron job that runs at regular intervals, e.g. 5 minutes, that executes a git pull
command in your sites folder. This pulls down any changes that have been made at predictable times.
The advantage of a cron job is that it can be made more secure, and has unlimited time to execute. It can also be repurposed to run the WP Cron command via wp cron
, speeding up page load times slightly, and making scheduled publishing more reliable. The disadvantage is that not all users are going to be able to set up cron jobs, but this is not an issue if you’re running a VPS, or have SSH access.
Automatic Updates
If the native WP automatic updates are active, changes will be made on the server that can modify the git working directory, preventing updates from being pulled in. Instead, updates will need to be handled separately, be it via composer
, wp cli
or manually.
One way to handle updates is to clone the repo into a local dev environment, and apply the updates and commit/push them up.
There are other methods though that are automated, I would recommend using WP CLI
WP CLI
It can be argued that there is no need to include the entire WordPress directory in the git repo, and that only the wp-content
folder is necessary, and bespoke plugins. This can be achieved with WP CLI.
WP CLI can be used to install and update core and the other plugins, and can be integrated into a shell script. This script can then include the git pull
and be ran by the cron job, or update PHP script.
The script can then run commands such as wp core update
, wp plugin update --all
, etc, automating the installation and updating of WordPress and any .org plugins.
This is how VVV sets up sites automatically, via a provision/vvv-init.sh
script. This script downloads and installs WordPress automatically, and keeps it up to date, preventing the need to keep a copy of WordPress in the git repository.
I love the automatic deployment with Git pull! On all of my VPS, I always have a PHP script that stores repos’ configurations and pull them when they have a new commit. Never worry about FTP again. It’s a big time saver.
Interesting topic. I have almost the same setup, but the only thing my setup is different is I have a git server on my server which I just git push to both github and my own git server. I just also started using composer and wp-cli, so reading this now, makes me wanna do the same. 😛