• Save
PyCon talk: Deploy Python apps in 5 min with a PaaS
Upcoming SlideShare
Loading in...5
×
 

PyCon talk: Deploy Python apps in 5 min with a PaaS

on

  • 5,239 views

How can you avoid servers and get back to coding? Platform-as-a-service (PaaS) makes deployment easy. But which PaaS do you choose and how do you get started? This talk will examine several of the ...

How can you avoid servers and get back to coding? Platform-as-a-service (PaaS) makes deployment easy. But which PaaS do you choose and how do you get started? This talk will examine several of the leading PaaS providers and discuss their pros/cons. We'll also give examples for how to deploy the same app to each of them to see the differences.

Statistics

Views

Total Views
5,239
Views on SlideShare
2,745
Embed Views
2,494

Actions

Likes
9
Downloads
0
Comments
0

8 Embeds 2,494

http://appsembler.com 2349
http://lanyrd.com 99
http://feeds.feedburner.com 34
http://eventifier.co 7
http://www.google-analytics.com 2
http://reader.aol.com 1
http://www.google.ch 1
http://www.google.com.au 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

PyCon talk: Deploy Python apps in 5 min with a PaaS PyCon talk: Deploy Python apps in 5 min with a PaaS Presentation Transcript

  • DEPLOY PYTHON APPS IN 5 MINUTES WITH A PAAS Nate Aune (@natea) PyCon Santa Clara March 15, 2013Sunday, March 17, 13 1
  • JAZKARTA (2004-NOW)Sunday, March 17, 13 2
  • 2010-2011 • Nothing equivalent to Heroku for Django developers • Built my own PaaS (“How hard can it be?”) • Shut down last year. Increased competition from big corps meant a race to the bottomSunday, March 17, 13 3
  • APPSEMBLER (2012-CURRENT)Sunday, March 17, 13 4
  • AGENDA • Why should I care? • What is a PaaS? What are the advantages? • Which PaaS should I use? • When might I not want to use a PaaS?Sunday, March 17, 13 5
  • WHERE ARE YOU DEPLOYING/HOSTING TODAY? • Shared hosting (i.e. Webfaction) • Running your own servers (co-located)? • Using an IaaS provider (i.e. AWS or Rackspace) • Already using a platform-as-a-service (PaaS)Sunday, March 17, 13 6
  • MEET DAVESunday, March 17, 13 7
  • Sunday, March 17, 13 8
  • CONFIGURING A SERVER • deciding what size to get (memory, disk) • getting all the dependencies installed on it • SSHing into the machine to deploy stuff (feels dirty, but he’s under time pressure) 1  day 1  daySunday, March 17, 13 9
  • MAINTAINING THE SERVER 1  day 1  day 1  daySunday, March 17, 13 10
  • SECURITY 1  day 1  day 1  day 1  daySunday, March 17, 13 11
  • SCALING 1  day 1  day 1  day 1  day 1  daySunday, March 17, 13 12
  • OH SH*TMOMENT.Sunday, March 17, 13 13
  • Sysadmin $80ktesed DBA $90k Train new guy 6 8 daysSunday, March 17, 13 14
  • WHY TOUCH SERVERS IF YOU DON’T HAVE TO?Sunday, March 17, 13 15
  • PaaS Is  it  the  promised  land?Sunday, March 17, 13 16
  • WHAT IS A PAAS? Platform-as-a-Service enables developers to create innovative applications without operational overhead around configuration, deployment and management.Sunday, March 17, 13 17
  • LAYERS OF INFRASTRUCTURE Source: EngineYard “PaaS - State of the Market Survey” May 2012 - http://venturebeat.com/2012/07/05/engine-yard-paas-infographic/Sunday, March 17, 13 18
  • Source: EngineYard “PaaS - State of the Market Survey” May 2012 - http://venturebeat.com/2012/07/05/engine-yard-paas-infographic/Sunday, March 17, 13 19
  • Source: EngineYard “PaaS - State of the Market Survey” May 2012 - http://venturebeat.com/2012/07/05/engine-yard-paas-infographic/Sunday, March 17, 13 20
  • Source: EngineYard “PaaS - State of the Market Survey” May 2012 - http://venturebeat.com/2012/07/05/engine-yard-paas-infographic/Sunday, March 17, 13 21
  • Source: AppFog “Evolution of the Cloud: Toward a NoOps World” Jan 2012 http://gigaom.com/cloud/why-2013-is-the-year-of-noops-for-programmers-infographic/Sunday, March 17, 13 22
  • EFFICIENT, ELASTIC, SECURE • Lots of applications co-located on a few servers • Drastically reduces resources • Add/remove capacity depending on load • All secured using SELinux or LXCSunday, March 17, 13 23
  • LET THEM DO THE BORING STUFF • Patches and updates • Migrating applications • Backups / snapshots • Configuring everything (web servers, load balancers, modules, databases)Sunday, March 17, 13 24
  • FOLLOW ALONG! $ git clone http://github.com/appsembler/paasbakeoff $ git branch dotcloud elasticbeanstalk gae heroku * master mezzpycon openshift stackatoSunday, March 17, 13 25
  • Sunday, March 17, 13 26
  • DEFINE OS DEPENDENCIES www: type: python systempackages: - openoffice.org - mysql-client-5.1 5  minSunday, March 17, 13 27
  • BACKUPS 5m 5m https://devcenter.heroku.com/articles/heroku-postgres-forkSunday, March 17, 13 28
  • SSL 5m 5m 5mSunday, March 17, 13 29
  • SCALING 5m 5m 5m 5mSunday, March 17, 13 30
  • CACHING 5m 5m 5m 5m 5mSunday, March 17, 13 31
  • IAAS VS. PAAS IaaS - days PaaS - minutesSunday, March 17, 13 32
  • WHICH PAAS? • Hosted • DIY • HybridSunday, March 17, 13 33
  • WHO ARE THE PLAYERS? • CloudFoundry (open source by VMWare) • Heroku (now Salesforce) • OpenShift (Redhat’s open source PaaS) • AppFog • Dotcloud • App Engine (Google) • Stackato (ActiveState) • Gondor (Python only) • Elastic Beanstalk (Amazon) • Azure (Microsoft)Sunday, March 17, 13 34
  • WHO ARE THE PLAYERS? We’ll look at these ones today. • CloudFoundry (open source by VMWare) • Heroku • OpenShift (now Salesforce) (Redhat’s open source PaaS) • AppFog • Dotcloud • App Engine (Google) • Stackato (ActiveState) • Gondor • Elastic Beanstalk (Python only) (Amazon) • Azure (Microsoft)Sunday, March 17, 13 35
  • HEROKU by Salesforce One of the first PaaS, extensive add-ons catalogSunday, March 17, 13 36
  • Sunday, March 17, 13 37
  • Sunday, March 17, 13 38
  • ANATOMY OF A DJANGO APP ON HEROKU customized settings.py for Heroku if not using S3, must configure static serve Procfile to configure process requirements.txt to define dependenciesSunday, March 17, 13 39
  • INSTALL THE HEROKU TOOLBELT Download the Heroku Toolbelt http://toolbelt.herokuapp.com/osx/download $ heroku login Enter your Heroku credentials. Email: someone@example.com Password: ****** Could not find an existing public key. Would you like to generate one? [Yn] Generating new SSH public key. Uploading ssh public key /Users/someone/.ssh/id_rsa.pubSunday, March 17, 13 40
  • CREATE APP AND DB $ heroku create paasbakeoff Creating paasbakeoff... done, stack is cedar http://paasbakeoff.herokuapp.com/ | git@heroku.com:paasbakeoff.git Git remote heroku added $ heroku addons:add heroku-postgresql:dev Adding heroku-postgresql:dev on paasbakeoff... done, v3 (free) Attached as HEROKU_POSTGRESQL_GREEN_URL Database has been created and is available Use `heroku addons:docs heroku-postgresql:dev` to view documentation. $ heroku pg:info === HEROKU_POSTGRESQL_GREEN_URL Plan: Dev Status: availableSunday, March 17, 13 41
  • SET DB ENV VARIABLES $ heroku config === paasbakeoff Config Vars HEROKU_POSTGRESQL_GREEN_URL: postgres://x:y@z.com:5432/d2b3c9ichbauv0 $ heroku pg:promote HEROKU_POSTGRESQL_GREEN Promoting HEROKU_POSTGRESQL_GREEN_URL to DATABASE_URL... done $ heroku config === paasbakeoff Config Vars DATABASE_URL: postgres://x:y@z.com:5432/d2b3c9ichbauv0Sunday, March 17, 13 42
  • ADD TO SETTINGS.PY Set the RACK_ENV environment variable to production $ heroku config:set RACK_ENV=productionSunday, March 17, 13 43
  • USE S3 FOR SERVING STATIC AND MEDIA FILES And Sendgrid for sending emailsSunday, March 17, 13 44
  • PROCFILE web: gunicorn_django -b 0.0.0.0:$PORT -w 9 -k gevent --max-requests 250 --preload mywebsite/settings.py Configure AWS settings $ heroku config:set AWS_ACCESS_KEY_ID=xxxxxxxxxxxxxxxxx $ heroku config:set AWS_SECRET_ACCESS_KEY=yyyyyyyyyyyyyyyyyyyyyyyyy $ heroku config:set AWS_STORAGE_BUCKET_NAME=zzzzzzzzzzzzz Sync, migrate, collectstatic $ heroku run python mywebsite/manage.py createdb $ heroku run python mywebsite/manage.py collectstaticSunday, March 17, 13 45
  • $ git push heroku master Counting objects: 8, done. DEPLOY WITH GIT PUSH Delta compression using up to 2 threads. Compressing objects: 100% (6/6), done. Writing objects: 100% (6/6), 616 bytes, done. Total 6 (delta 3), reused 0 (delta 0) -----> Heroku receiving push -----> Python/Django app detected -----> Preparing Python interpreter (2.7.2) -----> Creating Virtualenv version 1.7.2 New python executable in .heroku/venv/bin/python2.7 ... Running virtualenv with interpreter /usr/local/bin/python2.7 -----> Activating virtualenv -----> Installing dependencies using pip version 1.1 Downloading/unpacking Django==1.4.2 (from -r requirements.txt (line 1)) ... Cleaning up... -----> Collecting static filesSunday, March 17, 13 46
  • ANATOMY OF A DJANGO APP ON HEROKU customized settings.py for Heroku Procfile to configure process requirements.txt to define dependenciesSunday, March 17, 13 47
  • MORE HEROKU RESOURCES • Getting Started with Django on Heroku https://devcenter.heroku.com/articles/django • Heroku Hackers Guide ($10 eBook) http://theherokuhackersguide.com • Developers Guide to Running Django Applications on Heroku http://kencochrane.net/blog/2011/11/developers-guide-for-running-django-apps-on-heroku/ • django-skel http://django-skel.readthedocs.orgSunday, March 17, 13 48
  • DOTCLOUD polyglot from the start, very flexible, most Python centricSunday, March 17, 13 49
  • Sunday, March 17, 13 50
  • Sunday, March 17, 13 51
  • ANATOMY OF A DJANGO APP ON DOTCLOUD customized settings.py for Dotcloud createdb.py to create the database dotcloud.yml to store config info mkadmin.py to make the admin user nginx.conf to config URL rewriting postinstall to run syncdb, collectstatic wsgi.py to serve using uWSGISunday, March 17, 13 52
  • INSTALL THE DOTCLOUD CLIENT $ sudo pip install dotcloud $ dotcloud setup dotCloud username or email: natea@jazkarta.com Password: ==> dotCloud authentication is complete! You are recommended to run `dotcloud check` now.Sunday, March 17, 13 53
  • CREATE AND PUSH AN APP $ dotcloud create mezz ==> Creating a sandbox application named "mezz" ==> Application "mezz" created. Connect the current directory to "mezz"? [Y/n]: ==> Connecting with the application "mezz" ==> Connected with default push options: --rsync $ dotcloud push ==> Pushing code with rsync from "./" to application mezz building file list ... done 14:17:51: [www.0] Migrating stateful data located in ~/data 14:18:05: [www.0] Launching... 14:18:07: [www.0] Re-routing traffic to the new build... 14:18:08: [www.0] Successfully installed build revision rsync instance #0Sunday, March 17, 13 54
  • ANATOMY OF A DJANGO APP ON DOTCLOUD customized settings.py for Dotcloud createdb.py to create the database dotcloud.yml to store config info mkadmin.py to make the admin user nginx.conf to config URL rewriting postinstall to run syncdb, collectstatic wsgi.py to serve using uWSGISunday, March 17, 13 55
  • DOTCLOUD.YMLSunday, March 17, 13 56
  • DATABASE IN SETTINGS.PYSunday, March 17, 13 57
  • STATIC_ROOT AND MEDIA_ROOT INSunday, March 17, 13 58
  • NGINX.CONFSunday, March 17, 13 59
  • POSTINSTALLSunday, March 17, 13 60
  • CREATEDB.PY AND MKADMIN.PY createdb.py https://github.com/dotcloud/django-on-dotcloud/blob/master/createdb.py mkadmin.pySunday, March 17, 13 61
  • MORE RESOURCES • Dotcloud Python docs http://docs.dotcloud.com/0.9/services/python/ • Dotcloud Django docs http://docs.dotcloud.com/0.9/tutorials/python/django/ • django-on-dotcloud https://github.com/dotcloud/django-on-dotcloud/ • python-on-dotcloud https://github.com/kencochrane/python-on-dotcloudSunday, March 17, 13 62
  • STACKATO by ActiveState Python 3, Run anywhere, New Relic integration http://appsembler.com/blog/django-deployment-using-stackato/Sunday, March 17, 13 63
  • Sunday, March 17, 13 64
  • Sunday, March 17, 13 65
  • ANATOMY OF DJANGO APP ON STACKATO customized settings file stackato.yml to define services wsgi.py to serve using uWSGISunday, March 17, 13 66
  • STACKATOSunday, March 17, 13 67
  • Sunday, March 17, 13 68
  • Secure using Linux Containers (LXC)Sunday, March 17, 13 69
  • NEW RELICSunday, March 17, 13 70
  • Consistent deployment at all stages of the lifecycleSunday, March 17, 13 71
  • STACKATO FOR DJANGO 1.Download the Stackato client http://www.activestate.com/stackato/download_client 2.Create a wsgi.py file 3.Create a requirements.txt file (if you don’t already have one) 4.Edit the DATABASES and MEDIA_ROOT settings in settings.py file 5.Create a stackato.yml file to persist theSunday, March 17, 13 72
  • WSGI.PY FILESunday, March 17, 13 73
  • REQUIREMENTS.TXT Django==1.4.2 psycopg2==2.4.5 -e git+git@github.com:yourname/django-awesome.git#egg=django-awesome Or you can just reference another requirements file in your repo -r requirements/project.txtSunday, March 17, 13 74
  • DATABASE OVERRIDESSunday, March 17, 13 75
  • MEDIA_ROOTSunday, March 17, 13 76
  • TARGET AND LOGIN $ stackato target api.appsembler.net $ stackato login --email user@domain.com Attempting to login to [https://api.appsembler.net] Password: ******** Successfully logged into [https://api.appsembler.net]Sunday, March 17, 13 77
  • INITIAL PUSH $ stackato push Would you like to deploy from the current directory ? [Yn]: Would you like to use paasbakeoff as application name ? [Yn]: Detected a Python Application, is this correct ? [Yn]: Framework: python Runtime: <framework-specific default> Application Deployed URL [paasbakeoff.appsembler.net]: Application Url: paasbakeoff.appsembler.net Enter Memory Reservation [128M]:Sunday, March 17, 13 78
  • BIND SERVICES What kind of service ? 1. filesystem 2. memcached 3. mongodb 4. mysql 5. postgresql 6. rabbitmq 7. redis Choose: 5 Specify the name of the service [postgresql-cf691]: Creating Service: OK Binding Service: OK Create another ? [yN]: Would you like to save this configuration? [yN]: y Uploading Application [paasbakeoff]:Sunday, March 17, 13 79
  • AUTO-GENERATED STACKATO.YML FILE name: paasbakeoff instances: 1 framework: type: python mem: 128 Let’s add some other requirements to be installed requirements: requirements: pypm: pypm: - pillow -OR- - pillow - psycopg2 pip: - psycopg2Sunday, March 17, 13 80
  • RUNNING SYNCDB $ stackato update -n $ stackato start $ stackato logs $ stackato run python mywebsite/manage.py syncdb --noinput Creating tables ... ... Creating table django_comments Creating table django_comment_flags Creating default account (username: admin / password: default) ... Creating default Site 127.0.0.1:8000 ...Sunday, March 17, 13 81
  • HANDLING STATIC ASSETS $ stackato run python mywebsite/manage.py collectstatic --noinput ... Copying /app/python/lib/python2.7/site-packages/django/contrib/admin/static/admin/css/rtl.css Copying /app/python/lib/python2.7/site-packages/django/contrib/admin/static/admin/css/ie.css Copying /app/python/lib/python2.7/site-packages/django/contrib/admin/static/admin/css/forms.css Make sure they were copied to the right place framework: type: python home-dir: app processes: web: $STACKATO_UWSGI --static-map /static=$HOME/mywebsite/staticSunday, March 17, 13 82
  • RUN MANAGEMENT COMMANDS hooks: post-staging: - python mywebsite/manage.py syncdb --noinput - python mywebsite/manage.py collectstatic --noinput - python mywebsite/manage.py migrate --noinput Make sure you add South to the requirements requirements: pypm: - pillow - psycopg2 - southSunday, March 17, 13 83
  • PERSISTED FILESYSTEM FOR FILE UPLOADS services: postgresql-cf691: postgresql filesystem-paasbakeoff: filesystem Remember to set the MEDIA_ROOT in settings.py: MEDIA_ROOT = os.environ[STACKATO_FILESYSTEM]Sunday, March 17, 13 84
  • STACKATO.YML FILESunday, March 17, 13 85
  • DIRECTORY LAYOUTSunday, March 17, 13 86
  • OPENSHIFT by Redhat Open source, Auto-scaling, Jenkins builds http://appsembler.com/blog/django-deployment-using-openshift/Sunday, March 17, 13 87
  • Sunday, March 17, 13 88
  • Action hooks for running commands during build, deploy, post-deploy, etc. /data/ dir to store uploaded media files ANATOMY OF AN OPENSHIFT REPO .htaccess to serve up static files application inside of wsgi dir setup.py instead of requirements.txtSunday, March 17, 13 89
  • INSTALL THE RHC CLIENT $ sudo gem install rhc $ rhc setup ... $ rhc domain status 7 tests, 12 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications 100% passed You may need to add the SSH key and start the SSH agent $ ssh-add ~/.ssh/id_rsa $ ssh-agentSunday, March 17, 13 90
  • QUICK ‘N DIRTY INSTRUCTIONS $ rhc app create -a mezzanineopenshift -t python 2.6 $ rhc cartridge add -c mysql-5.1 -a mezzanineopenshift $ cd mezzanineopenshift $ git remote add paasbakeoff git://github.com/appsembler/paasbakeoff.git $ git fetch paasbakeoff $ git merge paasbakeoff/openshiftSunday, March 17, 13 91
  • Action hooks for running commands during build, deploy, post-deploy, etc. /data/ dir to store uploaded media files ANATOMY OF AN OPENSHIFT REPO .htaccess to serve up static files application inside of wsgi dir setup.py instead of requirements.txtSunday, March 17, 13 92
  • /WSGI/APPLICATIONSunday, March 17, 13 93
  • SETUP.PYSunday, March 17, 13 94
  • Sunday, March 17, 13 95
  • STATIC_ROOT AND MEDIA_ROOTSunday, March 17, 13 96
  • /WSGI/STATIC/.HTACCESSSunday, March 17, 13 97
  • .OPENSHIFT/ ACTION_HOOKS/DEPLOYSunday, March 17, 13 98
  • .OPENSHIFT/ ACTION_HOOKS/BUILDSunday, March 17, 13 99
  • CREATE AND BIND THE DATABASE $ rhc cartridge add -c mysql-5.1 -a mezz Password: ****** Adding mysql-5.1 to application mezz Success mysql-5.1 ========= Properties ========== Similar for PostgreSQL $ rhc cartridge add -c postgresql-8.4 -a mezzSunday, March 17, 13 100
  • $ git push GIT PUSH TO DEPLOY Counting objects: 5, done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 498 bytes, done. Total 3 (delta 1), reused 0 (delta 0) remote: restart_on_add=false remote: Waiting for stop to finish remote: Done remote: restart_on_add=false remote: ~/git/mezz.git ~/git/mezz.git remote: ~/git/mezz.git remote: Running .openshift/action_hooks/pre_build remote: setup.py found. Setting up virtualenv remote: New python executable in /var/lib/openshift/x/python-2.6/virtenv/bin/python remote: Installing setuptools............done. remote: Installing pip...............done. ...Sunday, March 17, 13 101
  • MORE RESOURCES • Getting started with Django on OpenShift https://openshift.redhat.com/community/get-started/django • openshift-django-example https://bitbucket.org/mdoglio/openshift-django-sample • Rapid Python and Django app deployment https://openshift.redhat.com/community/blogs/rapid-python-and-django-app- deployment-to-the-cloud-with-a-paasSunday, March 17, 13 102
  • ELASTIC BEANSTALK by Amazon Web Services Leverages EC2 and S3, Auto-scalingSunday, March 17, 13 103
  • Sunday, March 17, 13 104
  • .elasticbeanstalk directory to store config files config file with database settings for RDS wsgi.py fileSunday, March 17, 13 105
  • APP ENGINE by Google Task queues, Memcache, Blobstore Inbound/outbound email, sockets via Channel APISunday, March 17, 13 106
  • Sunday, March 17, 13 107
  • Sunday, March 17, 13 108
  • ANATOMY OF GAE lib directory needed since GAE can’t pip install -r requirements.txt modified settings file: add lib dir to python path and DB settings config file which defines libraries and static files mappingsSunday, March 17, 13 109
  • SETTINGS.PYSunday, March 17, 13 110
  • GAE Dotcloud OpenShiftSunday, March 17, 13 111
  • App Engine Stackato app.yaml stackato.ymlSunday, March 17, 13 112
  • Stackato postinstall OpenShift .openshift/action_hooks/deploySunday, March 17, 13 113
  • Stackato OpenShift Dotcloud Heroku Python 2.7, 3.2 2.6 (2.7) 2.6.5, 2.7.2, 2.7.2 stackato runtimes 3.1.2, 3.2.2 PostgreSQL 9.1 8.4 9.0 9.1.6 MySQL 5.5 5.1 5.1 (Yes, via RDS) Persisted FS Yes Yes Yes (Yes, via S3) Redis Yes, 2.4 No Yes, 2.4.11 (Yes, via addon) MongoDB Yes, 2.0 Yes, 2.2 Yes, 2.2.1 (Yes, via addon) Memcached Yes, 1.4 No Yes (Yes, via addon) RabbitMQ Yes, 2.4 No Yes, 2.8.5 (Yes, via addon) Solr No No Yes, 3.4.0 (Yes, via Websolr) Cron Yes Yes Yes Yes Extensible Yes, apt-get install Yes, DIY cartridge Yes, custom service Yes, buildpacks WebSockets Yes Yes Yes Yes, via Pusher add-onSunday, March 17, 13 114
  • Google App Engine Elastic Beanstalk Python 2.7 2.6 PostgreSQL No No MySQL 5.5 via Cloud SQL Yes, via RDS Persisted FS Yes, via Blob storage Yes, via S3 Redis No No MongoDB No No Memcached Yes Yes, ElasticCache RabbitMQ No (SQS) Solr No (CloudSearch) Cron Yes, via Task Queues No Extensible No Yes, via AMI WebSockets Yes, via Channel API NoSunday, March 17, 13 115
  • WHY NOT PAAS? • Already invested in your own infrastructure. • Need to run on servers outside U.S. • Special requirements not met by PaaS servicesSunday, March 17, 13 116
  • OPENSHIFT PRICINGSunday, March 17, 13 117
  • DOTCLOUD PRICINGSunday, March 17, 13 118
  • HEROKU PRICINGSunday, March 17, 13 119
  • GOOGLE CLOUD SQLSunday, March 17, 13 120
  • THANKS! Questions?Sunday, March 17, 13 121
  • MORE INFO • Wrap-up from PaaS bake-off http://appsembler.com/blog/wrap-up-from-paas-bake-off/ • Django deployment using PaaS http://appsembler.com/blog/django-deployment-using-paas/ • django-deployer https://github.com/natea/django-deployer • paasbakeoff - code examples https://github.com/appsembler/paasbakeoff/Sunday, March 17, 13 122