django SSL apache configuration - django

I have a django application and I would like to apply SSL to the admin pages. Since the admin page are the only pages needing SSL I want to do this using the apache configuration files and not using SSLMiddleware. My (partial) apache configuration files look like this:
<VirtualHost *:80>
.
.
DocumentRoot /home/www/sites_django/wmssite
.
<Directory "/home/www/sites_django/wmssite">
.
</Directory>
<Location "/admin">
RewriteEngine On
RewriteRule ^/(.*) https://www.whitemoorstudio.pvm/admin [L,R=301]
</Location>
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile "/usr/local/etc/apache22/www_whitemoorstudio_pvm.crt"
SSLCertificateKeyFile "/usr/local/etc/apache22/www_whitemoorstudio_pvm.key"
.
.
</VirtualHost>
The TLD .pvm is a local TLD I just use for testing on my internal network.
I have set up a self-sgned certificate and it works, well.... sort of. The strange thing is that for some reason when rewriting to https it cannot find the media files in the /media directory, no images, no css, no js. The apache error log tells me it is looking in the directory /usr/local/www/apache22/data/media:
[Sat Nov 06 20:45:18 2010] [error] [client 192.168.1.134] File does not exist: /usr/local/www/apache22/data/media, referer: https://www.whitemoorstudio.pvm/admin/
When I don't rewrite to https the admin media directory /usr/local/www/apache22/media. This directory media is a logical link:
media -> /usr/local/lib/python2.5/site-packages/django/contrib/admin/media
I have no idea why without SSL it is looking in:
/usr/local/www/apache22/media
and with SSL in:
/usr/local/www/apache22/data/media
This last directory doesn't exist!!!
Anyone any idea?

Problem already solved. When adding the stuff in the VirtualHost *:443 container
I had forgotten to specify the DocumentRoot directive so it was as specified in the main httpd.conf.
It went well in the VirtualHost *:80 container because in that section I had specified DocumentRoot.
In httpd.conf it is specified as:
DocumentRoot "/usr/local/www/apache22/data"

Related

Reconfiguring Apache to serve website root from new php source and specific sub-urls from old django site

How do I make a django website (in a apache/mod_wsgi/django setup) which is configured to serve from the root url, serve only for specific sub-url but not the root url? The root url shall be served from a new source (php). All this with a minimum of reconfiguration.
Currently the condensed virtualhost config looks like this
<VirtualHost *:80>
ServerAdmin admin#mysite.com
ServerName mysite.com
# mappings to django
WSGIScriptAlias / /opt/mysite/mysite.wsgi
<Directory /opt/mysite>
Order allow,deny
Allow from all
</Directory>
# mappings to wordpress
Alias /wp/ /var/www/mysiteWP/
<Location "/var/www/mysiteWP/">
Options -Indexes
</Location>
Alias /show/ /var/www/mysiteWP/
Alias /collection/ /var/www/mysiteWP/
</VirtualHost>
As you can see django and php(wordpress) are running side by side. Wordpress just serving mysite.com/show/ and mysite.com/collection/. Django is serving the rest, including the root url mysite.com. This configuration works.
What I want to do now, is, I want to make wordpress serve everything except some specific urls which should be served by django. E.g. django should just serve mysite.com/shop/ and mysite.com/news/ but nothing else, also excluding mysite.com.
How would I do this with a minimum of reconfiguration?
Thanks for your answers and hints.
Props to Graham Dumpleton. He answered another question of the exact same kind in this Q&A: Django (wsgi) and Wordpress coexisting in Apache virtualhost.
In short, after configuring Apache so the root url is served from php, the solution to route specific sub urls to django, but making it think its mount point is still the root, is WSGIScriptAliasMatch.
To this (example)problem the simple addition to the apache virtual host config was this:
WSGIScriptAliasMatch ^(/(shop|news)) /opt/mysite/mysite.wsgi$1
The whole virtual host config for this example is:
<VirtualHost *:80>
ServerAdmin admin#mysite.com
ServerName mysite.com
# mappings to django
WSGIScriptAliasMatch ^(/(shop|news)) /opt/mysite/mysite.wsgi$1
<Directory /opt/mysite>
Order allow,deny
Allow from all
</Directory>
# mappings to wordpress
DocumentRoot /var/www/mysiteWP/
<Location "/var/www/mysiteWP/">
Options -Indexes
</Location>
</VirtualHost>

403 forbidden when Django folder is located in /root

I'm trying to deploy my local Django site on my Ubuntu 12.04 server. I followed a tutorial, and everything seems to work fine, except Apache won't allow me to store my Django project under /root. More specifically, I get a 403 Forbidden when trying to access my site.
I suspect I need to configure my virtual host in a different manner. Any ideas?
Here is /etc/apache2/sites-available/mysite
<VirtualHost *:80>
ServerAdmin me#mysite.com
ServerName mysite.com
ServerAlias www.mysite.com
WSGIScriptAlias / /root/me/index.wsgi
Alias /static/ /root/me/static/
<Location "/static/">
Options -Indexes
</Location>
ErrorLog /var/log/mysite/error.log
</VirtualHost>
Thanks for the comments. I'll mark this as the correct answer for future reference.
I ended up moving the whole Django project to /home/anotheruser, and defined DocumentRoot as per Aamir Adnans suggestion. After service apache2 restart it started working.

