Sorry for the slow reply. Picking up after a couple of weeks of overseas travel 
and sickness.

On 10/09/2014, at 12:31 PM, lee <[email protected]> wrote:

> Hello,
> I am deploying a new Django instance on a server running Apache and mod_wsgi 
> - working off of a previous developers setup. I am new to this and while I 
> got the new site up and running by copying what the previous person did, I am 
> worried that he may not have things set up correctly. I have read through the 
> mod_wsgi documentation and Django deployment pages but I would like to ask 
> those with more expertise if my setup is safe and efficient.
> 
> My Django project is running in var/www  - is this safe?

No it isn't.

The reason this is a problem is that DocumentRoot is set to /var/www. This 
means that web server if it can be accessed in a way that the default action of 
serving up static files from the DocumentRoot directory can be triggered will 
result in someone being able to download the source code for your Django 
project. This includes being able to download your Django settings file which 
could contain database passwords or secret session keys for cookies.

So with the configuration you can given below, I can likely download your 
Django settings module as:

   http://site-name:8080/DjangoProject/DjangoProject/settings.py

> My settings are in /etc/apache2/sites-available/default and my Django project 
> settings are in a VirtualHost. Is this the correct place for these settings?

I have of late come to hate the default layout for Apache configuration files 
as they exist on Linux systems. They force you into this model which is setup 
more with the thought that you are going to host multiple distinct sites on the 
same web server. This is the exception rather than the rule, with most users 
likely only running a single site on a server, or at least under a single name 
based virtual host. The default layout therefore perhaps pushes people to doing 
things in a more complicated way than they need to.

Anyway, to answer whether for the Linux layout for Apache configuration that 
file is the best place to add things, it really depends on your requirements 
and whether you are in fact hosting more than one name based virtual host and 
also whether you have the server listening on multiple ports.

For example, your example has both port 8080 and port 80 virtual hosts. Why is 
that the case? What is the requirement around being able to listen on multiple 
ports?

> I hope to eventually get the old instance of Django running on a suburl with 
> the documentation here: 
> http://blog.dscpl.com.au/2012/10/requests-running-in-wrong-django.html
> 
> Thank you, Lee
> 
> My project is located on /var/www/DjangoProject and static files have been 
> collected to /var/www/DjangoProject/static
> 
> /var/www/DjangoProject/wsgi.py
> import os
> import sys
> sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 
> "../../")))
> sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 
> "../")))
> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "DjangoProject.settings")
> from django.core.wsgi import get_wsgi_application
> application = get_wsgi_application()

The changes to sys.path here seem to perhaps be duplicating what is done in the 
Apache configuration.

> ---/etc/apache2/apache2.conf Other settings above this line
> WSGIPythonPath 
> /var/www/DjangoProject/DjangoProject:/var/www/DjangoProject/env/lib/python2.6/site-packages
> 
> 
> 
> --/etc/apache2/httpd.conf No other settings besides this line
> WSGIPythonPath 
> /var/www/DjangoProject:/var/www/DjangoProject/DjangoProject:/var/www/DjangoProject/env/lib/python2.6/site-packages

What mod_wsgi version are you using?

There are better ways of setting up Python module search path so long as you 
aren't stuck with an older mod_wsgi version.

I blogged about this recently in:

  http://blog.dscpl.com.au/2014/09/python-module-search-path-and-modwsgi.html

> --/etc/apache2/sites-available/default
> NameVirtualHost *:8080
> <VirtualHost *:8080>
>         ServerAdmin webmaster@localhost
>         DocumentRoot /var/www
>         <Directory />
>                 Options FollowSymLinks
>                 AllowOverride None
>         </Directory>
>         <Directory /var/www/>
>                 Options Indexes FollowSymLinks MultiViews
>                 AllowOverride None
>                 Order allow,deny
>                 allow from all
>         </Directory>
> 
>         ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
>         <Directory "/usr/lib/cgi-bin">
>                 AllowOverride None
>                 Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
>                 Order allow,deny
>                 Allow from all
>         </Directory>
> 
>         ErrorLog ${APACHE_LOG_DIR}/error.log
>         LogLevel warn
>         CustomLog ${APACHE_LOG_DIR}/access.log combined
> </VirtualHost>

What is the port 8080 virtual host even being used for? Is it required?

