Using iRedMail with a django site on the same server - django

I am trying to create a small django site and use iRedMail for e-mail. I installed iRedMail first, and ensured that it worked. I could go to both www.domain.com/iredadmin and www.domain.com/mail and have it work perfectly. My next step was to install my django site and configure Apache. Unfortunately, this caused my django site to try and handle /mail/ and /iredadmin/. I've been fidgeting with the config for a few hours now and have no idea what to do. Here are the settings:
apache2.conf:
# Defaults...
WSGIPythonPath /path/to/website.com/website
sites-enabled/website.com:
<VirtualHost *:80>
ServerName website.in
ServerAlias www.website.in
ErrorLog ${APACHE_LOG_DIR}/error.log
Alias /static /path/to/website.com/website/static
Alias /media /path/to/website.com/website/media
Alias /mail /usr/share/apache2/roundcubemail/
Alias /admin /usr/share/apache2/iredadmin/
<Directory /usr/share/apache2/roundcubemail/>
Order allow,deny
Allow from all
</Directory>
WSGIScriptAlias / /path/to/website.com/website/website.wsgi
<Location "/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE website.settings
PythonDebug Off
PythonPath "['/path/to/website.com/website/']+sys.path"
</Location>
<Directory /path/to/website.com/website>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
<Directory /path/to/website.com/website/static>
Order allow,deny
Allow from all
</Directory>
<Location /static/>
SetHandler None
</Location>
<Directory /path/to/website.com/website/media>
Order allow,deny
Allow from all
</Directory>
<Location /media/>
SetHandler None
</Location>
</VirtualHost>
The django website displays fine, although I have been getting internal server errors.

You are trying to use both mod_wsgi and mod_python to handle the Django site at the same time, with mod_python overriding mod_wsgi. Choose one of the other. Since mod_python is no longer developed or supported and support for it in Django deprecated, probably not a good option to keep using it.
The next thing which is wrong is:
Alias /mail /usr/share/apache2/roundcubemail/
Alias /admin /usr/share/apache2/iredadmin/
Remove the trailing slashes:
Alias /mail /usr/share/apache2/roundcubemail
Alias /admin /usr/share/apache2/iredadmin
Even then it will still not work, because when using mod_python you have to tell mod_python not to handle those paths.
<Location /mail/>
SetHandler None
</Location>
<Location /admin/>
SetHandler None
</Location>
A further problem you may have is that /admin is usually used for the Django admin interface and you are overriding that.

Related

Apache Error: While writing python logs into file outside the project directory

I am working on a Django project and using Apache as web server. Everything is working fine with
python manage.py runserver
But while running the application through apache I am not able to write my python app logs into the stated path which is outside the project directory.
Project directory /home/ubuntu/saas-DocumentProcessing
Log files are in
/home/ubuntu/log/SaasAap/SaasAap.log and /home/ubuntu/log/error/error.log
My 000-default.conf content
<VirtualHost *:8000>
ServerAdmin abc#xyz.com
ServerName my_ip
ServerAlias my_ip
DocumentRoot /home/ubuntu/saas-DocumentProcessing/
WSGIScriptAlias / /home/ubuntu/saas-DocumentProcessing/src/wsgi.py
Alias /static/ /home/ubuntu/saas-DocumentProcessing/static/
ErrorLog /home/ubuntu/log/error.log
CustomLog /home/ubuntu/log/custom.log combined
<Location "/static/">
Options -Indexes
AllowOverride All
Require all granted
</Location>
<Location "/">
AllowOverride All
Require all granted
</Location>
<Directory /home/ubuntu/saas-DocumentProcessing/static>
Order allow,deny
Allow from all
</Directory>
<Directory /home/ubuntu/log>
Order allow,deny
Allow from all
</Directory>
WSGIDaemonProcess saas-DocumentProcessing python-path=/home/ubuntu/
saas-DocumentProcessing python-home=/home/ubuntu/saas-DocumentProcessing/ve
nv
WSGIProcessGroup saas-DocumentProcessing
</VirtualHost>

Can't get Apache to serve django admin static files

