Writing about this topic came to my mind few weeks ago when i had a couple of problems deploying a Django application to a production server.
Many of us knows that when you are developing your applications using django’s development server at the time to make it real and pass it to production many times things doesn’t go exactly as expected and you end up dealing with problems that you didn’t count with. For this reason this last week i started to make my development environments the most similar possible with production by using nginx which is the web server that i use most.
So my objective was to have a remote machine which would contain the webserver and also a repository system in which i can push/pull/update(and so on) the changes from my desktop machine and from there it take immediately effect on the webserver.
To achieve this goal had to install in my server 4 things:
So now its time to pass to the configuration.
First create a repository:$ cd ~/repo
$ hg init project
The folder you create your repository its arbitrary, but i would recommend you to do it on a standard folder such as /var/www.
Now we will create our django project inside of it$ cd project
$ django-admin.py startproject project
At this point we have already our repository with a template of a django project.
You can can add the created file and commit your changes, but if you try to push it it will fail and you will get an error like this:$ hg commit -m “First commit” $ hg push abort: repository default-push not found!
This is because we didn’t configure properly our repository yet. So now its time to configure it. Go back to the repository root and in it you will have a hidden folder .hg, this folder contains a file called hgrc( attention ::: I mean hgrc, not .hgrc).
Edit it with your favorite text editor, in my case vim.$ vim .hg/hgrc
Now will be possible to push your project with the first commit.$ hg push
We complete the first step, but it didn’t finished yet. Now its time to configure our django fastCGI and Nginx. If you don’t know how to do it try to google it or go to this example.
Go to your django project inside your project and start fastCGI startup. It will be important to pass a pidfile to it.$ cd ~/repo/project/project $ python manage.py runfcgi socket=/tmp/project.sock pidfile=/tmp/project.pid
If you followed the last example you shall be able to start Nginx with Django fastCGI and at this point your web server is already serving your django project which is inside your repository.
You shall be already able to clone this project to another machine, but regardless all the changes you have made once you try to push it from there two things will happen.
- The project on the web server will not be updated
- Nginx will not get restarted and the previous project will keep being served.
To workaround this two issues we will use mercurial hooks that are functions that are triggered and executed after a certain events happens in mercurial.
So go back to your hgrc file and there you can configure it. Once Again use your favorite text editor to do this$ cd ~/repo/project $ vim .hg/hgrc 1 [paths]
Read the hooks link to know more about what changegroup and incoming does, but if you look it shall be obvious what it will do. Line 5 will solve the issue number 1 and line 6 has a path to a shell script that will solve the problem number two.
All we have to do now is to write that shell script.$ cd ~/repo/project $ vim hook.sh 1 PIDFILE=”/tmp/project.pid” 2 PROJECT_PATH=”~/repo/project/project” 3 SOCKET_FILE=”/tmp/project.sock” 4 pid=`cat $PIDFILE` 5 kill $pid 6 python $PROJECT_PATH/manage.py runfcgi socket=$SOCKET_FILE pidfile=$PIDFILE 7 /etc/init.d/nginx restart
Perhaps you will need to give execution permission to this script.
$ chmod +x ~/repo/project/hook.sh
Now if everything went ok its everything done. Now, you can clone the project from other machines and once you push it this shell script will kill the last fastCGI process, start a new one and restart nginx so this way your changes takes immediate effect in your web server.
This is only a basic tutorial for a real simple situation but from here you shall have the bases and adapt it to your situation.