Recommended place for a Django project to live on Linux

File Hierarchy System

@Andy Hayden really states where not to place ones code. The File Hierarchy System (FHS) implicates the following structure; PATH maps to PACKAGE or PROVIDER (It is recommended that parties providing multiple packages should use PROVIDER/PACKAGE) :

/etc/opt/PATH  # FHS location for /opt configuration files
/opt/PATH      # FHS location for PROVIDER or PACKAGE name
/var/opt/PATH  # FHS location for /opt variable storage 

The FHS expects /opt/PATH to contain all the material necessary for the successful execution of ones package so it seems prudent to setup the following symbolic links

  • /etc/opt/PATH to /opt/PATH/etc
  • /var/opt/PATH to /opt/PATH/var

This provides a good basis but Django projects have extraneous requirements that the above structure does not fully meet.

Static Files

Static files are deployed when one runs python manage.py collectstatic to the STATIC_ROOT which should point to the web server root for static delivery, usually /var/www/PATH.

One could link /var/www/PATH symbolically to /opt/PATH/static but this is typically a bad idea; Consider the case that you have a misconfigured server and a user goes to www.domain.tld/../ and copies your work.

Settings

If you created your project with django-admin create-project WEBSITE the you will typically have a setup.py file under the WEBSITE folder.

PROJECT/
    WEBSITE/
         setup.py
         ...

If you converted this settings module into a package, or you used some wrapper around django-admin e.g. django-cms-create etc.

PROJECT/
    WEBSITE/
         settings/
             __init__.py  # from .settings import *
             settings.py
         ...

You might symlink /etc/opt/PATH to /opt/PATH/WEBSITE/settings instead of /opt/PATH/etc as described above. I can't think of a practical reason for doing so though... YMMV.

Media

Media, typically provided by ones websites users, are placed into MEDIA_ROOT. It seems prudent to map /var/opt/PATH to /opt/PATH/media in this case.

Virtual Environments

/opt/PATH/env seems the most logical location. /var/env/PATH also seems sensible but is probably better suited as a symbolic link to /opt/PATH/env.

Since a virtual environment is neither an application nor a library the locations /opt/bin and /opt/libs would not do for this. /env/ or /pyvenv/ does not conform to the FHS.

Whiskey

If you're using mod_wsgi with Apache the an invocation similar to python manage.py runmodwsgi --server-root /etc/opt/PATH --setup-only is probably preferable since it places the Apache control commands into the FHS compliant locations, granted they are more cumbersome to invoke in this case.

Home

To my understanding /home was traditionally used by PHP developers when they were hosting multiple sites upon the same server. If you're using Django you're probably serving your site from a dedicated machine and this structure looses a bit of favour in this case... YMMV.


In the Django tutorial it states:

Where should this code live?
If your background is in PHP, you're probably used to putting code under the Web server's document root (in a place such as /var/www). With Django, you don't do that. It's not a good idea to put any of this Python code within your Web server's document root, because it risks the possibility that people may be able to view your code over the Web. That's not good for security.

Put your code in some directory outside of the document root, such as /home/mycode.