I'm trying to deploy Django to apache but can't get it to serve my static admin files. It seems to be looking for them under /var/www/static and I can't seem to be able to change that.
The admin site seem to be working except for styling. I get a title and a log in form. My django app is working too. It's the static files for the admin that aren't served.
Using Django 1.4.1.
The files are under /usr/local/lib/python2.7/dist-packages/django/contrib/admin/static and linked to from /home/dutt/vaccapp/backend/static/admin.
The apache error log says this
[Sun Sep 30 10:57:20 2012] [error] [client 192.168.1.10] File does not exist: /var/www/home, referer: http://dathui.example.com/vaccapp/admin/
[Sun Sep 30 10:57:20 2012] [error] [client 192.168.1.10] File does not exist: /var/www/home, referer: http://dathui.example.com/vaccapp/admin/
But I'm not sure how to change it.
In my django site config I have
<VirtualHost *:80>
ServerAdmin me#host.com
ServerRoot "/home/dutt/vaccapp"
DocumentRoot "/home/dutt/vaccapp"
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /home/dutt/vaccapp/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
Alias /static/ "/home/dutt/vaccapp/backend/static/"
<Directory "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/static">
Order allow,deny
Options Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>
ServerRoot is not set in apache2.conf.
From my settings.py
STATIC_ROOT = '/home/dutt/vaccapp/backend/'
STATIC_URL = '/static/'
Nothing added to STATICFILES_DIRS.
This is added to my apache2.conf
WSGIScriptAlias /vaccapp /home/dutt/vaccapp/backend/wsgi.py
WSGIPythonPath /home/dutt/vaccapp
<Directory /home/dutt/vaccapp>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
ADMIN_MEDIA_PREFIX is set by default to /static/admin/ # Deprecated in Django 1.4 (now using STATIC_URL + 'admin/'. The result is the same.
Here's the fixes to the apache config:
Alias /static/admin "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/static"
Alias /static "/home/dutt/vaccapp/backend/static"
<Directory "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/static">
Order allow,deny
Options Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>
And the WsgiScriptAlias had to be moved from the main apache config into the VirtualHost.
After a long discussion we found the problem was that Django did not install the admin static properly ... they were symlinked to eachother (very weird). A Django reinstall fixed it and it worked fine now.
My low reputation forces me to write a whole answer to add a small detail to Igor's answer.
I simply added the apache config part to my configuration, but it was not sufficient. I had to change:
"/usr/local/lib/python2.7/dist-packages/django/contrib/admin/static"
to
"/usr/local/lib/python2.7/dist-packages/django/contrib/admin/static/admin"
both in the first Alias and in the <Directory> directive.
Just like Blazor I had to use a small variation of the original. My setup includes graphite-web, which is using django admin. I'm just posting it for reference.
My apache's virtual host:
<VirtualHost *:80>
ServerName graphite.myhost.com
Redirect permanent / https://graphite.myhost.com/
</VirtualHost>
<VirtualHost *:443>
ServerName graphite.myhost.com
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/graphite.cert
SSLCertificateKeyFile /etc/apache2/ssl/ssl_graphite.key
SSLStrictSNIVHostCheck on
WSGIDaemonProcess _graphite processes=5 threads=5 display-name='%{GROUP}' inactivity-timeout=120 user=_graphite group=_graphite
WSGIProcessGroup _graphite
WSGIImportScript /usr/share/graphite-web/graphite.wsgi process-group=_graphite application-group=%{GLOBAL}
WSGIScriptAlias / /usr/share/graphite-web/graphite.wsgi
AliasMatch ^/admin/(.*)static/admin(.*)$ /usr/lib/python2.7/dist-packages/django/contrib/admin/static/admin/$2
<Directory "/usr/lib/python2.7/dist-packages/django/contrib/admin/static/admin/">
Order allow,deny
Allow from all
</Directory>
Alias /content/ /usr/share/graphite-web/static/
<Location "/content/">
SetHandler None
</Location>
<Location "/">
Order allow,deny
allow from all
AuthType Basic
AuthName "Restricted Zone"
AuthBasicProvider wsgi
WSGIAuthUserScript /var/www/django_auth.wsgi
Require valid-user
</Location>
ErrorLog ${APACHE_LOG_DIR}/graphite-web_error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/graphite-web_access.log combined
</VirtualHost>
I also added STATIC_URL = 'static/' just to make sure I didn't have any issues with the regex.
Try using next
python manage.py collectstatic
The staticfiles app - Django documentation
I got similar problem when running Django + Apache, the Django admin site misses all styling. This is how I solved it:
apache conf: httpd-app.conf
Alias /static "/...path/to/your/django.../site-packages/django/contrib/admin/static"
<Directory "/...path/to/your/django.../site-packages/django/contrib/admin/static">
Require all granted
</Directory>
The /...path/to/your/django.../ above, you can find it by pip show django

How do I do multi-domain https with mod_wsgi?

