Heroku is a amazing Platform as a Service that enables you to build and run application in the cloud. It’s often the first choice for deploying an app when you don’t want to focus on something else that the app itself.

One great feature of Heroku is their “push to production” mechanism, which allows you to trigger deployments from your local environment itself. This removes the need from a CI/CD pipeline but keeps the simplicity and security of an automated deployment workflow. Therefore, this is great for small or side-projects.

This feature is easy to setup outside of Heroku, on any server with Git installed. Let’s see how to do so!

A. On the server side

1/ Make sure Git is installed on the server. Else install it 😉

2/ Create the bare repository on your server (here’s a great resource to know more about the difference between work respositories and bare repositories):

$ mkdir -p ~/git/app.git
$ cd ~/git/app.git
$ git init --bare

This is where your code will be pushed to, but that’s not the code your web server will execute. So I recommend to create the repository outside of your web “scope”.

3/ Create the directory that will contain your app’s code (the one executed by your web server):

$ mkdir -p ~/www/app

4/ Create a post-receive hook. That is where the real magic of all of it lies! This code will be executed every time you push code to that repository. In this post, we simply want to overwrite all the files in the web server with the ones in the repository, so here is how to handle it:

$ nano ~/git/app.git/hooks/post-receive

#!/bin/bash

export GIT_WORK_TREE=/home/bastien/www/app
git checkout -f

$ chmod +x ~/git/app.git/hooks/post-receive

Everything’s ready on the server side, let’s wrap everything up on the client side!

B. On the client side

1/ Add that new bare repository as a remote to your local repository:

$ git remote add production
ssh://bastien@IP/home/bastien/git/app.git

2/ Specify the ref as well (on your first push only):

$ git push production +master:refs/heads/master

3/ To deploy to production, you now simply need to type:

$ git push production

And all your latest work will be pushed to production automatically. No need for FTP, SSH or any custom deployment trick!

C. Conclusion

You might need to make advanced operations before deploying a new version of your code: generating assets, restarting the web server, etc. But as our post-receive script is a bash script, that shouldn’t be too hard!

Happy deployments 😊