Managing Django Projects on Your Server with Style
This article is outdated, you’ll find an updated article here.
A friend is in the process of setting up a new slice at everbody’s favorite VPS provider Slicehost and asked for some advice. I use MySQL, Nginx & Apache/mod_wsgi on Ubuntu to serve Django. I think Slicehost’s Articles are awesome and a great place to get help you get everything installed and running, so for this article, I’ll focus on some personal preferences regarding directory structure and repo management.
One of the biggest difficulties I’ve had to tackle lately is the rapid progress of Django. I have a number of client sites hosted on my slice and have had to freeze them at certain times when backwards incompatible changes come along. My original approach made this really messy, because I only accounted for having one copy of any given third party repo, symlinked from /usr/local/src to my Python site-packages directory. My new approach takes advantage of being able to set your PYTHONPATH at runtime.
My directory structure looks like this:
|-django |--projects |---domain1.com |---domain2.com |---domain3.com
Each site has the following structure:
|-domain1.com |--apache |---django.wsgi |--django |--domain1_project |---__init__.py |---app1 |---app2 |---manage.py |---settings.py |---static |---templates |---urls.py |--third_party_repo1 |--third_party_repo2
Just drop domain1.com in your PYTHONPATH and you’re good to go. I usually start with django and the third party repos as symlinks to a current checkout of the code in /usr/local/src. When the project is completed or if the linked code passes us by, I simply replace the symlink with an actual copy of the repo. This gives me a nice compartmentalized folder of the project that would be easy to move if needed. I can also update my repos in /usr/local/src without worrying about which project might break from the new code.
Have a better way to do things? Leave a comment and let me know. Thanks for reading and tune in next week to really geek out with Nginx & Apache/mod_wsgi configuration files.
Comments
Got something to say?
Our Products
Categories
- accessiblity
- code
- company news
- django
- gondola
- open source
- portfolio
- presentation
- pro tip
- review
- screencast
- seo
- software
- subversion
- trailmapping
- wordpress
Archives
- July, 2010
- June, 2010
- May, 2010
- April, 2010
- February, 2010
- December, 2009
- November, 2009
- October, 2009
Elsewhere
What we’ve been up to online
-
Just launched a Flask/App Engine mini-site we've been tinkering on http://emailed-me.appspot.com/
Pete, 14 hours, 49 minutes ago -
created repository Emailed-Me-
Pete, 14 hours, 57 minutes ago -
Our first iPhone development project hit the App Store last week and is already over 1k users! Check them out @takemyspot #iphone #geodjango
Pete, 3 weeks ago -
Love the new sites! RT @welikesmall: We just launched two new sites. http://post.ly/mGoq
Pete, 3 weeks, 1 day ago -
Pro tip: Using pip safely for automated deployment (no more pesky prompts) http://bit.ly/b5zsPa
Pete, 4 weeks, 1 day ago -
commented on justquick/django-mailfriend
Pete, 1 month ago -
RT @unbracketed: Excited to have @mitsuhiko joining us for some work this summer :)
Pete, 1 month ago -
New blog post: managing supervisord with upstart http://bit.ly/db3p5N
Pete, 1 month ago -
Troubleshooting OpenID is just like user/password. Except you have 5 of them and and you don't know which one is failing, and 3 login pages
Pete, 1 month, 1 week ago -
This gets very interesting around 42 min. Using javascript to snoop inside firewalled networks http://bit.ly/aNVPc5
Pete, 1 month, 2 weeks ago -
The final tally is in. 8 Lincoln Loopers attending DjangoCon. 3 US, 4 EU, and 1 NZ. Looking forward to it!
Pete, 1 month, 2 weeks ago -
Twitter / Dustin Curtis: I'm flying to Madrid tomor ...
Dustin Curtis travels to Berlin, Bangkok & Madrid in exchange for design services as the result of a late night tweet.
Pete, 1 month, 2 weeks ago -
created branch ubuntu-8.04 at lincolnloop/fab-pave
Pete, 1 month, 3 weeks ago -
created repository fab-pave
Pete, 1 month, 3 weeks ago -
pushed to master at lincolnloop/django-mailfriend
Pete, 1 month, 3 weeks ago


That’s typically the point where you want to use virtualenv :)
http://pypi.python.org/pypi/virtualenv
And for mod_wsgi integration: http://code.google.com/p/modwsgi/wiki/VirtualEnvironments
One feature of virtualenv I always like to exploit: easy_install in a virtualenv looks into your PYTHONPATH to find already installed packages in it and just links to them (so no duplication). Using the multiversion flag for easy_install you could even choose between different version and share them between projects.
I wouldn’t mix python modules and non modules on the Python path. And I wouldn’t put my apps into a project module
/web/domain1.com /manage.py /static /templates /python/django /python/project1 /python/project1/settings.py /python/project1/urls.py /python/app1 /python/app2 /python/third_party_repo1 /python/third_party_repo2Put /web/domain1.com/python/ on the Python path and modify manage.py to import project1.settings instead of just settings.
I’m also a fan of virtualenv and I use Doug Hellman’s [http://www.doughellmann.com/projects/virtualenvwrapper/ virtualenvwrapper]. I’m still experimenting with finding the killer combo (for my tastes) for managing and versioning django apps and projects. I can envision a lot more discussion about distribution and deployment in the near future as projects like Pinax gain maturity and devs/admins are finding themselves dealing with large numbers of dependencies. I don’t know about you but I get pretty damned frustrated when I spend time tracking down a weird “bug” to discover it was the result of an out-of-date package somewhere higher on the path list.
I’m also excited about [http://www.blueskyonmars.com/projects/paver/index.html Paver] since it integrates so tightly with the existing tools (distutils and setuptools) plus has support for virtualenv. It looks like it will make the creation of virtualenv bootstrap scripts a little more painless.
ne of the biggest difficulties I’ve had to tackle lately is the rapid progress of Django. I have a number of client sites hosted on my slice and have had to freeze them at certain times when backwards incompatible changes come along. My original approach made this really messy, because I only accounted for having one copy of any given third party repo, symlinked from /usr/local/src to my Python site-packages directory. My new approach takes advantage of being able to set your PYTHONPATH at runtime.