Django collectstatic and Apache issue - django

I use this command:
$ python manage.py collectstatic
to collect all static files from all applications and upload them to one single folder apps/apps/static/. So, I now have this file tree:
\home
\jacobian
\apps // <-- this is the root folder of my Django project
\apps
settings.py
urls.py
...
\static
The command collectstatic works fine - I see how it uploads all necessary files. But the problem is, I do not know how to force Apache now to load static files from that single \static folder. I tried to add these lines to my mysite.conf:
<VirtualHost *:80>
....
AliasMatch ^/js(.*) /home/jacobian/apps/apps/static$1
Alias /static/ /home/jacobian/apps/apps/static
</VirtualHost>
But is does not work. When I restart Apache and reload the page (which itself contains the link src="/js/test.js") in browser, I see in the console:
localhost/home/jacobian/apps/apps/static/js/test.js [HTTP/1.1 404 NOT FOUND]
although it seems that the url is resolved correctly, for some reason Apache is unable to upload static content from there. And by the way, what I also do not like about this is that the server discards home/jacobian/ part of the url.
EDIT
apache conf file looks like:
<VirtualHost *:80>
AliasMatch ^/js(.*) /home/jacobian/apps/apps/static$1
Alias /static/ /home/jacobian/apps/apps/static
DocumentRoot /home/jacobian/apps/apps
<Directory /home/jacobian/apps/apps/>
Order allow,deny
Allow from all
Options -Indexes
</Directory>
<Directory /home/jacobian/apps/apps/static>
Order allow,deny
Allow from all
</Directory>
WSGIScriptAlias / /home/jacobian/apps/apps/wsgi.py
</VirtualHost>
And this is what I have in Django project settings.py:
STATIC_URL = '/home/jacobian/apps/apps/static/'
STATIC_ROOT = '/home/jacobian/apps/apps/static/'
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
EDIT
I also tried this configuration:
<VirtualHost *:80>
AliasMatch ^/js(.*) /home/jacobian/apps/apps/static$1
Alias /static/ /home/jacobian/apps/apps/static
WSGIScriptAlias / /home/jacobian/apps/apps/wsgi.py
<Directory /home/jacobian/apps/apps>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
</VirtualHost>
but still get the very same error localhost/static/js/test.js [HTTP/1.1 404 NOT FOUND], even though there is a file /home/jacobian/apps/apps/static/js/test.js. I have a guess that it might be somehow related to the DEBUG mode in settings.py. Maybe I should do some extra magic with urls.py?

First, change your STATIC_URL to: '/static/'. That should be URL on what Apache serves your static files, not system directory path.
Second, remove DocumentRoot from your apache config. All files outside of static directories should be handled by wsgi.
Third, change:
<Directory /home/jacobian/apps/apps/>
Order allow,deny
Allow from all
Options -Indexes
</Directory>
to:
<Directory /home/jacobian/apps/apps>
<Files wsgi.py>
Order allow,deny
Allow from all
</Files>
</Directory>
You don't want to serve all your files, just wsgi.py should be accessed publicly, and handled by WSGI. Also try to move that block below WSGIScriptAlias.
Fourth, remove trailing slash at the end of path in <Directory /home/jacobian/apps/apps/>.
Fifth, change allow,deny to deny,allow.

Related

Django + Apache: cannot serve static files

