mirror of
https://github.com/jazzband/django-downloadview.git
synced 2026-03-16 22:40:25 +00:00
192 lines
4.8 KiB
Text
192 lines
4.8 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
|
|
****************************
|
|
|
|
Let's start in the situation described in the :doc:`demo application </demo>`:
|
|
|
|
* a project "demoproject"
|
|
* an application "demoproject.download"
|
|
* a :py:class:`django_downloadview.views.ObjectDownloadView` view serves files
|
|
of a "Document" model.
|
|
|
|
We are to make it more efficient with Nginx.
|
|
|
|
.. note::
|
|
|
|
Examples below are taken from the :doc:`demo project </demo>`.
|
|
|
|
|
|
***********
|
|
Write tests
|
|
***********
|
|
|
|
Use :py:func:`django_downloadview.nginx.assert_x_accel_redirect` function as
|
|
a shortcut in your tests.
|
|
|
|
:file:`demo/demoproject/nginx/tests.py`:
|
|
|
|
.. literalinclude:: ../../demo/demoproject/nginx/tests.py
|
|
:language: python
|
|
:emphasize-lines: 5, 25-34
|
|
|
|
Right now, this test should fail, since you haven't implemented the view yet.
|
|
|
|
|
|
************
|
|
Setup Django
|
|
************
|
|
|
|
At the end of this setup, the test should pass, but you still have to `setup
|
|
Nginx`_!
|
|
|
|
You have two options: global setup with a middleware, or per-view setup with
|
|
decorators.
|
|
|
|
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 = MEDIA_ROOT # Could be elsewhere.
|
|
NGINX_DOWNLOAD_MIDDLEWARE_MEDIA_URL = '/proxied-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.
|
|
|
|
:file:`demo/demoproject/nginx/views.py`:
|
|
|
|
.. literalinclude:: ../../demo/demoproject/nginx/views.py
|
|
:language: python
|
|
|
|
And use it in som URL conf, as an example in
|
|
:file:`demo/demoproject/nginx/urls.py`:
|
|
|
|
.. literalinclude:: ../../demo/demoproject/nginx/urls.py
|
|
:language: python
|
|
|
|
.. note::
|
|
|
|
In real life, you'd certainly want to replace the "download_document" view
|
|
instead of registering a new view.
|
|
|
|
|
|
***********
|
|
Setup 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 /proxied-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::
|
|
|
|
``/proxied-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.
|
|
|
|
|
|
*************
|
|
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
|