mirror of
https://github.com/jazzband/django-downloadview.git
synced 2026-03-16 22:40:25 +00:00
222 lines
5.7 KiB
Text
222 lines
5.7 KiB
Text
#####
|
|
Nginx
|
|
#####
|
|
|
|
If you serve Django behind Nginx, then you can delegate the file download
|
|
service to Nginx and get increased performance:
|
|
|
|
* lower resources used by Python/Django workers ;
|
|
* faster download.
|
|
|
|
See `Nginx X-accel documentation`_ for details.
|
|
|
|
|
|
****************************
|
|
Configure some download view
|
|
****************************
|
|
|
|
As an example, let's consider an application called "myapp".
|
|
|
|
:file:`settings.py`:
|
|
|
|
.. code-block:: python
|
|
|
|
INSTALLED_APPS = (
|
|
# ...
|
|
'myapp',
|
|
# ...
|
|
)
|
|
MYAPP_STORAGE_LOCATION = '/var/www/files/' # Could be MEDIA_ROOT for public
|
|
# files.
|
|
|
|
This application holds a ``Document`` model.
|
|
|
|
:file:`myapp/models.py`:
|
|
|
|
.. code-block:: python
|
|
|
|
from django.conf import settings
|
|
from django.core.files.storage import FileSystemStorage
|
|
from django.db import models
|
|
|
|
|
|
storage = FileSystemStorage(location=settings.MYAPP_STORAGE_LOCATION)
|
|
|
|
|
|
class Document(models.Model):
|
|
file = models.FileField(storage=storage, upload_to='document')
|
|
|
|
Notice the ``storage`` and ``upload_to`` parameters: files for ``Document``
|
|
model live in :file:`/var/www/files/document/` folder.
|
|
|
|
Then we configured a download view for this model, restricted to authenticated
|
|
users:
|
|
|
|
:file:`myapp/urls.py`:
|
|
|
|
.. code-block:: python
|
|
|
|
from django.conf.urls import url, url_patterns
|
|
from django.contrib.auth.decorators import login_required
|
|
|
|
from django_downloadview import ObjectDownloadView
|
|
|
|
from myapp.models import Document
|
|
|
|
|
|
download = login_required(ObjectDownloadView.as_view(model=Document))
|
|
|
|
url_patterns = ('',
|
|
url('^document/(?P<pk>[0-9]+/download/$', download, name='download'),
|
|
)
|
|
|
|
As is, Django is to serve the files, i.e. load chunks into memory and stream
|
|
them.
|
|
|
|
Nginx is much more efficient for the actual streaming... Let's use it!
|
|
|
|
|
|
***************
|
|
Configure Nginx
|
|
***************
|
|
|
|
See `Nginx X-accel documentation`_ for details.
|
|
|
|
Here is what you could have in :file:`/etc/nginx/sites-available/default`:
|
|
|
|
.. code-block:: nginx
|
|
|
|
charset utf-8;
|
|
|
|
# Django-powered service.
|
|
upstream frontend {
|
|
server 127.0.0.1:8000 fail_timeout=0;
|
|
}
|
|
|
|
server {
|
|
listen 80 default;
|
|
|
|
# File-download proxy.
|
|
#
|
|
# Will serve /var/www/files/myfile.tar.gz when passed URI
|
|
# like /optimized-download/myfile.tar.gz
|
|
#
|
|
# See http://wiki.nginx.org/X-accel
|
|
# and https://github.com/benoitbryon/django-downloadview
|
|
location /optimized-download {
|
|
internal;
|
|
# Location to files on disk.
|
|
# See Django's settings.NGINX_DOWNLOAD_MIDDLEWARE_MEDIA_ROOT
|
|
alias /var/www/files/;
|
|
}
|
|
|
|
# Proxy to Django-powered frontend.
|
|
location / {
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header Host $http_host;
|
|
proxy_redirect off;
|
|
proxy_pass http://frontend;
|
|
}
|
|
}
|
|
|
|
... where specific configuration is the ``location /optimized-download``
|
|
section.
|
|
|
|
.. note::
|
|
|
|
``/optimized-download`` is not available for the client, i.e. users
|
|
won't be able to download files via ``/optimized-download/<filename>``.
|
|
|
|
.. warning::
|
|
|
|
Make sure Nginx can read the files to download! Check permissions.
|
|
|
|
|
|
************************************************
|
|
Global delegation, with XAccelRedirectMiddleware
|
|
************************************************
|
|
|
|
If you want to delegate all file downloads to Nginx, then use
|
|
:py:class:`django_downloadview.nginx.XAccelRedirectMiddleware`.
|
|
|
|
Register it in your settings:
|
|
|
|
.. code-block:: python
|
|
|
|
MIDDLEWARE_CLASSES = (
|
|
# ...
|
|
'django_downloadview.nginx.XAccelRedirectMiddleware',
|
|
# ...
|
|
)
|
|
|
|
Setup the middleware:
|
|
|
|
.. code-block:: python
|
|
|
|
NGINX_DOWNLOAD_MIDDLEWARE_MEDIA_ROOT = MYAPP_STORAGE_LOCATION
|
|
NGINX_DOWNLOAD_MIDDLEWARE_MEDIA_URL = '/optimized-download'
|
|
|
|
Optionally fine-tune the middleware. Default values are ``None``, which means
|
|
"use Nginx's defaults".
|
|
|
|
.. code-block:: python
|
|
|
|
NGINX_DOWNLOAD_MIDDLEWARE_EXPIRES = False # Force no expiration.
|
|
NGINX_DOWNLOAD_MIDDLEWARE_WITH_BUFFERING = False # Force buffering off.
|
|
NGINX_DOWNLOAD_MIDDLEWARE_LIMIT_RATE = False # Force limit rate off.
|
|
|
|
|
|
*************************************************
|
|
Local delegation, with x_accel_redirect decorator
|
|
*************************************************
|
|
|
|
If you want to delegate file downloads to Nginx on a per-view basis, then use
|
|
:py:func:`django_downloadview.nginx.x_accel_redirect` decorator.
|
|
|
|
Adapt :file:`myapp/urls.py`:
|
|
|
|
.. code-block:: diff
|
|
|
|
from django.conf.urls import url, url_patterns
|
|
from django.contrib.auth.decorators import login_required
|
|
|
|
from django_downloadview import ObjectDownloadView
|
|
+ from django_downloadview.nginx import x_accel_redirect
|
|
|
|
from myapp.models import Document
|
|
|
|
|
|
download = login_required(ObjectDownloadView.as_view(model=Document))
|
|
+ download = x_accel_redirect(download,
|
|
+ media_root=settings.MY_APP_STORAGE_LOCATION,
|
|
+ media_url='/optimized-download')
|
|
|
|
url_patterns = ('',
|
|
url('^document/(?P<pk>[0-9]+/download/$', download, name='download'),
|
|
)
|
|
|
|
|
|
*************
|
|
Common issues
|
|
*************
|
|
|
|
``Unknown charset "utf-8" to override``
|
|
=======================================
|
|
|
|
Add ``charset utf-8;`` in your nginx configuration file.
|
|
|
|
``open() "path/to/something" failed (2: No such file or directory)``
|
|
====================================================================
|
|
|
|
Check your ``settings.NGINX_DOWNLOAD_MIDDLEWARE_MEDIA_ROOT`` in Django
|
|
configuration VS ``alias`` in nginx configuration: in a standard configuration,
|
|
they should be equal.
|
|
|
|
|
|
**********
|
|
References
|
|
**********
|
|
|
|
.. target-notes::
|
|
|
|
.. _`Nginx X-accel documentation`: http://wiki.nginx.org/X-accel
|