SlideShare a Scribd company logo
Django Deployment
  {   Tips, Tricks and Best Practices
   You mission, should you choose to accept it:
           Make your application run with 1 click,
            everywhere it counts, every time.
           Make your application run exactly the same way,
            everywhere it counts, every time.
           Prove that the above are true.




Reproducibility
   Reproducible Infrastructure
       Reproducible Systems
       Reproducible [Django] Applications
           Dependencies
           Configuration
           Data
           Deployment




Steps to Reproducibility
   Systems: Virtual or Physical
            Power Management
            Console
            Backup / Restore
        Network Layer
            Load Balancing
            Security
            Performance




Infrastructure
   A Stable Foundation
           Stable Operating System
           Reproducible Installation
                Kickstart Install
                Base Image
       Configuration Management
           Puppet, Chef
       Packaging




Systems
   What Python?
           How will you install packages?
           How will you make it reproducible?
       Database?
           Backup / Restore
           Failover
           Performance
       Caching?
           HTTP
           Objects
       Queuing?
       SSL?




Application Environment
   It’s just code, right?
            Probably Not




Application
   Just use pip!          lib/pypi-cache:
                           Django-1.4.3.tar.gz
   Not so fast.
       Lots of external   requirements.txt:
        dependencies       Django==1.4.3
       Eliminate them
        with a local       Type this:
                           pip install --no-index --find-links
        cache
                           file://$(PWD)/lib/pypi-cache -r
   Don’t’ forget          requirements.txt
    virtualenv!




     Dependencies
   settings.py              settings.py:
        No logic allowed!   from urlparse import urljoin
        ‚unknown‛           from os import environ
         import times        import dj_database_url #courtesy of Heroku
        Critical
   Local_settings.py        DATABASES =
        More of the same    dj_database.config(default=‚xxx‛)
                             BASE_URL = environ*‘DJANGO_BASE_URL’+
   Consider pushing         STATIC_URL = urljoin(BASE_URL, ‘static’)
    configuration in         MEDIA_URL = urljoin(BASE_URL, ‘media’)
    externally via
    environ,                 Run this:
    configparser, etc        DJANGO_BASE_URL=http://cdn.com/base/
                             django-admin.py runserver



Configuration
   Fixtures. Consider      fixtures/polls.py:
    writing them in         from ..models import Poll, Choice
                            def apply():
    Python!                   p = Poll.objects.get_or_create(q=‘test q’,
       Testable                defaults=dict(pub_date=‘1980-01-01))
                              c1 = Choices.objects.get_or_create(poll=p,
       More resilient to
                                choice_text=‘option 1’)
        change
       Less pk pain        fixtures/tests/test_poll.py:
                            Class PollFixtureTestCase(TestCase):
                              def test_fixture_applied():
   Migrations!                 self.assertEquals(Poll.objects.get(q=‘test q’)
       Test them




        Application: Database
management/__init__.py:
from django.db.models.signals import post_syncdb
from south.signals import post_migrate
from .. import models, fixtures

def update_poll_fixtures(verbose=True):
    fixtures.poll.apply()
    if verbose:
        print "Updating dynamic fixtures for profile”

def update_fixtures_post_syncdb(sender, **kwargs):
  update_poll_fixtures()

def update_fixtures_post_migrate(app, **kwargs):
if app == ’polls':
  update_poll_fixtures()

post_syncdb.connect(fixtures_post_syncdb, sender=models)
post_migrate.connect(fixtures_post_migrate)
Interwebs
   Back Up Everything!
   Move files to Green
       Fabric?
       RPM?
       Tar?
       Git?
       Rsync?
                           App               App   Deploy / Test
   Update Stuff
       syncdb
       apply fixtures
   Test Green!
   Flip/Flop Blue/Green           Data
   (Roll back to Blue)


     Deployment: Blue/Green
Erik LaBianca, WiserTogether, Inc.
    erik.labianca@gmail.com
    @easel
    https://linkedin.com/in/eriklabianca/
    https://slideshare.net/easel1/
    https://github.com/easel/
    https://github.com/WiserTogether/




Questions?

More Related Content

Django deployment best practices

  • 1. Django Deployment { Tips, Tricks and Best Practices
  • 2. You mission, should you choose to accept it:  Make your application run with 1 click, everywhere it counts, every time.  Make your application run exactly the same way, everywhere it counts, every time.  Prove that the above are true. Reproducibility
  • 3. Reproducible Infrastructure  Reproducible Systems  Reproducible [Django] Applications  Dependencies  Configuration  Data  Deployment Steps to Reproducibility
  • 4. Systems: Virtual or Physical  Power Management  Console  Backup / Restore  Network Layer  Load Balancing  Security  Performance Infrastructure
  • 5. A Stable Foundation  Stable Operating System  Reproducible Installation  Kickstart Install  Base Image  Configuration Management  Puppet, Chef  Packaging Systems
  • 6. What Python?  How will you install packages?  How will you make it reproducible?  Database?  Backup / Restore  Failover  Performance  Caching?  HTTP  Objects  Queuing?  SSL? Application Environment
  • 7. It’s just code, right?  Probably Not Application
  • 8. Just use pip! lib/pypi-cache: Django-1.4.3.tar.gz  Not so fast.  Lots of external requirements.txt: dependencies Django==1.4.3  Eliminate them with a local Type this: pip install --no-index --find-links cache file://$(PWD)/lib/pypi-cache -r  Don’t’ forget requirements.txt virtualenv! Dependencies
  • 9. settings.py settings.py:  No logic allowed! from urlparse import urljoin  ‚unknown‛ from os import environ import times import dj_database_url #courtesy of Heroku  Critical  Local_settings.py DATABASES =  More of the same dj_database.config(default=‚xxx‛) BASE_URL = environ*‘DJANGO_BASE_URL’+  Consider pushing STATIC_URL = urljoin(BASE_URL, ‘static’) configuration in MEDIA_URL = urljoin(BASE_URL, ‘media’) externally via environ, Run this: configparser, etc DJANGO_BASE_URL=http://cdn.com/base/ django-admin.py runserver Configuration
  • 10. Fixtures. Consider fixtures/polls.py: writing them in from ..models import Poll, Choice def apply(): Python! p = Poll.objects.get_or_create(q=‘test q’,  Testable defaults=dict(pub_date=‘1980-01-01)) c1 = Choices.objects.get_or_create(poll=p,  More resilient to choice_text=‘option 1’) change  Less pk pain fixtures/tests/test_poll.py: Class PollFixtureTestCase(TestCase): def test_fixture_applied():  Migrations! self.assertEquals(Poll.objects.get(q=‘test q’)  Test them Application: Database
  • 11. management/__init__.py: from django.db.models.signals import post_syncdb from south.signals import post_migrate from .. import models, fixtures def update_poll_fixtures(verbose=True): fixtures.poll.apply() if verbose: print "Updating dynamic fixtures for profile” def update_fixtures_post_syncdb(sender, **kwargs): update_poll_fixtures() def update_fixtures_post_migrate(app, **kwargs): if app == ’polls': update_poll_fixtures() post_syncdb.connect(fixtures_post_syncdb, sender=models) post_migrate.connect(fixtures_post_migrate)
  • 12. Interwebs  Back Up Everything!  Move files to Green  Fabric?  RPM?  Tar?  Git?  Rsync? App App Deploy / Test  Update Stuff  syncdb  apply fixtures  Test Green!  Flip/Flop Blue/Green Data  (Roll back to Blue) Deployment: Blue/Green
  • 13. Erik LaBianca, WiserTogether, Inc. erik.labianca@gmail.com @easel https://linkedin.com/in/eriklabianca/ https://slideshare.net/easel1/ https://github.com/easel/ https://github.com/WiserTogether/ Questions?

Editor's Notes

  1. ----- Meeting Notes (2/12/13 12:10) -----json fixtures: primary key problems, skips model.save, fixtures get of date when model changes