I am trying to serve protected media files with Nginx sendfile and X-Accel-Redirect using Django 2.0.
This is my Nginx configuration:
server {
listen 8000;
server_name localhost;
charset utf-8;
sendfile on;
# Protected media
location /protected {
internal;
alias /Users/username/Documents/sat23/venv/media/;
}
# Django static
location /static {
alias /Users/username/Documents/sat23/venv/static/;
}
# All other requests.
location / {
uwsgi_pass django;
include /Users/username/Documents/sat23/venv/uwsgi_params;
}
}
Then in my urls.py I added a simple view that should serve my media files (I'll configure permissions later):
def serveMedia(request):
url = request.path.replace('media', 'protected')
response = HttpResponse('')
response['X-Accel-Redirect'] = url
response['Content-Type'] = ''
return response
urlpatterns += [
path('/media/', serveMedia, name='protected_media')
]
However whenever I call localhost:8000/media/users/user35.jpg, I just get a Django (not nginx) 404 page, saying that Django tried all the configured paths and it couldn't find the requested one.
So I had a suspicion that my view just doesn't work. I then rewrote it like this:
def serveMedia(request):
return HttpResponse(content=b'Hello there')
And sure enough it doesn't get called. But I have no idea why. Could someone help me out?
P.S. Any recommendations on configuring nginx conf are also very welcome!
There are no capturing groups in your Django path call there, so that will only match /media/ verbatim.
You might want to use the old-school url route with a regexp like
urlpatterns += [
url(r'/media/.+', serveMedia),
]
to capture everything that starts with /media/
Related
I'm using Django 1.10 + uWsgi + nginx.
In Prod mode the static files do not show up, this is what my nginx error-log tells me:
404 ... static/CACHE/js/e3a6fa7588d1.js" failed (2: No such file or directory),
The folder static/CACHE remains empty (so the 404's make sense), but why?
I already set the permissions to 775 for static/CACHE .
nginx conf:
# /etc/nginx/sites/available/mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream bdjango {
server unix:///tmp/mysite.sock; # for a file socket
}
# configuration of the server
server {
# the port your site will be served on
listen 80;
# the domain name it will serve for
server_name dev.mysite.com; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 8M; # adjust to taste
# Django media
location /media {
alias /var/www/mysite/src/media; # your Django project's media files - amend as required
}
location /static {
alias /var/www/mysite/src/static; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass adjango;
include /var/www/mysite/src/uwsgi_params; # the uwsgi_params file you installed
}
}
Django settings contains
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__) + "../../../")
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')
So, why are my js/css files not in static/CACHE ?
EDIT:
solved it: uwsgi_pass was pointing at the wrong upstream location (which happened to be a different website):
uwsgi_pass adjango;
Are you using CACHE?
Have you defiened STATIC_URL and STATIC_ROOT correctly.
Is DEBUG = False?
Are you using any 3rd party tool to cache/pipline your static files?
It could be that django-compressor is failing.
Have you tried having DEBUG = True and COMPRESS_ENABLED = True in your settings and seeing if it works?
https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_ENABLED
Alternatively, I suggest having ADMINS setup in production so it emails you any errors, or setup sentry in your production setup.
Edit: I've made some progress trouble shooting this issue. For an update on the situation, read the comments and view this post on ServerFault:
https://serverfault.com/questions/690836/django-uwsgi-nginx-not-serving-media-files-django-returns-404-status-code?noredirect=1#comment851441_690836
I'm following this tutorial:
http://uwsgi-docs.readthedocs.org/en/latest/tutorials/Django_and_nginx.html
Everything was going well until I reached the "Basic nginx test" section. When I stopped and started nginx and then added "media.png" to my media folder and went to
192.168.***.***:8000/media/media.png
it gave me a 404 status code. Note that this status code was given by Django (DEBUG=True), so it says:
Page not found (404)
Request Method: GET
Request URL: http://192.168.***.***:8000/media/media.png
Using the URLconf defined in CMS.urls, Django tried these URL patterns, in this order:
This is mysite_nginx.conf:
# mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 8000;
# the domain name it will serve for
server_name 192.168.***.***; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /home/a/Documents/media; # your Django project's media files - amend as required
}
location /static {
alias /home/a/Documents/CMS/CMSApp/static; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /home/a/Documents/CMS/CMS/uwsgi_params; # the uwsgi_params file you installed
}
}
Any idea why I'm getting a 404 error when trying to view the media file?
Additional information: When I go to
http://192.168.***.***:8001/media/media.png
or
127.0.0.1:8001
it says "This web page is not available".
Is it possible to run Django and Wordpress on the same server? I have seen other examples where its possible if / is handled by django and /blog/ by wordpress but how about
/api/ -- eg. api/v1/user/show
/signin/,
/create/,
/dashboard/ -- eg. dashboard/reports/
By Django and
/
/about/
/security/
/contact/
/tos/
/privacy/
/faq/
/contact/
etc with Wordpress?
Yes, it is possible as far as I know if you're using nginx and uwsgi, you can config nginx like this:
upstream django {
server unix:/path/to/your/django/project/your.sock; # for a file socket
}
server {
location /about{
proxy_pass http://127.0.0.1:8080;# where your wordpress run
}
location /secirity{
proxy_pass http://127.0.0.1:8080;# where your wordpress run
}
# other url needed to handle by wordpress
# left are all handled by django
location / {
uwsgi_pass django;
include /path/to/your/django/project/uwsgi_params; # the uwsgi_params file you installed
}
}
I am serving images processed by my django server using the x-accel-redirec header and Nginx. However, the behavior is really odd as sometimes I get the image, and sometimes Nginx redirects the image URI to my Django (uwsgi) application and I get, of course, a 404. My config is as follows:
upstream django {
server unix:///tmp/django.sock;
}
server {
listen 80;
server_name website.dev;
# max upload size
client_max_body_size 75M; # adjust to taste
location /images/ {
internal;
alias /home/bob/images/;
}
location / {
uwsgi_pass django;
include /home/bob/django_website/uwsgi_params;
}
}
This behavior happens with the same URL when I refresh several times. When I get the 404 error message from Django it says: "The current URL, home/bob/images/image3.jpg, didn't match any of these."
In apache with mod_xsendfile it was working perfectly.
Please help
Right now, I'm trying to follow this tutorial:
http://honza.ca/2011/05/deploying-django-with-nginx-and-gunicorn
The template site loads correctly, but the images don't load. Here is part of my config.py file for my application:
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = ''
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = ''
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = '/home/lilo/textImageSite/imageSite/static/'
# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
My nginx config file (located at /etc/nginx/sites-enabled):
server {
listen 80;
server_name xxx.xx.xx.xx; #the actual IP of the server; it has a public IP address
access_log /home/lilo/textImageSite/access.log;
error_log /home/lilo/textImageSite/error.log;
location /static {
root /home/lilo/textImageSite/imageSite;
}
location / {
proxy_pass http://127.0.0.1:8888;
}
}
My gunicorn_conf file:
bind = "0.0.0.0:8888"
logfile = "/home/lilo/textImageSite/gunicorn.log"
workers = 3
And right now in my template, this is how I'm accessing the image:
<img src="{{STATIC_URL}}{{ choice.image_location}}" /> <br />
Here is what the generated HTML looks like:
<img src="/static/street_sign2.jpg" /> <br />
Sorry for the wall of text, but I can't figure out what's wrong with my setup...
Turns out I fixed my own problem... misunderstood how Nginx worked. :D
server {
listen 1234; //port that Nginx listens on
server_name xxx.xx.xx.xx; #the actual IP of the server; it has a public IP address
access_log /home/lilo/textImageSite/access.log;
error_log /home/lilo/textImageSite/error.log;
location /static {
root /home/lilo/textImageSite/imageSite;
}
location / {
proxy_pass http://127.0.0.1:8888; //the port that Gunicorn uses
}
}
So in my case, if I have my Gunicorn instance running on port 8888, then going to xxx.xxx.xx.x:8888/textImageSite would load the page, but without any static content. If I access it using xxx.xxx.xx.x:1234, then the page will load the static content (images, css style sheets etc). It's my first time using Gunicorn and Nginx (and first time writing a Django app too) so hopefully this will help someone who's confused :)
#make the following changes
#settings.py
STATIC_ROOT = os.path.join(BASE_DIR,'static')
STATIC_URL = '/static/'
#etc/nginx/sites-enabled
server {
listen 80;
server_name xxx.xx.xx.xx;
access_log /home/lilo/textImageSite/access.log;
error_log /home/lilo/textImageSite/error.log;
location /static {
root /home/lilo/textImageSite/imageSite;
}
location / {
proxy_pass http://127.0.0.1:8888;
}
}
#/etc/nginx/nginx.conf
user your_user_name;