4

I am originally a .NET developer and back then when we had to release a software from Visual Studio, we had to switch it to release mode to make sure the debug hooks are removed and the repository files are left behind. The end result was a clean set of files ready to be pushed into production.

After switching to Django and working with it for nearly three months I am now ready to deploy the first app. I have done quite some reading on it. I know how to set the debug to False and having a production_setting.py and how to deploy with WSGI on Apache.

But something I still haven't figured out is a nice process to push out a release.

With what I know now, I would do the following for a release:

  • Copy all the files by hand to a upload directory (excluding hidden mercurial directories)
  • Zip them all
  • sending them over SCP to the Ubuntu server
  • Logging into the server
  • Extracting the zip file and putting everything into place
  • Modifying the setting_production.py and enter the credentials

Is this a healthy process for Django deployment? :)
FYI I am using Aptana Studio 3.2.1

Thanks for any tips

supervacuo
  • 9,072
  • 2
  • 44
  • 61
Houman
  • 64,245
  • 87
  • 278
  • 460
  • 2
    Set up a remote Mercurial repo on the target server. Push to that repo and use a post-receive hook to `checkout` your push into the folder your web server will serve from (and reload your web server if needed). You can also put a condition in your settings file that checks whether the app is on the production server (e.g. check for a file or environmental variable) and load the relevant settings (settings_prod.py or settings_dev.py) – elithrar Aug 06 '12 at 10:23
  • 1
    @elithrar This should be answer. – del-boy Aug 06 '12 at 11:22

2 Answers2

2

You could look into Fabric; the documentation describes it as

... a Python (2.5 or higher) library and command-line tool for streamlining the use of SSH for application deployment or systems administration tasks.

It is capable of doing all the things you want it to.

Your "deploy" task would probably have several sub-tasks (_upload_tar_from_hg(), _migrate() etc.), but the overall picture would be something like:

from fabric.api import * 

env.release_name = 'foo_bar-1.0'
env.deployment_path = '/var/www/django/%s' % env.release_name    

def deploy():
    local('hg archive -t tgz $s.tar.gz' % env.release)
    put('%s.tar.gz' % env.release, env.deployment_dir)
    run('cd %s && tar -xzvf %s.tar.gz' % (env.deployment_path, env.release))
    local('rm %s.tar.gz' % env.release)
    run('cd %s/%s && ln -s settings_production.py settings.py' % (env.deployment_path, env.release))

This relies on having a separate settings_production.py in source control, which may not be appropriate. Fabric can find-and-replace in text files, or you could combine settings using a local_settings.py approach.

Check out the Fabric tutorial to fill in the gaps (like specifying connection details for your server. Once you're set up, just run

fab deploy

and the process should proceed automatically.

NB creating an archive from Mercurial without hg metadata is accomplished in one step with the hg archive command)

Community
  • 1
  • 1
supervacuo
  • 9,072
  • 2
  • 44
  • 61
  • the hg archive helped me already so far quite a bit. That's great for keeping things simpler until a more complex solution is required. +1 Thanks. – Houman Aug 10 '12 at 20:29
1

Set up a remote Mercurial repo on the target server. Using SSH keys with a "hg" user is generally the safest way, as you can just restrict shell access to that user and only allow it access to the repo.

Push to that repo and use a post-receive hook to checkout your push into the folder your web server will serve from (and reload your web server if needed).

You can also put a condition in your settings file that checks whether the app is on the production server (e.g. check for a file or environmental variable) and load the relevant settings (settings_prod.py or settings_dev.py)

elithrar
  • 23,364
  • 10
  • 85
  • 104
  • Sounds interesting, how do I create such post-receive hook ? Thanks – Houman Aug 10 '12 at 20:28
  • @Kave See here: http://mercurial.selenic.com/wiki/Hook - essentially you create a "hook" in your .hgrc file for the project, and then tie it to a script (Python, Ruby, bash; whatever). The script then handles the heavy lifting. e.g you might do a reload of your web-server, or modify a config file, etc. – elithrar Aug 11 '12 at 00:35