Seamless deployment of Django to single server

I have a new website built on Django and Python 2.6 which I’ve deployed to the cloud (buzzword compliant AND the Amazon micro EC2 instance is free!).
Here are my detailed notes:

As this is a new site (and wanting to play with the latest and greatest) I used Nginx and Gunicorn on top of Supervisor.
All software installed from trunk using YUM / easy_install.
My database is Sqlite (for now – not sure of where to go next, but that is not the question). Also on the todo list: virtualenv + pip.
So far so good.
My code in in SVN. I wrote a simple fabfile to deploy – checks out the latest code and restarts Gunicorn via Supervisor. I hooked my DNS name to an Elastic IP.
It works.

  • Is it possible to only deploy the changed files to an AWS Elastic Beanstalk application instead of uploading my whole source code?
  • Push a git repo to a remote server via ssh
  • Symfony2, AWS Beanstalk: how to push vendor as files not git-submodules to repo
  • How to keep a folder content with git
  • aws codecommit cannot push
  • aws.push does not work
  • My question is, how do I update the site without a disruption of service? Users of the site get 404s / 500s when I run my little update script.

    Is there a way to do this without adding another server (price is key)?

    I would love to have a staging system (on a different port?) and a seamless switch between Staging and Production. On the same (free) server. Via Fabric.
    How do I do that? Is it the same Nginx running both sites? Can I upgrade Staging without hurting Production? What would the fabfile look like? What would the directory tree look like?




    • Seamless deployment in Rails

  • Expressjs Deploying to AWS Elastic Beanstalk Errors
  • Should I add Django admin static files to my git repo?
  • DJANGO “Push rejected, no Cedar-supported app detected” — Git Issue
  • The bucket you are attempting to access must be addressed using the specified endpoint , while uploading from jenkins to s3
  • How to set environment variables for Laravel 5 on AWS EC2 with MySQL
  • Using Git For Community-Oriented Website Content Revision System
  • 2 Solutions collect form web for “Seamless deployment of Django to single server”

    Nginx allows you to setup failover for your reverse proxies you can put one gunicorn instance as the primary and as long as that version is running it will never look at the failover.

    If you configure your site so that your new version is in the failover instance you just need to write your fab file to update the failure instance with the new version of the site and then when ready, turn off primary instance. Nginx will seamlessly failover to second instance and bam you are running on new version with no downtime.

    You can then update the primary version and then turn it back on and your primary is now live. At this point you can keep the failover instance running just in case, or turn it off.

    Some things to consider. You have to be careful with databases, if you are using sqllite make sure both gunicorn instances can accesss the sqllite file.

    If you have a normal database this is less of a problem, you just need to make sure you apply any database migrations that the new version needs before you switch to it.

    If they are backwards compatible changes then it isn’t a big deal. If they aren’t backwards compatible then be careful, you could break the old version of the site before you switch over to new version.

    To make things easier I would run the versions on different virtual environments.

    If you use supervisord to control gunicorn, then you can use the supervisorctl commands to reload/restart which ever instance you want to deploy without affecting the other one.

    Hope that helps

    Here is an example of and nginx config (not a full config file, removed the unimportant parts)

    This assumes the primary gunicorn instance is running on port 9005 and the other is running on port 9006

    upstream service-backend {
        server localhost:9005;        # primary
        server localhost:9006 backup; # only used when primary is down
    server {
        listen 80;
        root /opt/htdocs;
        server_name localhost;
        access_log /var/logs/nginx/access.log;
        error_log  /var/logs/nginx/error.log;
        location / {
            proxy_pass http://service-backend;

    Sounds like you need to figure out how to tell gunicorn to gracefully restart. It seems like all you have to do is issue a HUP to the gunicorn process when to notify to reload the app. As describe in the link about, the gunicorn docs explain how to do it.

    Git Baby is a git and github fan, let's start git clone.