123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- ====================
- Deployment checklist
- ====================
- The internet is a hostile environment. Before deploying your Django project,
- you should take some time to review your settings, with security, performance,
- and operations in mind.
- Django includes many :doc:`security features </topics/security>`. Some are
- built-in and always enabled. Others are optional because they aren't always
- appropriate, or because they're inconvenient for development. For example,
- forcing HTTPS may not be suitable for all websites, and it's impractical for
- local development.
- Performance optimizations are another category of trade-offs with convenience.
- For instance, caching is useful in production, less so for local development.
- Error reporting needs are also widely different.
- The following checklist includes settings that:
- - must be set properly for Django to provide the expected level of security;
- - are expected to be different in each environment;
- - enable optional security features;
- - enable performance optimizations;
- - provide error reporting.
- Many of these settings are sensitive and should be treated as confidential. If
- you're releasing the source code for your project, a common practice is to
- publish suitable settings for development, and to use a private settings
- module for production.
- Run ``manage.py check --deploy``
- ================================
- Some of the checks described below can be automated using the :option:`check
- --deploy` option. Be sure to run it against your production settings file as
- described in the option's documentation.
- Switch away from ``manage.py runserver``
- ========================================
- The :djadmin:`runserver` command is not designed for a production setting. Be
- sure to switch to a production-ready WSGI or ASGI server. For a few common
- options, see :doc:`WSGI servers </howto/deployment/wsgi/index>` or
- :doc:`ASGI servers </howto/deployment/asgi/index>`.
- Critical settings
- =================
- :setting:`SECRET_KEY`
- ---------------------
- **The secret key must be a large random value and it must be kept secret.**
- Make sure that the key used in production isn't used anywhere else and avoid
- committing it to source control. This reduces the number of vectors from which
- an attacker may acquire the key.
- Instead of hardcoding the secret key in your settings module, consider loading
- it from an environment variable::
- import os
- SECRET_KEY = os.environ["SECRET_KEY"]
- or from a file::
- with open("/etc/secret_key.txt") as f:
- SECRET_KEY = f.read().strip()
- If rotating secret keys, you may use :setting:`SECRET_KEY_FALLBACKS`::
- import os
- SECRET_KEY = os.environ["CURRENT_SECRET_KEY"]
- SECRET_KEY_FALLBACKS = [
- os.environ["OLD_SECRET_KEY"],
- ]
- Ensure that old secret keys are removed from ``SECRET_KEY_FALLBACKS`` in a
- timely manner.
- :setting:`DEBUG`
- ----------------
- **You must never enable debug in production.**
- You're certainly developing your project with :setting:`DEBUG = True <DEBUG>`,
- since this enables handy features like full tracebacks in your browser.
- For a production environment, though, this is a really bad idea, because it
- leaks lots of information about your project: excerpts of your source code,
- local variables, settings, libraries used, etc.
- Environment-specific settings
- =============================
- :setting:`ALLOWED_HOSTS`
- ------------------------
- When :setting:`DEBUG = False <DEBUG>`, Django doesn't work at all without a
- suitable value for :setting:`ALLOWED_HOSTS`.
- This setting is required to protect your site against some CSRF attacks. If
- you use a wildcard, you must perform your own validation of the ``Host`` HTTP
- header, or otherwise ensure that you aren't vulnerable to this category of
- attacks.
- You should also configure the web server that sits in front of Django to
- validate the host. It should respond with a static error page or ignore
- requests for incorrect hosts instead of forwarding the request to Django. This
- way you'll avoid spurious errors in your Django logs (or emails if you have
- error reporting configured that way). For example, on nginx you might set up a
- default server to return "444 No Response" on an unrecognized host:
- .. code-block:: nginx
- server {
- listen 80 default_server;
- return 444;
- }
- :setting:`CACHES`
- -----------------
- If you're using a cache, connection parameters may be different in development
- and in production. Django defaults to per-process :ref:`local-memory caching
- <local-memory-caching>` which may not be desirable.
- Cache servers often have weak authentication. Make sure they only accept
- connections from your application servers.
- :setting:`DATABASES`
- --------------------
- Database connection parameters are probably different in development and in
- production.
- Database passwords are very sensitive. You should protect them exactly like
- :setting:`SECRET_KEY`.
- For maximum security, make sure database servers only accept connections from
- your application servers.
- If you haven't set up backups for your database, do it right now!
- :setting:`EMAIL_BACKEND` and related settings
- ---------------------------------------------
- If your site sends emails, these values need to be set correctly.
- By default, Django sends email from webmaster@localhost and root@localhost.
- However, some mail providers reject email from these addresses. To use
- different sender addresses, modify the :setting:`DEFAULT_FROM_EMAIL` and
- :setting:`SERVER_EMAIL` settings.
- :setting:`STATIC_ROOT` and :setting:`STATIC_URL`
- ------------------------------------------------
- Static files are automatically served by the development server. In
- production, you must define a :setting:`STATIC_ROOT` directory where
- :djadmin:`collectstatic` will copy them.
- See :doc:`/howto/static-files/index` for more information.
- :setting:`MEDIA_ROOT` and :setting:`MEDIA_URL`
- ----------------------------------------------
- Media files are uploaded by your users. They're untrusted! Make sure your web
- server never attempts to interpret them. For instance, if a user uploads a
- ``.php`` file, the web server shouldn't execute it.
- Now is a good time to check your backup strategy for these files.
- HTTPS
- =====
- Any website which allows users to log in should enforce site-wide HTTPS to
- avoid transmitting access tokens in clear. In Django, access tokens include
- the login/password, the session cookie, and password reset tokens. (You can't
- do much to protect password reset tokens if you're sending them by email.)
- Protecting sensitive areas such as the user account or the admin isn't
- sufficient, because the same session cookie is used for HTTP and HTTPS. Your
- web server must redirect all HTTP traffic to HTTPS, and only transmit HTTPS
- requests to Django.
- Once you've set up HTTPS, enable the following settings.
- :setting:`CSRF_COOKIE_SECURE`
- -----------------------------
- Set this to ``True`` to avoid transmitting the CSRF cookie over HTTP
- accidentally.
- :setting:`SESSION_COOKIE_SECURE`
- --------------------------------
- Set this to ``True`` to avoid transmitting the session cookie over HTTP
- accidentally.
- Performance optimizations
- =========================
- Setting :setting:`DEBUG = False <DEBUG>` disables several features that are
- only useful in development. In addition, you can tune the following settings.
- Sessions
- --------
- Consider using :ref:`cached sessions <cached-sessions-backend>` to improve
- performance.
- If using database-backed sessions, regularly :ref:`clear old sessions
- <clearing-the-session-store>` to avoid storing unnecessary data.
- :setting:`CONN_MAX_AGE`
- -----------------------
- Enabling :ref:`persistent database connections
- <persistent-database-connections>` can result in a nice speed-up when
- connecting to the database accounts for a significant part of the request
- processing time.
- This helps a lot on virtualized hosts with limited network performance.
- :setting:`TEMPLATES`
- --------------------
- Enabling the cached template loader often improves performance drastically, as
- it avoids compiling each template every time it needs to be rendered. When
- :setting:`DEBUG = False <DEBUG>`, the cached template loader is enabled
- automatically. See :class:`django.template.loaders.cached.Loader` for more
- information.
- Error reporting
- ===============
- By the time you push your code to production, it's hopefully robust, but you
- can't rule out unexpected errors. Thankfully, Django can capture errors and
- notify you accordingly.
- :setting:`LOGGING`
- ------------------
- Review your logging configuration before putting your website in production,
- and check that it works as expected as soon as you have received some traffic.
- See :doc:`/topics/logging` for details on logging.
- :setting:`ADMINS` and :setting:`MANAGERS`
- -----------------------------------------
- :setting:`ADMINS` will be notified of 500 errors by email.
- :setting:`MANAGERS` will be notified of 404 errors.
- :setting:`IGNORABLE_404_URLS` can help filter out spurious reports.
- See :doc:`/howto/error-reporting` for details on error reporting by email.
- .. admonition:: Error reporting by email doesn't scale very well
- Consider using an error monitoring system such as Sentry_ before your
- inbox is flooded by reports. Sentry can also aggregate logs.
- .. _Sentry: https://docs.sentry.io/
- Customize the default error views
- ---------------------------------
- Django includes default views and templates for several HTTP error codes. You
- may want to override the default templates by creating the following templates
- in your root template directory: ``404.html``, ``500.html``, ``403.html``, and
- ``400.html``. The :ref:`default error views <error-views>` that use these
- templates should suffice for 99% of web applications, but you can
- :ref:`customize them <customizing-error-views>` as well.
|