Click here to code!

Deploying a Django App to PythonAnywhere

Posted by Bob on Sun 23 July 2017 in Django • 3 min read

After Julian's great article on deploying a Flask app to Heroku, let's look at how we can deploy a Django app to PythonAnywhere (PA). In this article I share a few things I learned deployed our first Django app.

Good docs + nice interface

One of my first tries was the API / helper script, but unfortunately it did not make it to the end. Yet the Deploying an existing Django project on PythonAnywhere using the Manual option worked great for me:

pa choose manual option

Our first Django app is online:

pa site online

22nd of Jan 2018 update: we ended up hosting this on Heroku.

I really like the infrastructure of browser consoles and intuitive GUIs. Also config files like wsgi.py were clearly commented so setting it up was quick and almost painless.

Git + venv

Important steps of the deployment steps are git pulling your code and creating a virtual env, this worked very well.

pa supports git and venv

After this step I could just do a pip install -r requirements.txt to pull down Django and feedparser.

Now when I make changes to my app I can just do a git pull in the repo dir and restart the app in the browser. It just takes seconds :)

Scheduled tasks ... OK time to upgrade

Our app pulls in new articles from Planet Python as explained here. Planet was not on PA's whitelist and I wanted this task to be run every hour (instead of once a day). At this point I had to upgrade from Free to the Hacker tier. This has additional benefits, check out pricing.

Similar to other providers, at PA you pay for what you need/ consume. You can add apps on the fly. I'd hoped to get a small PostgreSQL DB with Hacker's tier, but that requires further upgrading ...

The interface to set up a scheduled task is nice and easy:

pa scheduled tasks

Notice that I activate the venv in the command because it needs to load env variables.

Less obvious

  • I had to add our PA domain pybites.pythonanywhere.com to ALLOWED_HOSTS (Django settings).

  • Django encapsulation. As detailed in this excellent article you want to hide your SECRET_KEY, DB credentials, etc from version control. I also followed the settings best practices described in the article. So make sure you do some work upfront. Make sure you check Django's checklist.

  • Env variables. You need to set them in 2 places. As the help doc admits this is not ideal. At the virtual env level it only seemed to work adding them to the activate script, not postactivate.

  • Handling static files was a bit of a pain. I ended up using collectstatic to get them all in one place:

    (venv) 12:27 ~/pybites-django/pybites (master)$ python manage.py collectstatic
    62 static files copied to ...
    

    And in the web GUI config I set:

    pa static files solution

    Not sure if this is the best solution because I need to rerun this when static files change ...

Multiple apps

As the Hacker tier gives me one app I made this container project / repo to host multiple apps in. It's a nice exercise in Django's architecture of one project -> multiple apps that can be moved around. As said, PA's pricing structure is pretty flexible, so we can always add apps if necessary.

Conclusion

So far I am happy with PA. In spite of some minor issues it is easy to deploy a Django app and it performs well. The help docs are well written.

They are also quite proactive: there was a file server issue last weekend which they updated via Twitter. And they just posted a full post mortem!

It was easy to reach out to support and I got a quick response. I also like the short email tutorial updates.

I will compare with Heroku pricing for PostgreSQL because adding one bumps the monthly price up from 5 to 12 USD (at this time of writing). Or I go with their default MySQL which is free.


Keep Calm and Code in Python!

-- Bob


See an error in this post? Please submit a pull request on Github.


Join our community and grab our Become a Better Python Developer cheat sheet. Learn Python. Receive bonus material. Challenge yourself!