> <VirtualHost *:80>
> ##############################
> ## DjangoProject WSGI         ##
> ##############################
> 
> ServerName DjangoProject.mit.edu
> Alias /favicon.ico /var/www/DjangoProject/DjangoProject/static/favicon.ico
> AliasMatch ^/([^/]*\.css) /var/www/DjangoProject/MyApp/static/MyApp/css/$1
> 
> Alias /media/  /var/www/DjangoProject/DjangoProject/media/
> Alias /static/ /var/www/DjangoProject/MyApp/static/

There are possibly better ways of doing this.

I blogged about this recently in:

  http://blog.dscpl.com.au/2014/09/hosting-php-web-applications-in.html

The target of that post was integrating with a PHP application, but the 
technique applies to normal static files as well.

> <Directory /var/www/DjangoProject/MyApp/static>
> Order deny,allow
> Allow from all
> <IfModule mod_expires.c>
>   ExpiresActive On
>   ExpiresDefault "access plus 1 seconds"
>   ExpiresByType text/html "access plus 1 seconds"
>   ExpiresByType image/gif "access plus 10080 minutes"
>   ExpiresByType image/jpeg "access plus 10080 minutes"
>   ExpiresByType image/png "access plus 10080 minutes"
>   ExpiresByType text/css "access plus 60 minutes"
>   ExpiresByType text/javascript "access plus 60 minutes"
>   ExpiresByType application/x-javascript "access plus 60 minutes"
>   ExpiresByType text/xml "access plus 60 minutes"
> ExpiresByType text/xml "access plus 60 minutes"
> </IfModule>
> </Directory>
> 
> <Directory /var/www/DjangoProject/DjangoProject/media>
> Order deny,allow
> Allow from all
> <IfModule mod_expires.c>
>   ExpiresActive On
>   ExpiresDefault "access plus 1 seconds"
>   ExpiresByType text/html "access plus 1 seconds"
>   ExpiresByType image/gif "access plus 10080 minutes"
>   ExpiresByType image/jpeg "access plus 10080 minutes"
>   ExpiresByType image/png "access plus 10080 minutes"
>   ExpiresByType text/css "access plus 60 minutes"
>   ExpiresByType text/javascript "access plus 60 minutes"
>   ExpiresByType application/x-javascript "access plus 60 minutes"
>   ExpiresByType text/xml "access plus 60 minutes"
> </IfModule>
> </Directory>
> 
> WSGIDaemonProcess DjangoProject.example.com processes=2 threads=15 
> display-name=%{GROUP}
>     WSGIProcessGroup DjangoProject.example.com
> 
> WSGIScriptAlias /MyApp /var/www/DjangoProject/DjangoProject/wsgi.py
> WSGIScriptAlias / /var/www/DjangoProject/DjangoProject/wsgi.py

Why is the Django application being mounted at both the root of the site and a 
sub URL?

This doesn't look right and will provide multiple URLs to the same resource.

> <Directory /var/www/DjangoProject/DjangoProject>
> <Files wsgi.py>
> Order deny,allow
> Allow from all
> </Files>
> <IfModule mod_expires.c>
>   ExpiresActive On
> ExpiresDefault "access plus 1 seconds"
>   ExpiresByType text/html "access plus 1 seconds"
>   ExpiresByType image/gif "access plus 10080 minutes"
>   ExpiresByType image/jpeg "access plus 10080 minutes"
>   ExpiresByType image/png "access plus 10080 minutes"
>   ExpiresByType text/css "access plus 60 minutes"
>   ExpiresByType text/javascript "access plus 60 minutes"
>   ExpiresByType application/x-javascript "access plus 60 minutes"
>   ExpiresByType text/xml "access plus 60 minutes"
> </IfModule>
> </Directory>
> 
> AddType audio/mpeg .mp1 .mp2 .mp3 .mpg .mpeg
> </VirtualHost>

Overall the main concern is where you placed the Django application code.

Other things can likely be done in better/cleaner ways these days, and I didn't 
mention all of those even. If you are stuck on an older mod_wsgi version 
because you are using some older LTS variant of a Linux system and will only 
use a binary packaged mod_wsgi provided by the distribution even if it has bugs 
then your choices are limited.

Independent of mod_wsgi you can likely also avoid duplication of all the 
mod_expires configuration. That configuration does worry me though a bit 
because it is applied so liberally. Seems to me that it would cause too 
aggressive caching in browser clients or caching proxies making it hard for you 
to change the returned content quickly if a dynamic site.

Graham

-- 
You received this message because you are subscribed to the Google Groups 
"modwsgi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/modwsgi.
For more options, visit https://groups.google.com/d/optout.

Reply via email to