Serving static files on a webserver in Django - django

I am setting up my site on an external server (AWS). Everything seems to be working except for the static files (CSS and images).
My project is set up like so --
/var/www/
djangoapps
myproject
settings.py, apps, etc.
djangotemplates
myproject
HTML files
/var/www/html
media
static
Images & CSS files
In the httpd conf file I have --
<Location /mysite>
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
SetEnv PYTHON_EGG_CACHE "/var/cache/www/pythoneggs"
PythonDebug Off
PythonPath "['/var/www/djangoapps'] + sys.path"
</Location>
<Location "/media/">
SetHandler None
</Location>
And in settings.py --
STATIC_URL = '/myproject/static/'
STATICFILES_DIRS = ('/var/www/html/media/static/',)
When I load the page, the templates are working, and the URL to the image files is 'correct' (e.g., background: url("/myproject/static/email.jpg"). However, the images are not loading. What do I need to change so that the images and CSS will load properly?

Have you seen the official docs on serving static media with mod_python? I suspect you need a similar SetHandler for your static files that you do for your media files.
Also, mod_python is deprecated.

You need to add an alias for your static files to be served from. Something like:
Alias /myproject/static/ /var/www/djangoapps/myproject/media/static
This way Apache will serve the static files instead of asking django to handle it.

Related

Why isnt Django not loading built-in static files?

I have a Django instance set up on an Apache server running through uWSGI hunky dory. Everything looks perfect on my local machine when I use python manage.py runserver. Unfortunately, the minute I uploaded the files to my pre-prepared production server, it refused to load all of Django's built-in static files, returning a 404 and I have no idea why...
The url that is being queried is listed as www.mysite.com/static/admin/css/fonts.css and is similar for the admin backend(css/base.css,css/dashboard.cssandcss/responsive.css). At first I thought it might be something wrong with the packages so I force-reinstalled Django but no go. Still not loading...
Here is my uWSGI config .ini:
[uwsgi]
chdir = /path/to/top/level/mysite
module = mysite.wsgi:application
env = DJANGO_SETTINGS_MODULE=mysite.settings
master = true
pidfile = /path/to/project.pid
socket = 127.0.0.1:49152
; Dont use UNIX sockets as it confuses the proxy and alters the request
: URL's. Current Apache version cant handle it.
; socket=/var/run/swerth_django.sock
processes = 5
harakiri = 20
post-buffering = 1
max-requests = 5000
vacuum = true
home = /path/to/top/level/Virtualenv/directory
daemonize = /path/to/uWSGI.log
env = LANG=en_US.UTF-8
enable-threads = true
And I have included Static root and url as follows (comments were for my own understanding):
#The URL of which the static files in STATIC_ROOT directory are served
STATIC_URL = '/static/'
#The absolute path to the directory where ./manage.py collectstatic
# will collect static files for deployment.
STATIC_ROOT = '/home/swerth/public_html/swerth/static'
It is worth mentioning however, I do not have any static files of my own as of yet. I am not at that point in development. I simply want to use the templates shipped with Django.
Edit:
Ok, so I did some research and managed to narrow it down a bit (Thank you to #Alasdair for pointing out a particular page in the Django docs). It seems that I can run python manage.py collectstatic just fine and it imports all the files I need into www.mysite.com/static. For some reason however, django dosnt seem to be 'seeing' the files as they don't render in browser (404 not found).
In light of this I am assuming its my config in settings.py?
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
#The URL of which the static files in STATIC_ROOT directory are
#served
STATIC_URL = '/static/'
#The absolute path to the directory where ./manage.py collectstatic
# will collect static files for deployment.
STATIC_ROOT = os.path.join(BASE_DIR, "static")
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
My Apache is set up as a reverse proxy using the following config:
RewriteEngine off
ProxyPreserveHost on
ProxyPass "/" "uwsgi://127.0.0.1:49152/"
ProxyPassReverse "/" "uwsgi://127.0.0.1:49152/"
Am I doing this wrong or something? (P.s. I am trying to avoid having to edit the HTML files static file link as I really would prefer to know WHAT I'm doing wrong so it doesn't happen again since Django should be able to serve straight from www.mysite.com/static)
Edit Round 2:
Ok, so I did as suggested and tried to set up my proxy to exclude the static directory and just serve the files normally and added an alias to map the URL to the actual directory but it still isn't working properly. It seems to completely ignore my ProxyPass exception and sends it off to Django even though I included it above the less specific rule? Interesting issue, when I specify /admin/ instead of just / for the less-specific ProxyPass, it only proxies that URL to Django, however, all of a sudden Django kicks up a 404 for /admin/. Additionally, I get a 403 forbidden for the static files I was trying to serve?!?! My current .conf looks like this:
Alias /static/ /home/swerth/public_html/swerth/static/
<Directory /home/swerth/public_html/swerth/static/>
Require all granted
</Directory>
<Directory /home/swerth/public_html/swerth/swerth/>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
ProxyPreserveHost on
ProxyPass /whm-server-status/ !
ProxyPass /static/ !
ProxyPass / uwsgi://127.0.0.1:49152/
ProxyPassReverse / uwsgi://127.0.0.1:49152/
This is probably because you've not set up Apache to serve your static files. Try doing the following
Go to your 'static' file folder and get the absolute path to that folder using pwd. Looks like /home/swerth/public_html/swerth/static in your case. Also make sure that the user running the Apache httpd's process has read access to the static folder.
Now edit your VirtualHost by doing
sudo nano /etc/apache2/sites-available/000-default.confsudo nano /etc/apache2/sites-available/000-default.conf
Replace 000-default.conf with your own if you're using a different config file.
Add the following to the virtual hosts block:
<VirtualHost *:80>
. . .
Alias /static /home/swerth/public_html/swerth/static
<Directory /home/swerth/public_html/swerth/static>
Require all granted
</Directory>
. . .
</VirtualHost>
Also make sure you place this above your uwsgi <Directory> part
4. Restart apache by doing sudo systemctl restart apache2
This is a good tutorial I found on how to deploy a Django app to production.
Hope this helps.

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/

my website urls via apache2 dont work

my first question for this site, i hope it goes well!!
I have, ubuntu, apache2, python, django and mod_python.
All is installed properly.
I have created a website project which works properly when i run it locally.
But i cant get it working the same way on apache.
I can access my website project directories, but i cant access my website projects URL's
I think this has something to do with incorrectly configuring my directives in the httpd.conf file. Also when i type the server name in the web browser i get a server not found
a quick rundown:
My project lives in /home/jamie/mysite
django, apache, modpython on root directory
in /etc/apache2/sites-available/http.conf i have:
NameVirtualHost 111.22.33.44
<VirtualHost 111.22.33.44>
ServerName www.example.com
DocumentRoot /home/jamie/mysite
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Location "/mysite">
SetHandler python-program
PythonHandler django.core.handlers.modpython
#removed line -PythonHandler mod_python.publisher- didnt work#
SetEnv DJANGO_SETTINGS_MODULE mysite.settings
PythonPath "['/home/jamie/', '/usr/local/lib/python2.6/dist-packages'] + sys.path"
PythonAutoReload On
PythonDebug On
</Location>
</VirtualHost>
ANybody that can help me i will give 1 BILLION DOLLARS to
ok akonsu cheers for this.
http//localhost/templates points to my templates folder and shows all the files and subdirectories. http//localhost/templates/homepage.html will show the homepage.html located in the templates folder with all the ugly django tags that go with it.
I want run my website app on apache the same way as if i ran it locally, via the urls.
example. http//localhost/homepage would point directly to the file homepage.html which is located in the templates folder as this is how it is set out in the urls.py file and would not show the ugly django tags.
If i do type in http//localhost/homepage via the apache server i get the url /homepage does not exist on this server
The django book tells me to point DJANGO_SETTINGS_MODULE to my apps settings file, which i have done 'DJANGO_SETTINGS_MODULE mysite.settings' The settings file points to the urls file which points to the views file which in turn renders with template files and so on and so forth. Thus if i typed http//localhost/homepage it should work as homepage has been configured properly in my urls.py file. I believe i have done what they have asked but still no luck. Either im getting the DJANGO_SETTINGS_MODULE part wrong or starting with /localhost is wrong.
I dont know what difference this makes but if i change the servername in the httpd.conf file to say www.blabla.com it wont throw an error when i restart apache server, meaning it's configured right. But when i type www.blabla.com in the browser i get an error saying this site does not exist.
try removing PythonHandler mod_python.publisher

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.

django site doesn't see urls.py

I just moved my site to an actual apache server (was developing locally before) and the site can't seem to find the urls.py file. basically what happens is that the homepage works, which is weird in itself considering that if i go to any url, e.g. website/about/, i will get a 404 error with text {'path': u'about/'}.
I tried ROOT_URLCONF set to mysite.urls and just urls, and if i move the urls.py it will continue to behave the same way.
I don't know if its related but I also can't seem to access my site media folder, it seems as though the server is still reading it in its old path, but the settings.py file is correct. (tried restarting apache, rebooting server, etc..)
I would be more worried about it not finding the media directory, that's pure apache. If that part of the equation isn't working, nothing else will. Work with apache's httpd.conf until you can browse to the media directory correctly first.
Update:
I copied in my working conf file and substituted your values. Your django.root might need to be "" or not set at all, as I've found that it shouldn't end with a /:
<Location "/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE fikdusite.settings
PythonOption django.root ""
PythonDebug On
PythonPath "['/django_apps/', '/django_apps/fikdusite/'] + sys.path"
</Location>
And make sure that the .profile of the user that apache runs your site as, has:
export DJANGO_SETTINGS_MODULE='fikdusite.settings'
export PYTHONPATH=$PYTHONPATH:/django_apps:/django_apps/fikdusite
First, don't use mod_python, use mod_wsgi.
Secondly, don't forget that you need to restart Apache every time you make a code change in Django.