Serve multiple Django static directories with Apache - django

Is there a way to serve 2 or more static directories from Apache? I am using Django and it works fine with 1 static path; when I put 2 it ignores the 2nd.
I don't want to use collecstatic. Just trying to setup my development environment and I like to keep my statics in each app separately. I know in production this will change.
Here is my Apache httpd.conf code:
#games app
Alias /static/ "C:/nerd_project/nerd/games/static/"
<Directory "C:/nerd_project/nerd/games/static">
Require all granted
</Directory>
#ice_cream app
Alias /static/ "C:/nerd_project/nerd/ice_cream/static/"
<Directory "C:/nerd_project/nerd/ice_cream/static">
Require all granted
</Directory>
games app works; the css and images load
ice_cream app does not load and is ignored

You are trying to Alias same URL path /static/ to two directories. That's why it's failing.
Django has pretty fine documention on Serving static files during development.
Check STATICFILES_DIRS settings docs to serve static files from multiple directories.
If you are trying to serve multiple projects static you may consider VirtualHost.

I was also having the same problem till today morning and landed on this page to understand why my static file configs were failing.
You can serve multiple apps with multiple static locations.
See how I have two Flask app and one Django app running and static files being served from different locations for all.
ServerName ec2-52-20-211-238.compute-1.amazonaws.com
# logs configuration
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
WSGIDaemonProcess aira threads=5
WSGIScriptAlias /aira /var/www/aira/aira/aira/aira.wsgi
Alias /aira/static/ /var/www/aira/aira/aira/static/
<Directory /var/www/aira/aira/aira/>
Order allow,deny
Allow from all
</Directory>
WSGIDaemonProcess ama threads=5
WSGIScriptAlias /ama /var/www/AMA/ama.wsgi
Alias /ama/static/ /var/www/AMA/static/
<Directory /var/www/AMA>
Order allow,deny
Allow from all
</Directory>
WSGIDaemonProcess realestatesurvey threads=5
WSGIScriptAlias /RealEstateSurvey /var/www/RealEstateSurvey/mydata/wsgi.py
Alias /RealEstateSurvey/static/ /var/www/RealEstateSurvey/mydata/static/
<Directory /var/www/RealEstateSurvey/mydata/static>
Order allow,deny
Allow from all
</Directory>
For flask template just use
For Django:
STATIC_URL = '/RealEsatateSurvey/static'
in html files:-

I can give a much more easier way to solve this issue that I learned about recently.
If you don't want to serve your static files with Nginx or a apache, but from different apps or folders you can install a pip module called whitenoise in your virtual environment.
Refer this: whitenoise docs
And then just add this in middlware before the sessionmiddleware in your settings.py file.
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware', # Serve static in production without nginx or apache
'django.contrib.sessions.middleware.SessionMiddleware',
........
]
Then finally you can remove those Alias statements for rendering static files from your httpd.conf file. Make migrations and restart the server, your problem will be solved.

I figured out EXACTLY what needs to be done to serve multiple static directories using Apache.
This page https://docs.djangoproject.com/en/1.8/howto/static-files/ mentions this:
"Also this helper function only serves the actual STATIC_ROOT folder; it doesn’t perform static files discovery like django.contrib.staticfiles."
Adding + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) to the urls.py did not load the css and images. You have to read a bit more carefully and go to this page:
https://docs.djangoproject.com/en/1.8/ref/contrib/staticfiles/#django.contrib.staticfiles.views.serve
I added the following to the my urls.py and now IT WORKS:
from django.conf import settings
from django.contrib.staticfiles import views
if settings.DEBUG:
urlpatterns += [
url(r'^static/(?P<path>.*)$', views.serve),
]
I simply commented out the alias and directories pointing to the 2 static directories in Apache's httpd.conf file.
Of course this is strictly for a development server only as I like to keep my statics in each app.

Related

Apache is not serving static files from Django app

