Yesterday I announced the alpha release of django-deployer, and today I’d like to show how to use it for deploying a Django app to Google App Engine (GAE).
Here is a 5 min demonstration video showing how it works. (The video is best viewed in Chrome or Safari – there is currently a bug in the player when used with Firefox)
What makes Google App Engine different?
GAE is a bit different than the other PaaS providers in the following ways:
1. You cannot run pip install -r requirements.txt on the server, so you have to run it locally and then push up all the packages to GAE. Thankfully, there is a script provided by django-deployer that takes care of this for you.
2. GAE already provides Django 1.4, PIL and a bunch of other packages, so you should use the versions that GAE provides, rather than pushing up your own. django-deployer prepares and uploads the packages that are in your project that are not already provided by GAE. (Note: any unsupported package that requires C extensions is not going to work on GAE, since you can’t compile code on the server)
3. GAE provides a MySQL-compatible service called Cloud SQL. You need to create a new Cloud SQL instance and grant your GAE app as an authorized application. Once you’ve created an instance, it can contain unlimited databases up to the disk allowance (on the free tier, this is 512MB). The script provided by django-deployer will prompt you for the instance name, and then proceed to create the database for you using google_sql.py (provided by the GAE Python SDK).
4. Any Django management commands (syncdb, migrate) have to be run locally against the remote Cloud SQL database. Similarly, collectstatic also has to be run locally and then push the resulting ‘static’ dir up to the server. Again, django-deployer provides a wrapper script called manage.sh, that can handle these tasks for you.
How do I get started with Django on GAE?
You just head on over to sign up for an App Engine account using any Google account. Once you’re logged in, create a new app by clicking on Create application. We’re going to call our application “djangodeployermezz“:
Turn on Cloud SQL
Then you need to go over to the Google APIs console, which is a bit confusing because it’s a totally different interface than the App Engine UI. Hopefully in the future, Google will provide a more seamless unified experience when using their PaaS.
You’ll want to click on the Services menu item and turn on Cloud SQL.
Click on the pricing link to see how much a Cloud SQL instance costs. Google is offering an introductory Cloud SQL trial instance (tier D0). You still need to enable billing for your project, but Google will not charge you for resources consumed by your tier D0 Cloud SQL instances.
You are allowed only one tier D0 Google Cloud SQL instance in total, no matter how many Google APIs projects you have. If your tier D0 instance reaches the storage limit, you will not be able to add more data to your database, but you will be able to access your instance to delete data. You can track the amount of storage used in the APIs Console. If you require more storage or RAM, you can change your trial instance to one of the paid tiers at any point through the console.
Create a new database instance
Once you’ve turned on Cloud SQL and enabled billing, then you need to create a new instance by clicking on the New Instance… button. We’re going to make a new instance called “djangomezzanine:djangomezzdb“. Note: be sure to add your application as an authorized application to interface with this database instance.
Using django-deployer to prepare your Django project for deployment to GAE
Now that you’ve got the application and database instance created, you’re all ready to use django-deployer to finish out the remaining steps. As you saw in the video above, there are just a few steps to follow:
$ pip install django-deployer $ git checkout -b appengine # optional step to make a separate branch $ deployer-init # this creates the fabfile.py $ fab setup We need to ask a few questions before we can deploy your Django app * What is your Django project directory name? (This usually contains your settings.py and a urls.py) mywebsite * What is your Django settings module? [mywebsite.settings] * Where is your requirements.txt file? [requirements.txt] mywebsite/requirements/project.txt * What version of Python does your app need? [Python2.7] * What is your STATIC_URL? [/static/] * What is your MEDIA_URL? [/media/] * Which provider would you like to deploy to (dotcloud, openshift, appengine)? appengine * What's your Google App Engine application ID (see https://appengine.google.com/)? djangodeployermezz * What's the full instance ID of your Cloud SQL instance (should be in format "projectid:instanceid" found at https://code.google.com/apis/console/)? djangomezzanine:djangomezzdb * What's your database name? appenginedemo * Where is your Google App Engine SDK location? [/usr/local/google_appengine] Creating a deploy.yml with your app's deploy info... Created /Users/nateaune/Dropbox/code/paasbakeoff/deploy.yml
Then run fab deploy create the virtualenv with all the packages and deploy:
$ fab deploy ...
Next create the database on Cloud SQL using the convenience command cloudcreatedb:
$ sh manage.sh cloudcreatedb Google SQL Client Type "help" or "?" for help. Connecting to Google SQL database "djangomezzanine:djangomezzdb" on host None. Using readline for history management. Loading history file "/Users/nateaune/.googlesql/djangomezzanine:djangomezzdb.hist" sql> Execution time: 0.212 seconds 1 row sql> Bye.
Next syncdb the database on Cloud SQL using the convenience command cloudsyncdb:
$ sh manage.sh cloudsyncdb ...
Everything is set up now, you can run other commands that will execute on your remotely deployed app, such as:
$ sh manage.sh dbshell
You can now go to http://djangodeployermezz.appspot.com to see the site running!
Testing and contributing
django-deployer is an open source project and the code is available on Github. Please test it out and give me feedback. Your contributions (docs, fixes and features) are most welcome! A big thanks to Colin Su who already contributed lots of code to get django-deployer working with Google App Engine.