CONRADKRAMERSign in

article← all posts

Deploy a Website Using Git in Ubuntu

·12:00 PDT·2 min·updated

This is a follow up to my previous post on how to set up a Flask web app with nginx and uWSGI. This post will run down how to set up a git-based deployment system for that web app. Git is pretty popular for deployment, and is used in services like Heroku. Heroku is great, but I prefer to have full control over my server, and roll my own stuff, all while maintaining the same ease of use.

Repository setup

To continue from my previous example, the website is deployed in /srv/www/helloworld. This tutorial should work with pretty much any website, but it will still focus on Flask based ones.

First, if you have not already done so, install git.

unknown node

Next, put your website under version control with git

unknown node

A gitignore file is also a good idea. For a Flask app, put the following in .gitignore

unknown node

and to add it to the repository

unknown node

Now we are going to create a bare 'hub' repository that will act as an intermediary between the active deployment folder and the rest of the world.

unknown node

Next, add the hub as a remote for the deployment repository

unknown node

Add the magic

To automatically update the deployment repository when changes are pushed to the hub, we are going to use git hooks. Git hooks are scripts that are executed after certain changes occur within the repository.

To begin, add the following to /srv/git/helloworld.git/hooks/post-update

unknown node

and make sure that it is executable

unknown node

This post-update script updates the deployment repository when the hub is updated. Next, we are going to setup the reverse, a hook to update the hub when changes are committed in the deployment directory (this should be rare, but just in case). Add the following to /srv/www/helloworld/.git/hooks/post-commit

unknown node

and add make it executable

unknown node

Further modification

If you went ahead and tested the deployment system, you'd find that the changes aren't reflected in your browser yet. uWSGI is still using the old compiled python files, and did not notice the changes to the directory. To get uWSGI to notice the changes, you have to reload it every time you push changes. A reload command can be added to the git hook, but it isn't as easy as it sounds. You need root privileges to reload uWSGI, and when you push changes to the server, you are most likely logging in as your own personal user. The solution to this problem is to create a setuid binary that reloads uWSGI.

First, install the Ubuntu build-essential package

unknown node

Next, put the following in ~/reload_uwsgi.c

unknown node

Now to compile, install and configure the binary

unknown node

And lastly add this executable to our git hooks, which should look like the following

/srv/git/helloworld.git/hooks/post-update:

unknown node

/srv/www/helloworld/.git/hooks/post-commit:

unknown node

Testing it out

Clone the repository on your local machine

unknown node

Make some changes, commit them to master, and push them to the server

unknown node

and voila! The change should be reflected on the website.

Discuss on Hacker News here.

Discussed on Hacker News — 50 points, 21 comments.