I don't know what's wrong in my virtualhost for django project but the simply question is no matter what modification I do over this file stills output the same in error log from apache and not load any css or js files, what I can see is that Apache is looking for static and media file in the root web folder: /var/www
[Fri May 30 00:58:08 2014] [error] [client 192.168.1.145] File does not exist: /var/www/static, referer: http://192.168.1.143/dgp/login/
I set up virtual host file as follows:
WSGIPythonPath /var/www/dgp_python2_7/bin/python2.7:/var/www/dgp_python2_7/lib/python2.7/site-packages
WSGIScriptAlias /dgp /var/www/dgp/dgp/dgp/wsgi.py
<VirtualHost 127.0.0.1:80>
ServerName www.dgp.dev
ServerAlias dgp.dev
AliasMatch ^/([^/]*\.css) /var/www/dgp/dgp/static/$1
Alias /media/ /var/www/dgp/dgp/media/
Alias /static/ /var/www/dgp/dgp/static/
Alias /images/ /var/www/dgp/dgp/images/
<Directory /var/www/dgp/dgp/static/>
Order deny,allow
Allow from all
</Directory>
<Directory /var/www/dgp/dgp/media/>
Order deny,allow
Allow from all
</Directory>
ErrorLog /var/www/dgp/dgp/error.log
CustomLog /var/www/dgp/dgp/access.log combined
</VirtualHost>
And in settings.py STATIC_ROOT with '/var/www/dgp/dgp/static/' where is located all the css content.
How can I tell apache or Django to looking for the proper directory '/var/www/dgp/dgp/static/'? It's driving me crazy, I don't understand how something so elemental in development it's so complex for production.
Regards!
Edit with the solution
The really problem was that I didn't disable the default site for Debian Apache (that is the version I'm working for) and has another method for stablish virtualhost, at beginning we have to disable default site with the follow command: a2dissite defaultand everything works now like a charm!
You can tell where your static files are being looked for in your project's rendered html. Just view the source in your browser and look for a stylesheet or javascript include, what is the full path to the file?
My guess, you have to run Django's collect static script, which will collect all the static scripts in all of your project's app and put them into one location. This is a core part of deploying Django projects and unavoidable if you use multiple "apps" in your project.
in your terminal go to the Django projects root folder and type this:
python manage.py collectstatic
Read more at https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/

django project on apache2 + mod_wsgi - TemplateDoesNotExist

I just installed mod_wsgi on server with apache2.
I also installed django.
I created project and app inside project (in fact I uploaded app from my local machine).
The url-view mapping in my app works but when view tries to render any template there is TemplateDoesNotExist exception.
All my templates are in /[project]/[app]/templates/[app] (there are also some sub directories in this directory such "elements" and "errors" with specific templates)
Anyway it seems that django/wsgi doesn see the templates in my app - on my local machine {with django developement server) it works ok and django finds templates in my [app]/templates directory.
I am render templates using this path "[app]/base.html" or "[app]/elements/some_elements.html"
in my httpd.conf:
WSGIScriptAlias /wsgi /var/src/[project]/[project]/wsgi.py
WSGIPythonPath /var/src/[project]/
<Directory /var/src/[project]>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
Do you have TEMPLATE_DIRS in settings.py pointing at the correct location for this server?

Django + mod_wsgi: Can someone advise me on my setup and rewrite rules

This is my first time deploying Django to a recently acquired Linode server and I'm curious if someone can look over my deployment and help me fix some nagging issues and advise me whether i'm doing things incorrectly.
Directory Structure
home\
-public\
-example.com\
-public\
-.htaccess
-index.html
-log\
-application\
-mysite\
-mysite\
-manage.py
-static\
-myapp\
-logs\
How is this for deployment structure for Django?
Incorrect URL Naming
I've hosted the Django application called 'myapp' on my domain 'example.com'. Following the instructions on the Django website I've made it so that the urls.py for the app must begin with '/myapp'. This has resulted in the domain for the app becoming 'example.com/myapp'.
How can I set it so that example.com is simply the Django app I've written?
I'd like to simply navigate to example.com and it load my app instead of example.com/myapp.
Even weirder is that I would've thought that example.com would load my index.html file however it tries to find a URL mapping for Django instead...
Django Log File Writing Permissions
Whenever I SSH onto my machine to either 'syncdb' or 'collectstatic', the logging module creates the log file I've named in my settings.py file. This causes problems for me because I am the owner of the file and apache2 (www-data) cannot write to it. It's just annoying having to manually delete the log file after every command before I restart the apache server.
Here is my /etc/apache2/sites-available/example.com file:
# domain: example.com
# public: /home/setheron/public/example.com/
WSGIPythonPath /home/setheron/public/example.com/applications/mysite:/home/setheron/env/lib/python2.7/site-packages
<VirtualHost *:80>
# Admin email, Server Name (domain name), and any aliases
ServerAdmin setheron#setheron.com
ServerName www.example.example.com
ServerAlias example.com
WSGIScriptAlias / /home/setheron/public/example.com/applications/mysite/mysite/wsgi.py
Alias /static/ /home/setheron/public/example.com/applications/mysite/static/
<Directory /home/setheron/public/example.com/applications/mysite/static/>
Order deny,allow
Allow from all
</Directory>
<Directory /home/setheron/public/example.com/applications/mysite/mysite>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
# Index file and Document Root (where the public files are located)
DirectoryIndex index.html index.php
DocumentRoot /home/setheron/public/example.com/public
# Log file locations
LogLevel warn
ErrorLog /home/setheron/public/example.com/log/error.log
CustomLog /home/setheron/public/example.com/log/access.log combined
</VirtualHost>
If you want Django serving the entire site, get rid of your public directory, indexes and whatnot. Other than /static, you should only need your WSGIScriptAlias directive. Fix the urls.py to say that your site should be coming from /, rather than /myapp.

