Thursday, August 27, 2009

Django - Apache - SVN with production and development environment.

After getting my Django website up and running with Apache and mod_python,
I thought that it would be even better to have two versions of it running. A Production version, that is stable and that has been checked with -almost- no bugs, and a Development version, where I can play around add features, and fix bugs.
And because I am tired of having to do tar files in order to have backups of what I do, I thought it was time to stop being scared of versioning, and give it a go.
It took me a whole week to find a setup that works pretty well on my server, but feel free to leave a comment if think I should have done things differently !

Here is the plan :
 
  1. Install and configure SVN to be able to rollback to a previous version.
  2. Setup a separate Dev and a Prod environment using SVN(subversion).
  3. Apache Virtual Host for Dev and Prod environment.
  4. Different settings.py files on Production and Development

1. Install SVN on Ubuntu.

Run the following command :
sudo apt-get install subversion
Ok now that SVN(Subversion) is installed, we need to decide in which folder you want to have your files saved. SVN is like a database of your files.
You can tell subversion to save the changes you make to a file, a group of files, or a folder, every time you are happy with the changes you've made.
All you have to do is to tell it where you want it to store these infos.
I chose /home/svn/ because I have lots of space on my /home/ directoy, but feel free to change these settings !

To create this directory also called a repository, you need to run the following command :
sudo svnadmin create /home/svn
Now that this is done, you can run ls -l /home/svn to doublecheck that the folder has been created correctly.

Since you have your repository created, ready to be fed with your project, you want to import these files for the first time in SVN. By doing this, SVN will record every changes that you do to your project, and be able to rollback to a previous version of a file in case you made a mistake ! Isn't that great !?

The only thing that you need to know about SVN, is that by convention, you have to create 3 folders that will be containing your project :
  • trunk/
  • tags/
  • branches/
All we are interested in at that level (my level lol) is trunk/ .My project is located in /home/martin/code/martincozzi/, and I want to store it inside /home/svn/martincozzi/trunk/ .

I am now going to prepare my SVN repository to store these files.
mkdir /tmp/martincozzi/trunk
mkdir /tmp/martincozzi/tags
mkdir /tmp/martincozzi/branches
Why /tmp ? Because i am just building a architecture for my SVN and I don't really need these folders after ! To import these files into my SVN repository I type :
sudo svn import /tmp/martincozzi/ file:///home/svn/martincozzi/ -m "Folder Hierarchy Creation"
The -m option stands for Message. I am just leaving a message for myself later on saying "This is when I created my file hierarchy".
Now that this is done. I can now import my project files into my trunk folder. Again, why trunk/ ? It's just a convention so don't worry about it.
sudo svn import /home/code/martincozzi/ file:///home/svn/martincozzi/trunk -m "Importing website into SVN"
Great ! My website is now into the SVN ! What does this mean ? Wherever I am, I can now get the latest version of my project and work on it !

To do this I need to Checkout my project into a folder of my choice !

2. Setup a Dev and Prod environment.
 
Note : Because I want to separate my Dev environment from my Prod environment, I will checkout project inside a /dev folder ! The path to my Dev environment will then be /home/martin/code/dev/martincozzi/ . I strongly recommend that you do the same !
mkdir /home/martin/code/dev/
mkdir /home/martin/code/prod/
To checkout my project into /dev I do the following :
svn checkout file:///home/svn/martincozzi/trunk /home/martin/code/dev/martincozzi
By doing this I get the last version of my project, ready to worked on ! Every change that I make will on this files will be recorded by SVN !
For example edit /home/martin/code/dev/martincozzi/settings.py , save the change, then type in
svn diff
SVN will tell you which files have been edited.

Let's say that I've done a couple of changes, and that I am happy with them. I want to commit my changes to the SVN to tell it that I want to save this changes into a new version. I just type in :
 svn commit -m "Here is a list of changes that I've made : bla bla bla bla "
My changes have been submitted to SVN. I am now ready to show the public the changes that I've made to my webiste. In order to do that, I want it to be published inside /home/martin/code/pub/martincozzi/ . To do so, I will use the export command from svn.
svn export file:///home/svn/martincozzi/trunk/ /home/martin/code/prod/martincozzi/
And I now have the last version of my website in my prod/ folder ! I can now setup Apache to have two addresses, like :
  • dev.martincozzi.com
  • www.martincozzi.com
With dev being the website I am developing and www.martincozzi.com the running version of it !

3. Apache VirtualHost for Prod and Dev sites

If you followed my "How to setup Django & Apache with mod_python and static files" tutorial, just edit the files you've already created as follow.
<VirtualHost *>
  ServerAdmin admin_contact@martincozzi.com
  DocumentRoot /home/martin/code/prod/martincozzi/
  ServerName martincozzi.com
  ServerAlias www.martincozzi.com
  <Location "/">
    SetHandler python-program
    PythonHandler django.core.handlers.modpython
    SetEnv DJANGO_SETTINGS_MODULE martincozzi.settings
    PythonDebug Off
    PythonPath "['/home/martin/code/prod/'] + sys.path"
  </Location>
</VirtualHost>
And for the dev part :
<VirtualHost *>
  ServerAdmin admin_contact@martincozzi.com
  DocumentRoot /home/martin/code/dev/martincozzi/
  ServerName dev.martincozzi.com
  ServerAlias dev.martincozzi.com
  <Location "/">
    SetHandler python-program
    PythonHandler django.core.handlers.modpython
    SetEnv DJANGO_SETTINGS_MODULE martincozzi.settings
    PythonDebug Off
    PythonPath "['/home/martin/code/dev/'] + sys.path"
  </Location>
</VirtualHost>
Easy isn't it ?!

One thing tho .. You settings.py on /prod/ has to be different than your settings.py on /dev/ . Well here's a cool fix !

4. Different settings.py files on Production and Development


To keep up minimum efforts, and not having to change my settings.py file everytime I commit --> export my project, this is what I do !

I copy my /dev/settings.py into /dev/local_settings.py
cp /home/martin/code/dev/martincozzi/settings.py /home/martin/code/dev/martincozzi/local_settings.py
local_settings.py is going to be my config file for /dev/ whereas settings.py is going to be my /prod/ settings file.
In local_settings.py make the following changes :
DEBUG = True
 And in settings.py change it to :
DEBUG = False
 And of course change your MEDIA_ROOT and TEMPLATE_DIRS  according to your templates info, with /prod/ for settings.py, and /dev/ for local_settings.py
Once you've done this, at the bottom of settings.py add the following code :
try:
  from local_settings import *
except ImportError:
  pass
This tries to load the local_settings.py infos, and if it can't then just use the settings.py infos !
Doing this, you can tell SVN no to commit the local_settings.py
 svn propedit svn:ignore local_settings.py .

No comments:

Post a Comment