How to deploy on a production server from your local Git repository

If you’re like me and began to do what you do more than a decade ago, you’ll definitely remember how we all used to push updates to our production servers via FTP. There’s no shame in that: we’ve all been beginners.

Using FTP might even be fine today for teeny-weeny projects, but two things are for sure:

  1. it’s slow,
  2. it will almost always lead to uncertainty regarding the syncronization between your local copy of the project, and the remote one on the server (even if I hear that some people still develop directly on a server, but that’s a rant for another occasion).

Luckily for us, we have version control systems such as Git and our work is never really lost.

So how can we avoid using FTP to upload updates to our production servers?

You set up a new repository that’s hosted on the very same production server you’ll project will end up on and also push updates to that repository.

So let’s assume that you have developed a theme for WordPress and you want to keep it in sync with your local copy.

I wouldn’t want to have the theme folder on the production server to host the repository itself, so I’d opt to set it up in a folder outside public_html and then listen for push events on that repository and perform a checkout of the project to the actual theme folder.

So, since I’m lazy, I’ve created a little script to make my life easier:

#!/bin/sh
rm -rf $1.git
mkdir -p $1.git
cd $1.git
git --bare init
cat <<EOF >hooks/post-receive
#!/bin/sh
mkdir -p $2
export GIT_WORK_TREE=$2
git checkout -f
EOF
chmod +x hooks/post-receive

You can create a file (let’s say create-repo.sh) in the folder that will host your repositories on the server, adjust the file permissions so that it can be executed (chmod +x ./create-repo.sh), and launch it with the following syntax:

./create-repo.sh repository-name path-to-actual-folder

This script does the following things in sequence:

  1. remove any pre-existing repository with the specified name,
  2. set up a new blank repository in a specific folder whose name is indicated by the first parameter (in our case repository-name),
  3. create a hook that is triggered upon receiving a push that will perform the checkout in the actual project folder (second parameter passed to the script, in our case path-to-actual-folder).

So, assuming that you have a standard WordPress installation in the root directory, you could create a repository that points to the themes folder:

./create-repo.sh your-theme-name /home/your-user/public_html/wp-content/themes/your-theme-name

The only remaining thing is to upload stuff to the production server, for which you’ll have to create a new remote pointing to the newly created repository through SSH and then execute a push towards said remote:

ssh://your-username@your-host.dev/~/repos/your-theme-name.git

assuming that you’ve created the repository in a repos folder in your home directory, which I’d recommend.

As you can see, this is nothing too complex, but it’s a pretty nice time saver nonetheless.

Leave a Reply