I think this is common problem, but non of the solutions I tried work.
The code from apache conf:
<VirtualHost *:80>
ServerName xxxx
ServerAdmin xxxx
DocumentRoot /home/matousc/apps/iacah
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias /static /home/matousc/apps/iacah/www/static
<Directory /home/matousc/apps/iacah/www/static>
Require all granted
Allow from all
</Directory>
<Directory /home/matousc/apps/iacah/app/mainapp>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess iacah python-path=/home/matousc/apps/iacah/app python-home=/home/matousc/apps/appenv
WSGIProcessGroup iacah
WSGIScriptAlias / /home/matousc/apps/iacah/app/mainapp/wsgi.py
</VirtualHost>
I can access the page via Internet, so I am sure that I am editing the right apache conf file. However the static files are not loaded.
The static files are not downloaded with 403 error. I noticed that if I change the line:
Alias /static/ /home/matousc/apps/iacah/www/static
to (removed slash at the end of static:
Alias /static /home/matousc/apps/iacah/www/static
then I will get 404 error. In tutorials I saw both options, so I am little bit confused why it can play a role.
The owner of the /www/ folder is www-data (I am using ubuntu 18):
drwxrwx--x 3 www-data www-data 4096 Sep 21 10:14 .
drwxr-xr-x 8 matousc matousc 4096 Sep 21 10:14 ..
drwxrwxrwx 12 www-data www-data 4096 Sep 21 10:14 static
I use this machine as a multihost, and I have there one other static website, that works (the files are served correctly)
<VirtualHost *:80>
ServerName xxxxx
ServerAdmin xxxx
DocumentRoot /home/matousc/apps/placeholder
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory /home/matousc/apps/placeholder>
Require all granted
Options +Indexes
AllowOverride None
Order allow,deny
Allow from all
</Directory>
In Django I use (I hope recommended) settings:
STATIC_URL = "/static/"
if production_machine:
level_up = os.path.dirname(BASE_DIR)
STATIC_ROOT = os.path.join(level_up, "www", "static")
STATICFILES_DIRS = (
STATIC_ROOT,
)
else:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
(the production_machine should be True).
Any ideas what else I can try?
Have you run manage.py collectstatic? In production, you need to call this for django to copy from ur dev code to the STATIC_ROOT location.
https://docs.djangoproject.com/en/1.11/ref/contrib/staticfiles/#collectstatic
I am not really sure what was the major problem, however problem magically disappear after another hour of pure witchcraft. For other people that stuck in the same situation:
make sure that you are editing the correct apache conf file
as #Du D. suggest make sure that the static files are collected correctly. There is multiple issues that can occur (it does not grab all your static folders etc...). Search for problem in your settings.py
check that you really know who is the apache user on your machine
make sure that the folder with collected static files is owned by apache user and has the rwx access rights recursively!
play a lot with slashes in apache conf file. Seems that some combinations of slash usage are supperior to others. In my case /static/ was the incorrect one (even though it throw only 403 instead of 404 before). My working example work only with /static.
I probably miss some steps because I was lucky and not encounter all possible problems, so feel free to edit/extend my answer.

Serving admin css for django 1.5 using apache

I am moving a application built on Django 1.5 to the development server, running apache, for the first time. I have it mostly running properly, but I am having issues with the CSS serving. I can either get the site's CSS working but not the admin's css or have the admin's css working but not the site's css.
I followed the documentation's and used the collectstatic command to get all the static assets into the STATIC_ROOT folder.
This is my relevant data from my settings file
STATIC_ROOT = '/var/www/projectmanagement/django/static/'
STATIC_URL = '/static/'
STATICFILES_DIRS = (
'/var/www/projectmanagement/django/projectmanagement/projects/static',
)
This is the relevant data from httpd.conf
Alias /static/admin/ /var/www/projectmanagement/django/static/admin/
Alias /static /var/www/projectmanagement/django/static/
<Directory /var/www/projectmanagement/django/static/>
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias / /var/www/projectmanagement/django/projectmanagement/django.wsgi
<Directory /usr/local/wsgi/scripts>
Order allow,deny
Allow from all
</Directory>
and from my vhost.conf
NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin webmaster#pmt.com
ServerName pmt.com
ServerAlias www.pmt.com
DocumentRoot /var/www/projectmanagement/html/
ErrorLog /var/www/projectmanagement/logs/error.log
CustomLog /var/www/projectmanagement/logs/access.log combined
WSGIScriptAlias /projectmanagement /var/www/projectmanagement/django/projectmanagement/django.wsgi
<Directory "/var/www/projectmanagement/html">
php_admin_value open_basedir "/var/www/projectmanagement/html/:/tmp/:/var/www/projectmanagement /django/projectmanagement/"
php_admin_value include_path "/var/www/projectmanagement/html/:/tmp/:/var/www/projectmanagement /django/projectmanagement/"
</Directory>
</VirtualHost>
When I add the line
AliasMatch /([^/]*\.css) /var/www/projectmanagement/django/static/admin/css/$1
to before the first alias in my httpd.conf file, I get the admin css to work but not the site's css. If it's gone then the site's css works but not the admin's. This has me fairly stumped.
Adding that alias will capture all .css requests, but only looks capable of serving the admin css. Removing it means the css requests will reach your WSGIScriptAlias, and I presume you've got DEBUG = True... so django will be serving your static media for you.
I don't know why django's built in static server isn't working for your admin css - have you set up STATICFILES_FINDERS?
Anyway your alias really should be something like this, so it can serve all of your static files:
AliasMatch /static/ /var/www/projectmanagement/django/static/

Deploy Django on Apache - Directory layout

I have a Django application with the following directory structure
/myapp/
/login/
/myapp_settings/
/subapp1/
/supapp2/
manage.py is in the myapp directory.
In the project's url.py I have URL settings like this:
urlpatterns = patterns('',
url(r'^subapp1/', include('subapp1.urls')),
url(r'^xhr/', include('subapp1.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^subapp2/', include('smart_selects.urls')),
# Login / logout.
url(r'^login/$', 'django.contrib.auth.views.login'),
url(r'^logout/$', 'django.contrib.auth.views.logout', {'next_page': '/subapp1/'}, name='auth_logout'),
url(r'^logout/(?P<next_page>.*)/$', 'django.contrib.auth.views.logout', name='auth_logout_next'),
)
When deployed on the development runserver, everything links and loads correctly. When I deploy the entire myapp directory to the Django root on Apache, I find it's not linking as expected.
For example, if I link to example.com/login/, I get an Apache 404. I think it's because I don't have a virtual directory configuration defined for that specific directory.
I have the following set up in Apache for my application:
WSGIScriptAlias /myapp /var/www/django-projects/myapp/myapp_settings/wsgi.py
WSGIPythonPath /var/www/django-projects/myapp
Alias /media/ /var/www/django-projects/myapp/media/
Alias /static/ /var/www/django-projects/myapp/static/
<Directory /var/www/django-projects/myapp/static>
Order deny,allow
Allow from all
</Directory>
<Directory /var/www/django-projects/myapp/media>
Order deny,allow
Allow from all
</Directory>
<Directory /var/www/django-projects/myapp/myapp_settings/>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
Do I need an Alias and a Directory configuration for each URL pattern I use? If so, how can I redo my URL patterns so that I don't need to do this. I don't want to have to do all of this extra Apache configuration when I deploy the application.
EDIT: I modified my WSGIScriptAlias as suggest by Reinbach. It now reads WSGIScriptAlias / /var/www/django-projects/myapp/myapp_settings/wsgi.py. However, this still returns a 404. The error in the Apache log says
[Fri Sep 07 09:11:00 2012] [error] [client 192.189.x.x] File does not exist: /var/www/html/login
Notice that it's looking in /var/www/html (Default Apache root) instead of /var/www/django-projects
EDIT2: I'm attaching the VirtualHost block for this section
WSGIPythonPath /var/www/django-projects/myapp
<VirtualHost sub.example.com:80>
DocumentRoot /var/www/django-projects/myapp
ServerName sub.example.com
WSGIScriptAlias / /var/www/django-projects/myapp/myapp_settings/wsgi.py
Alias /robots.txt /var/www/django-projects/myapp/static/robots.txt
Alias /favicon.ico /var/www/django-projects/myapp/static/favicon.ico
AliasMatch ^/([^/]*\.css) /var/www/django-projects/myapp/static/css/$1
AliasMatch ^/([^/]*\.js) /var/www/django-projects/myapp/static/js/$1
AliasMatch ^/([^/]*\.png) /var/www/django-projects/myapp/static/images/$1
AliasMatch ^/([^/]*\.swf) /var/www/django-projects/myapp/static/swf/$1
Alias /media/ /var/www/django-projects/myapp/media/
Alias /static/ /var/www/django-projects/myapp/static/
<Directory /var/www/django-projects/myapp/static>
Order deny,allow
Allow from all
</Directory>
<Directory /var/www/django-projects/myapp/media>
Order deny,allow
Allow from all
</Directory>
<Directory /var/www/django-projects/myapp/myapp_settings/>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
</VirtualHost>
I believe you want to change your WSGIScriptAlias as you currently have it expecting to handle example.com/myapp/login while your sample is showing you trying to use example.com/login
WSGIScriptAlias / /var/www/django-projects/myapp/myapp_settings/wsgi.py
See How to use Django with Apache and mod_wsgi
LONG STORY SHORT
Allow and Deny are deprecated since Apache 2.4.x, use Require all granted (or denied) instead.
THE LONG STORY
I'm encountering the same problem while trying to set up Django with Apache and mod_wsgi. I'm not entirely sure why this happens but when I comment out the following lines in the httpd.conf
# Deny access to the entirety of your server's filesystem. You must
# explicitly permit access to web content directories in other
# <Directory> blocks below.
#
#<Directory />
# AllowOverride none
# Require all denied
#</Directory>
everything works alright.
I'm not sure if this is the right and secure way to solve the problem, but I hope it might help.
P.S. I think this shouldn't cause much security troubles since root directory is aliased anyways:WSGIScriptAlias / /var/www/django-projects/myapp/myapp_settings/wsgi.py, but I may be worng.
P.P.S. Looks like the better solution would be to leave those lines uncommented, but change Order and Allow directives in favor of Require all granted. For example:
<Directory /var/www/django-projects/myapp/myapp_settings/>
<Files wsgi.py>
Require all granted
#Order deny,allow
#Allow from all
</Files>
</Directory>
However this is only a trial and error solution I could come up. I got no deep understanding why it works but Order and Allow doesn't.
P.P.P.S Oh, now I know what. Allow and Deny are deprecated since Apache 2.4.x. Good answer can be found here.

Can't get mod_wsgi to work with Apache and Django on Mac OS X

I've been trying to get mod_wsgi working on a Mac OS X server, and I'm having absolutely no luck. I've added the LoadModule statement to the httpd.conf, and I've got the following file included:
apache_django_wsgi.conf:
WSGIDaemonProcess django
WSGIProcessGroup django
Alias /plagtest/ "/Users/plagtest/myproject/"
<Directory "/Users/plagtest/myproject/">
Order allow,deny
Options Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>
WSGIScriptAlias /plagtest "/Users/plagtest/myproject/apache/myproject.wsgi"
<Directory "/Users/plagtest/myproject/apache">
Allow from all
</Directory>
And here's my WSGI file:
myproject.wsgi:
import os
import sys
paths = [ '/Users/plagtest/myproject',
'/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages',
'/Users/plagtest',
]
for path in paths:
if path not in sys.path:
sys.path.append(path)
sys.executable = '/usr/local/bin/python2.7'
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
I can restart Apache just fine, but when I browse to localhost/plagtest/ it comes up file not found, and this is what I get in the error log:
File does not exist: /Library/WebServer/Documents/plagtest/
I'm not entirely familiar with Apache, and I'm sure that it's probably something very simple, but I can't for the life of me find a solution online. Any help in this matter would be greatly appreciated.
It looks like you have two Aliases for the same path. So hence you have a duplication. Remove:
Alias /plagtest/ "/Users/plagtest/myproject/"
<Directory "/Users/plagtest/myproject/">
Order allow,deny
Options Indexes
Allow from all
IndexOptions FancyIndexing
</Directory>
Without the media alias's the django manuals recommended HTTP conf is:
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
<Directory /path/to/mysite.com/mysite>
<Files wsgi.py>
Order allow,deny
Allow from all
</Files>
</Directory>

Serving static files on my own server

im setting a django server, but im having problem with my static's file's:
django settings
STATIC_URL = 'http://localproject/static/'
STATIC_ROOT = '/srv/www/project/static/'
MEDIA_ROOT = '/srv/www/project/public/'
MEDIA_URL = '/public/'
ADMIN_MEDIA_PREFIX = '/static/admin/'
apache
Alias /static/ /srv/www/project/static/'
<Document /srv/www/project/static>
Order allow,deny
Allow form all
</Document>
Alias /public/ /srv/www/project/public/'
<Document /srv/www/project/public>
Order allow,deny
Allow form all
</Document>
So, i have the admin without style and the website, for example http://localproject/public is showing a error about * Not FlatPage matches the given query *
yes, im using django.contrib.staticfiles
Any idea?
Thanks
Two things:
First, ADMIN_MEDIA_PREFIX = STATIC_URL+'admin/'. You can actually use that or change it to ADMIN_MEDIA_PREFIX = 'http://localproject/static/admin/'. /static/admin/ is incorrect in your scenario.
Second, Django is still being handed the request, and 'public' is being passed as a slug to the FlatPages view, which is why you're getting that error. See: https://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/#serving-files for the proper Apache configuration for staticfiles.
Im answering maybe that help someone, the problem was that im using apache (/etc/apache2/sites-available/project), but i was wrong with "use another apache config into the project" /srv/www/project/apache/httpd.conf and setting my Alias in this last one config, when the Alias config need to be in (/etc/apache2/sites-available/project)
using:$ sudo nano /etc/apache2/sites-available/project
and the content for project
<VirtualHost *:80>
ServerName project
DocumentRoot /srv/www/project
<Directory /srv/www/project>
Order allow,deny
Allow from all
</Directory>
AliasMatch ^/([^/]*\.css) /srv/www/project/static/css/$1
Alias /public/ /srv/www/project/public/
Alias /static/ /srv/www/project/productos/static/
<Directory /srv/www/project/productos/static>
Order deny,allow
Allow from all
</Directory>
<Directory /srv/www/project/public>
Order deny,allow
Allow from all
</Directory>
WSGIDaemonProcess project processes=2 threads=15 display-name=%{GROUP}
WSGIProcessGroup project
WSGIScriptAlias / /srv/www/project/apache/django.wsgi
</VirtualHost>
my settings.py:
MEDIA_ROOT = '/srv/www/project/public/'
MEDIA_URL = 'http://project/public/'
STATIC_ROOT = '/srv/www/project/productos/static/'
STATIC_URL = '/static/'
ADMIN_MEDIA_PREFIX = 'http://project/static/admin/'
And now is working :), remember this is my own server