Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tim Penhey: Deploying a Django application using Juju

Tim Penhey: Deploying a Django application using Juju

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Tim Penhey:
Deploying a Django application using Juju
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
@ Kiwi PyCon 2014 - Sunday, 14 Sep 2014 - Track 2
http://kiwi.pycon.org/

**Audience level**

Intermediate

**Description**

Juju is a service orchestration tool for deploying services into public or private clouds. I will talk about how I deployed my Django application using Juju.

**Abstract**

Juju is a service orchestration tool for deploying services into public or private clouds. The services that Juju deploys are described in Charms. A Charm should use the "best practice" for deploying the service. In the case of Django, this would be using gunicorn and nginx. I explain how the postgresql charm communicates with the django charm, and how I had to change my application's settings and urls to work with the django charm. The application that is deployed is a "proprietary" app, and as such, the deployment of the application itself is done with another charm. The interaction between the subordinate charms and the principal django charm are explained, and how the data is exchanged between the charms. As well as the deployment story, I also explain how application updates are deployed very simply.

**YouTube**

https://www.youtube.com/watch?v=6hc8VkFeHjA

6b880a0b67fac54c42c77fe70d97334d?s=128

New Zealand Python User Group

September 14, 2014
Tweet

Transcript

  1. Deploying a Django based application with Juju Tim Penhey @howbazaar

  2. or perhaps

  3. How I used Juju to deploy our Django based website

    to Amazon EC2 Tim Penhey @howbazaar
  4. • Not a Django talk • Not about how Juju

    works • Not lots of python code What this talk is not
  5. Backstory • Rachel had this cool idea… • I said

    “I know how to do that…”
  6. Backstory • Co-founded “know about when and where” (kawaw) with

    Rachel Saunders and Brenton Hall • Web site and mobile application combo • MVP ready… now what?
  7. • Django • PostgreSQL • jQuery, backbone.js • PhoneGap The

    basics
  8. Developing on my laptop We did what all developers did…

    ./manage.py runserver … but then, after a while … ./manage.py runserver_plus
  9. Making it publicly visible Now we had real issues •

    keeping the site alive • backups • secure connections • scalability
  10. Disclaimer I work for Canonical on the Juju project

  11. What is Juju? • Service orchestration in the cloud Configure,

    manage, maintain, deploy and scale efficiently with best-practice Charms on any public, private or hybrid cloud from a powerful GUI or the command-line.
  12. Charms give Juju its power • encapsulate application configurations •

    define how services get deployed • define how they connect to other services • know how to scale
  13. but really… why?

  14. None
  15. Existing charms postgresql python-django gunicorn

  16. Test deployment locally • deploy into LXC containers on my

    laptop • same charms are used • tests interaction
  17. Juju can help with scaling later • Add ha-proxy, memcached

    • Multiple database servers • Scale out the application servers
  18. Simple repeatable deployments • Repeatability is a key • New

    code as easy as upgrading a charm
  19. however private codebase

  20. Writing a subordinate charm • Simplest way to get code

    on to the same machine as the python-django charm was to write a subordinate charm • a.k.a. payload charm • puts the python code and resources into the right place on the disk
  21. Hooks • install • config-changed • upgrade-charm • python-django-relation-joined •

    python-django-relation-changed
  22. Hooks - continued • Hooks are just scripts • Juju

    is hook language agnostic • Just needs to be executable • I use python (with charm-helpers)
  23. Hooks - reality • Install packages ◦ apt, pip ◦

    install, upgrade-charm • Everything else ◦ copy code across ◦ config-changed, relationship hooks ◦ config-changed also gets called after upgrade- charm
  24. Charm settings.py import glob from os.path import abspath, dirname, join

    PROJECT_DIR = abspath(dirname(__file__)) conffiles = glob.glob(join(PROJECT_DIR, '{{ dir }}', '*.py')) conffiles.sort() if not 'INSTALLED_APPS' in locals(): from django.conf.global_settings import * for f in conffiles: exec(open(abspath(f)).read())
  25. First real code change • break up settings.py • charm

    makes files based on relationships or configuration settings ◦ config options ▪ 10-secret.py ▪ 30-allowed.py ▪ 40-debug.py ▪ 50-extra-config.py ◦ relationships - e.g. postgresql ▪ 20-engine-pgsql.py
  26. Mirror the charm settings • Very similar base settings.py •

    Added settings dir ◦ 10-secret.py - SECRET_KEY ◦ 15-defaults.py - template loaders, base apps ◦ 20-database.py - local db settings ◦ 25-static-files.py - STATIC* settings ◦ 30-debug.py - DEBUG and TEMPLATE_DEBUG ◦ 40-project.py - root urls, wsgi app ◦ 45-debug-toolbar-juju.py ◦ 50-kawaw-juju.py ◦ 60-allauth-juju.py ◦ 70-logging-juju.py ◦ 80-email-juju.py
  27. urls.py was next • Similar loading pattern for urls •

    Kinda makes sense for a framework charm
  28. First deployment

  29. None
  30. Error • Improperly configured • hmm… more info needed •

    increased logging • turned on debug
  31. Second deployment

  32. None
  33. Error • debug toolbar not configured • manual registration needed

    for urls if not using ./manage.py
  34. Third deployment

  35. None
  36. Error • allauth not configured • hadn’t set up the

    google and facebook entries • oh yeah… • off to the admin interface
  37. None
  38. No CSS, no images • default static file serving not

    enabled with gunicorn • google suggests nginx
  39. nginx • no promoted nginx charm • I wanted it

    to run beside the django charm • simplest approach was to roll it into the kawaw subordinate • added SSL • ./manage.py collectstatic --noinput
  40. Fourth deployment

  41. OMG - it worked!

  42. kawaw charm makefile update-payload: @mkdir -p payload/ssl @cat ../../../requirements.txt |

    grep -v "^pytz" | grep -v "^psycopg2" > payload/requirements.txt @cp -r ../../../wit payload @cp ../../ssl/server.key payload/ssl @cp ../../ssl/kawaw.pem payload/ssl @rm -r payload/wit/fixtures
  43. Deploying updated code $ juju upgrade-charm kawaw That’s it

  44. Lessons learned

  45. Lessons learned • insufficient documentation around using the python-django charm,

    had to read the code • insufficient documentation around how to write a payload charm for python-django, very much work it out as you go
  46. Lessons learned • python-django and gunicorn still needs nginx to

    be really useful • should have a full stack django charm that includes gunicorn and nginx by default ◦ that just knows how to enable SSL for apps
  47. Future work • PostgreSQL charm has daily backups by default,

    need to test restore • Database still lives on the ephemeral instance, need to move it elsewhere • Automated staging site based of production that has a copy of production database
  48. Juju commands cd ~/src/wit/working/juju export JUJU_REPOSITORY=$(pwd) juju bootstrap --constraints 'mem=2048

    root-disk=20G' juju deploy --to 0 cs:trusty/postgresql --config kawaw-prod.yaml juju deploy --to 0 local:python-django --config kawaw-prod.yaml juju deploy local:gunicorn juju add-relation postgresql:db python-django juju add-relation python-django gunicorn juju deploy local:kawaw juju add-relation python-django kawaw juju expose kawaw
  49. Questions?