Blog about software development


Deploy with Git: push to production

22 Oct 2018 - by 'Maurits van der Schee'

When you are building applications or websites in PHP, Ruby, Python or any other scripting language then you may still be using FTP to deploy to production. Please don't! When you have SSH access to your production server (for instance when running on a VPS), then you may use Git to automatically deploy your software. We will setup your production server as a Git remote so that you can type "git push production" to deploy the latest version of your code to production. This post will show you the steps to take to achieve this.

Configuring public key based access

Your local machine needs a public/private key-pair to be able to deploy to production without a password. You can generate a public/private key-pair using "ssh-keygen" on Linux or "PuTTYgen" on Windows. You may install the Linux package using:

sudo apt install openssh-client

or the download and install the windows MSI package from:


On Linux your private key is saved to "~/.ssh/id_rsa" and on Windows you create a file with a ".pkk" extension. Both formats can (and should) be encrypted using a passphrase for protection.

Install you private key

On the server you login using your password. Then you create a "~/.ssh/authorized_keys" file using:

mkdir ~/.ssh
nano ~/.ssh/authorized_keys

In that file you copy the contents of your ".ssh/id_rsa.pub" file (as a single line). If you have created a ".pkk" file you need to look for the public key in OpenSSH format (for pasting into "authorized_keys"). When using "nano" use "Ctrl-O" to save and "Ctrl-X" to exit.

Creating a bare repo to push to

On the server you need a repository to push to. This should be a bare repo to avoid conflicts. If your script project resides in "~/public_html" then you may create a repo in a new directory and initialize it using:

mkdir ~/myproject.git
cd ~/myproject.git
git --bare init

Now you have a bare repository as a target to push to. Lets ensure that the "public_html" contains a clone of the bare repo using:

cd ~/public_html
git clone ~/myproject.git .

Adding a "post_receive" hook to automate

In the hooks directory of the bare repo you can create a script with execution rights that pulls the contents from the bare repo to the production site. The file should be

nano ~/myproject.git/hooks/post-receive

Make sure the contents of the file are:

unset GIT_DIR
cd /home/maurits/public_html/
git pull

Now make the file executable, so that it can be run after receiving a commit:

chmod 755 ~/myproject.git/hooks/post-receive

Testing the deployment

First you need to add an extra remote to your local repository:

git remote add production maurits@localhost:myproject.git

You should replace "localhost" with the server address and "maurits" with your username on that server. Then you need to test an edit and execute:

git push production

Note that you may have to set the default branch (master) with the suggested command.

Enjoy pushing to production!

PS: Liked this article? Please share it on Facebook, Twitter or LinkedIn.