This presentation was given at the Boston Django meetup on November 16, and surveyed several leading PaaS providers including Stackato, Dotcloud, OpenShift and Heroku.
For each PaaS provider, I documented the steps necessary to deploy Mezzanine, a popular Django-based CMS and blogging platform.
At the end of the presentation, I do a wrap-up of the different providers and provide a comparison matrix showing which providers have which features. This matrix is likely to go out-of-date quickly because these providers are adding new features all the time.
1. Django
deployment revisited
Nate Aune, @natea
Appsembler & Jazkarta
November 15, 2012
Django Boston Users Group
2. A brief history of /me
• Jazkarta (2004-Current) AWS)
first taste of cloud platforms (GAE,
• DjangoZoom -(2010-2011) it be!?”
built my own PaaS “how hard can
• Appsembler (2012-Current) SaaS apps
leveraging PaaS, make it easy to launch
3. What’s on the menu
• Where are you deploying Django apps today?
• What is a PaaS?
• Why you might want to use a PaaS?
• What are the different PaaS players?
• How do they compare?
4. Where are you
deploying Django 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)
5. What is a PaaS?
Platform-as-a-service enables developers to create
innovative applications without operational overhead
around configuration, deployment and management.
6. Layers of infrastructure
Source: EngineYard “PaaS - State of the Market Survey” May 2012 - http://venturebeat.com/2012/07/05/engine-yard-paas-infographic/
7. Source: EngineYard “PaaS - State of the Market Survey” May 2012 - http://venturebeat.com/2012/07/05/engine-yard-paas-infographic/
8. Source: EngineYard “PaaS - State of the Market Survey” May 2012 - http://venturebeat.com/2012/07/05/engine-yard-paas-infographic/
9. Source: EngineYard “PaaS - State of the Market Survey” May 2012 - http://venturebeat.com/2012/07/05/engine-yard-paas-infographic/
10. 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/
11. Efficient, Elastic, Secure
• Lots of applications co-located on a few servers
• Drastically reduces resources
• Add/remove servers depending on load
• All secured using SELinux or LXC
12. Let them do
the boring stuff
• Let the PaaS provider do the boring stuff
• Patches and updates
• Migrating applications
• Backups / snapshots
• Configuring everything (web servers, load
balancers, modules, databases)
13. Who are the players?
• CloudFoundry • Heroku
(open source by VMWare) (now Salesforce)
• OpenShift
(Redhat’s open source PaaS)
• AppFog • Dotcloud • App Engine
(Google)
• Stackato
(ActiveState)
• Gondor (Python only) • Elastic Beanstalk
(Amazon)
• Azure
(Microsoft)
14. Who are the players?
We’ll look at these ones tonight.
• CloudFoundry • Heroku • OpenShift
(open source by VMWare) (now Salesforce) (Redhat’s open source PaaS)
• AppFog • Dotcloud • App Engine (Google)
• Stackato • Gondor
(ActiveState) • Elastic Beanstalk
(Python only)
(Amazon)
• Azure (Microsoft)
15. Stackato
by ActiveState
Python 3, Run anywhere, New Relic integration
http://appsembler.com/blog/django-deployment-using-stackato/
21. 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 the
configuration (optional)
26. 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]
27. 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]:
Creating Application [paasbakeoff]: OK
Create services to bind to 'paasbakeoff' ? [yN]: y
28. 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]:
Checking for bad links: 29 OK
Copying to temp space: 28 OK
Checking for available resources: 44022 OK
Packing application: OK
Uploading (20K): 100% OK
Push Status: OK
Staging Application [paasbakeoff]:
29. Auto-generated
stackato.yml file
name: paasbakeoff
instances: 1
framework:
type: python
mem: 128
services:
postgresql-cf691: postgresql
Let’s add some other requirements to be installed
requirements: requirements:
pypm: pypm:
- pillow -OR- - pillow
- psycopg2 pip:
- psycopg2
31. 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'
554 static files copied.
Make sure they were copied to the right place
framework:
type: python
home-dir: app
processes:
web: $STACKATO_UWSGI --static-map /static=$HOME/mywebsite/static
32. Run management
commands automatically
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
- south
33. 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']
40. 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.txt
48. 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
==========
Connection URL = mysql://127.12.26.129:3306/
Database Name = mezz
Password = **********
Username = admin
Similar for PostgreSQL
$ rhc cartridge add -c postgresql-8.4 -a mezz
49. Git push to deploy
$ git push
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.
...
remote: Running .openshift/action_hooks/deploy
remote: hot_deploy_added=false
remote: MySQL already running
remote: Done
remote: Running .openshift/action_hooks/post_deploy
To ssh://0e94a6186e07430f8d9b989fdf702362@mezz-natea.rhcloud.com/~/git/mezz.git/
03605bf..e05607c master -> master
50. 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-paas
54. 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.
$ dotcloud check
==> Checking the authentication status
==> Client is authenticated as natea
55. 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 #0
14:18:08: [www.0] Installation successful for service (www) instance #0
14:18:08: --> Application (mezz) fully installed
==> Application is live at http://mezz-natea.dotcloud.com
$ dotcloud open
==> Opening service "www" in a browser: http://mezz-natea.dotcloud.com
56. 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 uWSGI
67. 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.pub
68. 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: available
Connections: 0
PG Version: 9.1.6
Created: 2012-11-15 20:59 UTC
Data Size: 5.9 MB
Tables: 0
Rows: 0/10000 (In compliance)
Fork/Follow: Unavailable
69. 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/d2b3c9ichbauv0
HEROKU_POSTGRESQL_GREEN_URL: postgres://x:y@z.com:5432/d2b3c9ichbauv0
70. Add to settings.py
Set the RACK_ENV environment variable to production
$ heroku config:set RACK_ENV=production
71. Use S3 for serving
static and media files
And Sendgrid for sending emails
73. $ git push heroku master
Counting objects: 8, done.
Delta compression using up to 2 threads.
Deploy with git push
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 files
0 static files copied.
-----> Discovering process types
Procfile declares types -> (none)
Default types for Python/Django -> web
-----> Compiled slug size: 9.4MB
-----> Launching... done, v7
http://djangosample.herokuapp.com deployed to Heroku
To git@heroku.com:djangosample.git
af73905..3046deb master -> master
74. 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/
75. 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-on
76. Other resources
• 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/
Editor's Notes
\n
I started Jazkarta, a web consulting firm in 2004. AWS for our own website, before EBS. Connexions @ Rice University. GAE project for Aprigo, now known as ClockLock. Founded DZ to provide GAE-like capabilities to Django devs. Appsembler helps developers SaaSify their apps. Tried lots of PaaS providers and hope to share some of that knowledge w/ you tonight.\n
\n
How many are ... ? Who still hasn&#x2019;t deployed Django onto a server?\n
\n
\n
\n
\n
\n
Lucas argues that over the years, the costs of hosting apps has exponentially decreased, while the productivity has exponentially increased.\n
\n
\n
Two open source options (CloudFoundry and OpenShift). CloudFoundry given birth to AppFog/Stackato. Big companies moved into this space within the last couple years (Redhat, VMWare, Salesforce through acquisitions). Amazon, Microsoft and Google built their own cloud platforms.\n
Two open source options (CloudFoundry and OpenShift). CloudFoundry given birth to AppFog/Stackato. Big companies moved into this space within the last couple years (Redhat, VMWare, Salesforce through acquisitions). Amazon, Microsoft and Google built their own cloud platforms.\n