setting up two Django websites under Apache with WSGI

I've set up a django website as described in the django docs: https://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/
Now I want to setup another version of the site (different source dir, different database) to run on the same server. There are active users and flex apps who use app #1, so I want to keep app #1 access unchanged. I also rather not change the urls.py at all even for app #2.
I was thinking of different port for app #2
For example
http://192.168.1.1/load_book/123/ will load book from app #1
http://192.168.1.1:444/load_book/123/ will load book from app #2
I'm a complete noob to Apache and WSGI... how do I set it up?
What do you mean by they have the same URLs? The same hostname, perhaps?
Let's say you've got 2 apps:
http://example.com/your_app
http://example.com/my_app
These can both be Django apps, served by WSGI, on the same Apache instance. Using either Directory or Location directives in your apache conf to specify the .wsgi loader file as described in the django docs linked above:
<Location /your_app>
WSGIScriptAlias /your_app /path/to/mysite/apache/your_app/django.wsgi
...
</Location>
<Location /my_app>
WSGIScriptAlias /my_app /path/to/mysite/apache/my_app/django.wsgi
...
</Location>
The only real gotcha is that you'll need to tell your_app and my_app that they are no longer on the document root of the host. To do this, add a base_url parameter to your settings.py and prefix all of the entries in your urls.py with this param. This will ensure when the request comes through Apache, your python app can route it accordingly.
For an easy example of how this is done, have a look at the code for Bookworm, a Django app.
You can attatch the wsgi application to different sub-paths under the same domain. If you do this the paths to the views inside Django will still be the same. You do not have to modify the urls.py. In the following example Django will regard /site1 as the root of project1.
Check out http://code.google.com/p/modwsgi/wiki/InstallationInstructions for documentation on mod_wsgi.
<VirtualHost *:80>
ServerName www.example.com
WSGIDaemonProcess example
WSGIProcessGroup example
WSGIScriptAlias /site1 /home/django/project1/deploy/wsgi.py
<Directory /home/django/project1/deploy>
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias /site2 /home/django/project2/deploy/wsgi.py
<Directory /home/django/project2/deploy>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
Now the two sites will run in the same daemon process using different python sub-interpreters.

Serving 2 django sites with the same code

I'm serving a django site with apache and wsgi using an apache config as follow:
Alias /media/ /var/www/media/
Alias /files/ /var/www/files/
WSGIDaemonProcess fc processes=5 threads=5 display-name=%{GLOBAL}
WSGIProcessGroup fc
WSGIScriptAlias / /home/path/to/django.wsgi
The app is served in the root directory of the host. I'd like now to change this so I can serve it at http://host/app1 and another one, with a different django setting, at http://host/app2
How can I change the config to do this?
Thanks
You'll need a set of WSGI* directives for each project. That second parameter to WSGIScriptAlias tells Apache where the project lives in the tree; WSGI removes this prefix before the URL is passed to Django's URL resolver.
For example:
WSGIDaemonProcess app1 threads=15
WSGIScriptAlias /app1 /var/www/django_project1/django.wsgi
<Location /app1>
WSGIProcessGroup app1
</Location>
WSGIDaemonProcess app2 threads=15
WSGIScriptAlias /app2 /var/www/django_project2/django.wsgi
<Location /app2>
WSGIProcessGroup app2
</Location>
I haven't tried to optimize this; there may be a better way. But this should get you running.
You may try to make other folder with second settings.py and create symbolic links to your apps, locales, static, templates, urls.py etc.
I have multiple projects using same apps so I've put them in standalone folder which i added to python path. I also use same database for both sites, but i have different SITE_ID so i can specify wchich site i want to have my content. This way i can have totally different websites using different templates, styles and images having the same content. If JS scripts are the same on both sites i create a symlink.