Django + apache: How can I create a server alias which invisibly redirects to my django app on the server?

I am trying to figure out a how to forward a specific alias of a server to a specific django web app, and at the same time, keep the URL address bar in the user's browser to only show the server alias.
To be more specific:
This is for an intranet project at my company. We have a big linux server which does a lot of computational work, and it is also running apache to serve a variety of web pages and apps. My current django app is running at:
http://deptserver.example.com/mydjangoapps/myapp
But, I would love it if my users could use this instead:
http://myapp.example.com/
(I already have the IT folks forwarding myapp.example.com to deptserver.example.com via a CNAME in the DNS)
I can't break anything on the apache server, since it is serving critical stuff, but I do have the ability to add in things like a VirtualHost or some url rewriting rules, etc.
This is my django setup in the apache httpd.conf file:
<Location "/mydjangoapps">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mydjangopath.settings
PythonOption django.root /mydjangoapps
PythonPath "['/home/me/mydjangopath'] + sys.path"
PythonDebug On
</Location>
And, this is in the sites-enabled default file (i.e. I can't break this part of the server):
<VirtualHost *:80>
ServerAdmin webmaster#example.com
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 /var/log/apache2/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
</VirtualHost>
In that above VirtualHost I've tried something like this using mod_rerwite:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^myapp\.example\.com
RewriteRule ^(.*) mydjangoapps/myapp$1
Which doesn't work because it thinks that mydjangoapps/myapp is a file path and not a URL path, so it gives me a 400 error. I wish that it would forward to a URL path instead.
I have also tried this:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^myapp\.example\.com
RewriteRule ^(.*) http://deptserver.example.com/mydjangoapps/myapp$1
Which just forwards the user to that long URL.
These are the things I have thought about but haven't tried too much:
virtualhost
mod_rewrite
alias
proxy (?)
port (putting my own apache server on a different port of the main server)
What's the best way (or only way) to do this?
Thanks!
Ask your IT folks to add another IP address (let's say a.b.c.d) to that box's network interface, and then route myapp.example.com to that new ip address.
That way, you can set up a completely separate VirtualHost:
<VirtualHost a.b.c.d:80>
# Your configuration here
</VirtualHost>
<VirtualHost *:80>
# The existing configuration here, unchanged
</VirtualHost>
Then you just have to change <Location "/mydjangoapps"> to <Location "/"> and you'll be able to access your website from a browser at http://myapp.example.com/.
As AndrewF noted, VirtualHosts are the way to go here. If you don't want to use the IP address, you can just set it up with name-based virtual hosting:
NameVirtualHost *:80
<VirtualHost *:80>
ServerName myapp.example.com
(...etc...)
Then that bit of the configuration will only respond to requests on myapp.example.com, leaving the standard configuration to pick up everything else.
Edit after comment If you're on a Debian-based system, which you seem to be as you mention sites-enabled, you shouldn't really be putting anything in httpd.conf - all the site-specific stuff should be in a separate file. This file should go in sites-available, and then run sudo a2ensite my_site_file to symlink it to the sites-enabled directory.

Django (wsgi) and Wordpress coexisting in Apache virtualhost

I have a Django project that I need mounted at two different subdirectories of my url, and I need Wordpress running at /. So:
*.example.com - WordPress
*.example.com/studio - django
*.example.com/accounts - django
Here's the httpd.conf that I have so far:
<VirtualHost *:80>
ServerName wildcard.localhost
ServerAlias *.localhost
AddType application/x-httpd-php .php
DocumentRoot /var/empty
Alias /site_media/ /home/zach/projects/python/myproject/static/
Alias /media/ /home/zach/projects/python/myproject/env/lib/python2.6/site-packages/django/contrib/admin/media/
Alias / /home/zach/projects/python/myproject/wordpress/
WSGIScriptAlias /accounts /home/zach/projects/python/myproject/app/privio.wsgi
WSGIScriptAlias /studio /home/zach/projects/python/myproject/app/privio.wsgi
<Directory /home/zach/projects/python/myproject/app>
Order allow,deny
Allow from all
</Directory>
<Directory /home/zach/projects/python/myproject/wordpress>
Order allow,deny
Allow from all
</Directory>
Before I added the config for WordPress, the Django app was working fine. But with this new setup I am able to see the WordPress install at /, but the Django app isn't getting served. I'm sort of a noob at Apache config - what am I missing?
Replace:
DocumentRoot /var/empty
with:
DocumentRoot /home/zach/projects/python/myproject/wordpress
Remove:
Alias / /home/zach/projects/python/myproject/wordpress/
Replace:
WSGIScriptAlias /accounts /home/zach/projects/python/myproject/app/privio.wsgi
WSGIScriptAlias /studio /home/zach/projects/python/myproject/app/privio.wsgi
with:
WSGIScriptAliasMatch ^(/(accounts|studio)) /home/zach/projects/python/myproject/app/privio.wsgi$1
In other words, use DocumentRoot to refer to wordpress that needs to be at root of site and not Alias directive.
The WSGIScriptAliasMatch is so Django itself thinks it is still mounted at root site even though only nominated sub URLs of it are actually passed through. This simplifies things for urls.py.
Note that the $1 at end of WSGI script path is important, so don't leave it off.
Paging Graham Dumpleton :)
I'd venture a guess that the line
Alias / /home/zach/projects/python/myproject/wordpress/
overrides everything below it. Therefore any requests to /accounts will be processed by the wordpress application rather than by the Django application.
From the documentation:
Mounting At Root Of Site
If instead you want to mount a WSGI application at the root of a site, simply list '/' as the mount point when configuring the WSGIScriptAlias directive.
WSGIScriptAlias / /usr/local/www/wsgi-scripts/myapp.wsgi
Do note however that doing so will mean that any static files contained in the DocumentRoot will be hidden and requests against URLs pertaining to the static files will instead be processed by the WSGI application.

Setting up several Django apps on one server

I've been trying to configure two separate Django apps on one server such that they can be accessed at different URL's...using the below config, I can access the first app, but I'm at a loss at how to include the setup for the second app. The admin media is also not being loaded at all
NameVirtualHost *:8032
ServerName localhost
ServerAdmin webmaster#example.com
DocumentRoot "/usr/local/www/djcode/test"
<Directory "/usr/local/www/djcode/test">
Options +ExecCGI
Order allow,deny
Allow from all
</Directory>
Alias /site_media "/usr/local/www/djcode/test/site_media/"
Alias /media "/usr/local/www/djcode/test/site_media/media/"
WSGIDaemonProcess test user=www group=www processes=2 threads=5
WSGIProcessGroup test
AddHandler wsgi-script .wsgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /test.wsgi/$1 [QSA,L]
ServerName localhost
ServerAlias localhost
DocumentRoot "/usr/local/www/apache22/data"
Make two configuration files in /etc/apache2/sites-available folder. Give them proper logical names according to your sites (e.g. example1.com , example12.com etc). Use a2ensite command to enable both of them and restart your apache server.
Each of your config file should look something like this:
<Virtualhost *:8032>
ServerName localhost
ServerAdmin webmaster#example.com
DocumentRoot "/usr/local/www/djcode/test"
<Directory "/usr/local/www/djcode/test">
Options +ExecCGI
Order allow,deny
Allow from all
</Directory>
Alias /site_media "/usr/local/www/djcode/test/site_media/"
Alias /media "/usr/local/www/djcode/test/site_media/media/"
WSGIDaemonProcess test user=www group=www processes=2 threads=5
WSGIProcessGroup test
AddHandler wsgi-script .wsgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /test.wsgi/$1 [QSA,L]
</Virtualhost *:8032>
You'll also need to add up some directives to serve static content. Serving static content from apache has overhead so it'll be a better idea if you server it using some lightweight webserver such as Lighttpd or Nginx and connect to apache using reverse proxy to serve the django based content. Here's a tutorial on using NginX
Since you are using mod_wsgi, you can run each site as different user as well so that two of them may not access each other's data. This is useful if the two sites belong to different stakeholders.
It is not clear whether you want them to both be hosted under the same VirtualHost or not. Others have gone off and told you to use separate VirtualHost's but that isn't necessary and it can be done under the same VirtualHost. Some have provided a configuration using mod_python when you were actually using mod_wsgi. You also technically didn't need the Alias directives for the static media, although where you stored them may need to change depending on URL you expected to be able to use to access them.
That all said, for your current configuration, because you have used AddHandler to map .wsgi files you can already host multiple applications, you would just need to create multiple .wsgi files in the document directory and use the appropriate URL to access them. Further configuration could be added to avoid needing to specify the '.wsgi' extensions in the URL.
I can give a proper answer if you do the following:
Say whether they need to be under the same VirtualHost.
Say what URL within the VirtualHost each distinct application should be accessible as.
Say what media URL should be used for each distinct application.
Say whether each should run in a separate process, or whether them running in different sub interpreters of the same process is adequate. Running in separate processes would allow each to be restarted independently when making code changes.
You can create multiple Virtual Hosts in Apache, and modify the following for each app:
<VirtualHost *:80>
DocumentRoot /var/www
ServerName www.site.com
<location "/<name>">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE <app name>.settings
PythonPath "['/path/to/app'] + sys.path"
</location>
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/site2
ServerName www.site2.com
<location "/<name2>">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE <app2 name>.settings
PythonPath "['/path/to/app2'] + sys.path"
</location>
</VirtualHost>
edit: also add the following to each Virtual Host
<location "/media">
SetHandler None
</location>
<location "/admin_media">
SetHandler None
</location>
<locationmatch ".(jpg|gif|png)$">
SetHandler None
</locationmatch>
I've encountered something like this. Here's some related questions, albeit not precisely on point:
How does one set up multiple accounts with separate databases for Django on one server?
Multiple installs of Django - How to configure transparent multiplex through the webserver (Lighttpd)?
Hope it helps, though.
For the admin media you can put the same alias in both virtual hosts, or if they need to be different setup a copy of them and have 2 different aliases.