I'm a developer and a bit of an apache novice and I'm trying to transition a bunch of our Django https servers to mod_wsgi, which previously used mod_python:
<VirtualHost *:443>
ServerName *.example.com
SSLEngine On
SSLCertificateFile /etc/ssl/star_example_com.crt
SSLCertificateKeyFile /etc/ssl/star_example_com.key
SSLCertificateChainFile /etc/ssl/DigiCertCA.crt
UseCanonicalName Off
VirtualDocumentRoot /var/www/%0
<Directory "/var/www/foo.example.com">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE example.foo.settings
PythonPath "['/home/django'] + sys.path"
PythonDebug on
</Directory>
<Directory "/var/www/bar.example.com">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE example.bar.settings
PythonPath "['/home/django'] + sys.path"
PythonDebug on
</Directory>
</VirtualHost>
This allows us to run several https sites on the same physical server (ip). Adding a new https host simply involves adding a new <Directory> section, and creating the corresponding directory under /var/www/.
The closest I've gotten is by using
<Directory "/var/www/bar.example.com">
SetHandler wsgi-script
Options ExecCGI
</Directory>
and creating /var/www/bar.example.com/bar.wsgi, then I can access urls like https://bar.example.com/bar.wsgi/...rest..of..path..
I haven't been able to find a directive (that can be used inside <Directory>) that is equivalent to WSGIScriptAlias when the target is a file-path, like we're using for the non-https sites:
<VirtualHost *:80>
ServerName bar.example.com
WSGIScriptAlias / /home/venv/upgrade/example/bar/bar.wsgi
<Directory "/var/www/bar/">
Order deny,allow
allow from all
</Directory>
</VirtualHost>
Which allows us to go to http://bar.example.com/...rest..of..path.. (ie. no bar.wsgi prefix).
Is it possible to get rid of the bar.wsgi part in the https url?
[Solution:] (based on #GrahamDumpleton's link):
<Directory /var/www/bar.example.com/>
Options ExecCGI Indexes FollowSymlinks
AddHandler wsgi-script .wsgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /bar.wsgi/$1 [QSA,PT,L]
Order allow,deny
Allow from all
</Directory>
works beautifully.
This is covered in:
http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#The_Apache_Alias_Directive
See the bit towards the end of the section where shows use of mod_rewrite and an application wrapper to do fixups of SCRIPT_NAME.

Two Django projects running simultaneously and mod_wsgi acting werid

I'm trying to run two Django projects simultaneously. I happened to be using mod_wsgi, and found the site is acting weird. Perhaps there would be a workaround, but I'd like to know what I'm missing and how to solve the problem.
In the apache configuration
# Setup the Python environment
# As root owns basically everything on a Amazon AMI and root
# cannot be used. Create a folder under /var/run/wsgi
# with the owner as ec2-user and group ec2-user.
WSGISocketPrefix /var/run/wsgi
# Call your daemon process a name
WSGIDaemonProcess pydaemon processes=1 threads=5
# Call your daemon process group a name
WSGIProcessGroup pydaemon
# Point to where the handler file is. This will be different
# If you are using some other framework.
WSGIScriptAlias /test /var/www/html/test/wsgi.py
WSGIScriptAlias /proto /var/www/html/proto/wsgi.py
After Apache restarts, if I connect to '/proto', then the proto site is shown. However, then I connect to '/test', without restarting Apache, the proto site is still shown, and I cannot access to the test site.
Now I restart Apache, this time I go to '/test' first. The test site comes up! However, if I go to '/proto' it still shows the test site, not the proto site.
What could make this happen? I added SESSION_COOKIE_PATH differently for each application just in case, but the problem still exists.
[UPDATED]
I also tried as the following, to give different WSGI application group names, but without luck.
Alias /cuedit /var/local/test/wsgi.py
<Location /test>
SetHandler wsgi-script
Options +ExecCGI
WSGIApplicationGroup test
</Location>
Alias /proto /var/local/proto/wsgi.py
<Location /proto>
SetHandler wsgi-script
Options +ExecCGI
WSGIApplicationGroup proto
</Location>
[UPDATED]
I changed from the daemon mode to the embedded mode. I guess the problem was two instances shared the same mod_wsgi daemon process so their namespace collide.
I would expect they should be handled correctly, but in the daemon mode I couldn't get it right.
Use this as a workaround:
WSGIDaemonProcess pydaemon-1 processes=1 threads=5
WSGIDaemonProcess pydaemon-2 processes=1 threads=5
WSGIScriptAlias /test /var/www/html/test/wsgi.py
<Location /test>
WSGIProcessGroup pydaemon-1
WSGIApplicationGroup %{GLOBAL}
</Location>
WSGIScriptAlias /proto /var/www/html/proto/wsgi.py
<Location /proto>
WSGIProcessGroup pydaemon-2
WSGIApplicationGroup %{GLOBAL}
</Location>
This will force each application into separate daemon process group and no way they should be able to interfere with each other.
If that still doesn't work, you have problems with your WSGI script file somehow.
I also have 2 Django projects however each one is running on a different port (httpd config), it looks something like this:
<VirtualHost *:80>
ServerAdmin xx
ServerName xx
ServerAlias xx
ErrorLog /path/to/first/project/logs/error.log
CustomLog /path/to/first/project/logs/access.log combined
Alias /static/ /path/to/first/project/sitestatic
WSGIDaemonProcess app processes=1 threads=15 display-name=%{GROUP}
WSGIProcessGroup app
WSGIScriptAlias / /path/to/first/project/django.wsgi
<Directory /path/to/first/project/apache>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:8080>
ServerAdmin xx
ServerName xx
ServerAlias xx
ErrorLog /path/to/second/project/logs/error.log
CustomLog /path/to/second/project/logs/access.log combined
WSGIDaemonProcess app1 processes=1 threads=15 display-name=%{GROUP}
WSGIProcessGroup app1
WSGIScriptAlias / /path/to/second/project/apache/django.wsgi
<Directory /path/to/second/project/apache>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
The problem might be related to Apache sharing the Python sub interpreter between WSGI applications. Try adding this to the Apache configuration to avoid sharing:
WSGIApplicationGroup %{GLOBAL}
Check this blog post for in-depth explanation and additional tips (check the comments too).
Can't comment on the answer given by Graham, so adding one of my own.
The problem for me really was the Python Interpreter, but I also had to add the python-path for each interpreter. Here follows an example configuration:
WSGIDaemonProcess py_app1 processes=1 threads=5 python-path=/path/to/app1
WSGIScriptAlias /app1 /path/to/app1/wsgi.py
<Directory /path/to/app1>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
<Location /app1>
WSGIProcessGroup py_app1
WSGIApplicationGroup %{GLOBAL}
</Location>
WSGIDaemonProcess py_app2 processes=1 threads=5 python-path=/path/to/app2
WSGIScriptAlias /app2 /path/to/app2/wsgi.py
<Directory /path/to/app2>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
<Location /app2>
WSGIProcessGroup py_app2
WSGIApplicationGroup %{GLOBAL}
</Location>

Deploying a Django app on Apache + mod_wsgi with HTTP auth

Is it possible to deploy a Django app on Apache + mod_wsgi (the standard way) but with HTTP authentication in front of the whole thing?
Basically, I need an extra layer of HTTP security before any user, Django-authenticated or anonymous, is even able to reach the app.
Is this possible? If so, where do the Apache auth directives go?
Yes, it's possible.
With mod_wsgi on /, any resources to be provided by apache need to be listed as aliases.
Auth directives and host restrictions live in Location directives.
So I've disabled any apache access restrictions on things like css, and provided host/ip based access to another directory.
<VirtualHost *:80>
Servername app.domain.example
CustomLog logs/access_log combined
ErrorLog logs/error_log
DocumentRoot "/home/app/apache/app/html"
Alias /media/ /home/app/apache/app/html/media/
<Location />
Options None
AuthType Basic
AuthName "Login Prompt"
AuthUserFile /path/to/passwd.file
Require valid-user
</Location>
<Location /media>
Order allow,deny
Allow from all
Satisfy any
</Location>
WSGIDaemonProcess app user=app group=app processes=5 threads=1 display-name=app_WSGI
WSGIProcessGroup app
WSGIScriptAlias / /home/app/apache/app.wsgi
</VirtualHost>
Sure, here is example from one site:
<VirtualHost *:80>
ServerName djangoproject.domain.biz
DocumentRoot "/home/user/websites/djangoproject/website/"
WSGIDaemonProcess djangoproject python-path=/home/user/.virtualenvs/djangoproject/lib/python2
.6/site-packages/ user=user group=user threads=1
WSGIProcessGroup djangoproject
WSGIScriptAlias / /home/user/websites/djangoproject/website/django.wsgi
<Directory "/home/user/websites/djangoproject/website/">
Order deny,allow
Allow from all
AuthType Basic
AuthName "By Invitation Only"
AuthUserFile /etc/apache2/passwords
Require valid-user
</Directory>
</VirtualHost>