Why is static content request going to uwsgi? - django

I'm setting up my Django project to work with uwsgi and nginx. For static content, I have the following in my nginx.conf:
location /static {
alias /Users/me/mystatic; # your Django project's static files - amend as required
}
I have set STATIC_ROOT to /Users/me/mystatic and called collectstatic to copy all the static files into that directory. In my uwsgi log, I see GET requests for the static content. Since nginx is supposed to serve the static content, why is the GET request sent to uwsgi?

Make sure that STATIC_URL is set as "/static/".
The nginx conf should look something like this:
server {
listen 80 ;
server_name XXXX;
client_max_body_size 4G;
location /static/ {
alias <path-to-collectstatic>
}
location / {
include uwsgi_params;
uwsgi_pass unix:/tmp/uwsgi_web.sock;
}
}
Notice the appending / in location block for static
Last thing, make sure that application server is running with DEBUG as False

The issue was that I had placed my own nginx.conf in /usr/local/etc/nginx/sites-enabled, not /usr/local/etc/nginx/servers. In /usr/local/etc/nginx/nginx.conf, include servers/*; is at the end. Therefore, UWSGI was still serving the static files. I followed the django-nginx-uwsgi tutorial, and I assumed I had to create a new sites-enabled directory. I am using OS X.
I see on Linux, though, /etc/nginx/nginx.conf has include include /etc/nginx/sites-enabled/*; at the end, so the steps in the tutorial are applicable on Linux.
The extra / at the end of /static doesn't make a difference, but it doesn't hurt to have it at the end of all paths.

Related

Django + Nginx save uploded file to other server and reverse file

I have 2 servers: first for Nginx and Django and second server for storage
Nginx and app server IP: 192.168.1.1
storage server IP: 192.168.1.2
Nginx installed on two servers.
In Django config media path:
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
MEDIA_URL = '/media/'
Nginx config is in the first server:
server {
listen 80;
server_name 192.168.1.1;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log ;
location = /favicon.ico { access_log off; log_not_found off; }
location /media/ {
proxy_pass http://192.168.1.2/;
}
location / {
uwsgi_pass unix:/tmp/uwsgi/app.sock;
include uwsgi_params;
}
location /static/ {
alias /home/ubuntu/app/static/;
}
}
and storage server Nginx config:
server {
listen 80;
server_name 192.168.1.2;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log ;
location /media/ {
alias /home/ubuntu/app/media;
}
}
Questions:
How can Django save (upload file) to the storage server (192.168.1.2)?
better if suggest solutions with minimum changes in code.
How Nginx can reverse files from a storage server?
the end user just typing 192.168.1.1
Solution 1: Network File System (NFS)
An example of NFS is GlusterFS.
What it does is, it makes multiple disks or servers available as a single directory. So you can configure it to show your other server as media directory and any files you put in there, it will be automatically stored in your other server. And you can fetch those files as if they are in the media directory even though they are on another machine. No changes required to your django code, or nginx config.
Solution 2: Custom File Storage backend
Another solution is to write your own File Storage backend and save the images to your second server from there. In fact, there's a library called django-storages which supports uploading files to another server using FTP. See docs: http://django-storages.readthedocs.io/en/latest/backends/ftp.html
Personally, second solution seems better to me because you don't really need NFS right now. And even if you do later on, you can install Gluster on your second server and scale out from there.

Is it necessary to include sites-enabled directory within nginx.conf?

I am following Setting up Django and your web server with uWSGI and nginx tutorial. I was stuck on part Configure nginx for your site. I tried everything that I have found searching the internet, mainly I was trying to fix my config mysite_nginx.conf file, but it seems now that it was correct all the time.
This is my config file mysite_nginx.conf which of course is symlinked from /usr/local/etc/nginx/sites-enabled/.
# mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
server 127.0.0.1:8001;
}
# configuration of the server
server {
listen 8000;
server_name localhost;
charset utf-8;
client_max_body_size 75M;
location /media {
alias /Users/username/dev/my_site/mysite/media;
}
location /static {
alias /Users/username/dev/my_site/mysite/static;
}
location / {
uwsgi_pass django;
include /Users/username/dev/my_site/mysite/uwsgi_params;
}
}
The problem I faced
Visiting localhost:8000/media/img.jpg or localhost:8000/static/img.jpg always was returning 404 Not Found. In nginx logs all of the requests were mapped to /usr/local/Cellar/nginx/version/html/ which is a symlink to the /usr/local/var/www/ where index.html and 5xx.html files are present.
My static/ and media/ were added to the /usr/local/Cellar/nginx/version/html/ so in nginx error logs I saw requests to /usr/local/Cellar/nginx/version/html/static/img.jpg.
The solution that worked for me
In nginx.conf file I have included path to the sites-enabled. After this all of my requests where mapped to the absolute paths that I have added as an alias of the location and everything worked as expected.
...
http {
include mime.types;
include /usr/local/etc/nginx/sites-enabled/*.conf;
default_type application/octet-stream;
...
The Question
In the tutorial that I mentioned there was no mention about this, so I suppose it should work without editing nginx.conf file? But it didn't worked for me, am I missing something?
First of all there is no restriction or necessity to follow one approach. You can have all your config in a single nginx.conf or you can split it into multiple files and include them, or you can include specific patterns from a directory.
Different OS distribution may use different config type of default config setup. The common one being usage of a nginx.conf using include site-enabled/*.conf; and include conf-enabled/*.conf;
The logic is that your create your actual config in sites-available and conf-available directory and you just symlink them in the sites-enabled and conf-enabled directory respectively. So tomorrow if you want to disable a config then instead of renaming or deleting it you just delete the symlink from xxxx-enabled directory. This is just a convention so it easier for you to manage virtual hosts related to different sites in their own files.
By default these have some default configs which are for the demo nginx page. Before setting up your config you should disable this, so that it doesn't mess up with your config.
Now sometimes the include may not be part of the default nginx.conf. Because you installed nginx using brew the config used in that installation is different. If you check the file it has below include
include servers/*;
So the expectation is to put it at different place. So you have to be aware that the base config is nginx.conf (that also can be changed by compiling nginx from source). It can then include other configs or choose not to and just have a default server in nginx.conf itself. Before following any tutorial do read your nginx.conf file first.

Django to serve static files with exceptions

In my production environment I have Nginx serving static files for my Django application, but while developing I let Django so the work.
I need to have Nginx serving all static files but those in a certain subdirectory. So, Django side, I need to intercept that directory and treat it differently.
How can I make Django dev server intercept all the calls to /static/* but not those to /static/myspecialfiles/*´ and hence write a url route to handle the GET calls to said/static/myspecialfiles/*´?
You need to tackle this in two areas, Django and nginx.
For Django, since running a local setup (when DEBUG=True) already serves static content from STATIC_ROOT automatically, just add a URL conf for your special files:
# in urls.py
url(r'^/static/specialfiles/', SpecialView.as_view(), name='special'),
Then, in your nginx conf, make sure you ignore that path so it actually reaches Django:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:8000;
}
location /static/specialfiles/ {
proxy_pass http://localhost:8000;
}
location /static/ {
alias /home/ubuntu/dev/example/static/;
}
}
Since the locations are parsed sequentially, your special files will hit the django block before the generic static block.
But really you'd be best to just move your special files somewhere else.

Nginx is not serving Django static files

I just configured my first django server for a very basic django-website. I'm using Django 1.4 and Nginx 1.0.14 with supervisor and gunicorn.
The problem is that Nginx is not serving the static files as suposed, but I don't know the why because is my first time using it.
This is the path where really lives my static files:
/home/cristian/envs/santalupe.com/santalupe/santalupe/static
And this is the setting I've in my nginx config file:
# Django admin media.
location /media/ {
autoindex on;
alias /home/cristian/envs/santalupe.com/lib/python2.7/site-packages/django/contrib/admin/static/;
}
# Site media
location /static/ {
autoindex on;
alias /home/cristian/envs/santalupe.com/santalupe/santalupe/static/;
}
Please let me know what I need to do in this case because I have not idea about the real problem.
You aren't serving the admin media from Nginx, just normal media. Try something like:
location /admin/media/ {
# this changes depending on your python version
root /home/cristian/envs/santalupe.com/lib/python2.7/site-packages/django/contrib;
}
Note how there's no trailing slash and the path ends at contrib. I'm using almost exactly this code successfully in production.
Maybe manage.py collectstatic on server help you?
Here is good description on right solution https://docs.djangoproject.com/en/dev/howto/static-files/#serving-static-files-in-production

Add expires header to django with nginx

I use django_compress to compress my static files. All static files are collected under /static/ url using collectstatic command. Now I want to add expires headers to this files. There is no problem to do this with apache, but when I add to my nginx.conf:
location /static/ {
root /home/user/proj/static;
expires 7d;
}
and restart the server then static files are not served. What should I change?
The location is under server context.
Refs http://wiki.nginx.org/HttpCoreModule#root, a request such as http://yourserver/static/foo will be directed to /home/user/proj/static/static/foo . Is the static/static right structure on you server?
Also run nginx -t to ensure there is no error in configuration, before reload nginx.