Upload
erik-labianca
View
1.168
Download
7
Embed Size (px)
Citation preview
{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!
Not so fast.
Lots of external dependencies
Eliminate them with a local cache
Don’t’ forget virtualenv!
Dependencies
lib/pypi-cache:Django-1.4.3.tar.gz
requirements.txt:Django==1.4.3
Type this:pip install --no-index --find-links file://$(PWD)/lib/pypi-cache -r requirements.txt
settings.py
No logic allowed!
‚unknown‛ import times
Critical
Local_settings.py
More of the same
Consider pushing configuration in externally via environ, configparser, etc
Configuration
settings.py:from urlparse import urljoinfrom os import environimport dj_database_url #courtesy of Heroku
DATABASES = dj_database.config(default=‚xxx‛)BASE_URL = environ*‘DJANGO_BASE_URL’+STATIC_URL = urljoin(BASE_URL, ‘static’)MEDIA_URL = urljoin(BASE_URL, ‘media’)
Run this:DJANGO_BASE_URL=http://cdn.com/base/django-admin.py runserver
Fixtures. Consider writing them in Python!
Testable
More resilient to change
Less pk pain
Migrations!
Test them
Application: Database
fixtures/polls.py:from ..models import Poll, Choicedef apply():p = Poll.objects.get_or_create(q=‘test q’, defaults=dict(pub_date=‘1980-01-01))
c1 = Choices.objects.get_or_create(poll=p,choice_text=‘option 1’)
fixtures/tests/test_poll.py:Class PollFixtureTestCase(TestCase):def test_fixture_applied():self.assertEquals(Poll.objects.get(q=‘test q’)
management/__init__.py:from django.db.models.signals import post_syncdbfrom south.signals import post_migratefrom .. 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)
Back Up Everything!
Move files to Green Fabric?
RPM?
Tar?
Git?
Rsync?
Update Stuff syncdb
apply fixtures
Test Green!
Flip/Flop Blue/Green
(Roll back to Blue)
Deployment: Blue/Green
Data
App App
Interwebs
Deploy / Test
Erik LaBianca, WiserTogether, Inc.
@easel
https://linkedin.com/in/eriklabianca/
https://slideshare.net/easel1/
https://github.com/easel/
https://github.com/WiserTogether/
Questions?