Setting up Django for Production - 1

Learn via video courses
Topics Covered

Overview

There are many shortcuts in Django to make the lives of web developers more accessible, but none of those tools is helpful if you can't quickly deploy your sites. The goal of Django has been to make deployment simple.

Based on your architecture or your unique business requirements, you have a wide range of deployment options for your Django application, but Django cannot advise you on this topic.

Being a web framework, Django requires a web server to function. And because Python isn't a native language of most web servers, we need an interface to enable communication.

How to Deploy with WSGI?

The Python web server and application standard, WSGI, serves as the primary deployment platform for Django.

You can use any WSGI-compliant application server by instructing it to use the start project management command in Django, which creates a basic default WSGI configuration for you to customize as needed for your project.

Finally, we'll go over applying WSGI middleware and configuring the settings module step-by-step.

How to Use Django with Gunicorn?

A pure-Python WSGI server for UNIX is called (also known as "Green Unicorn"). pip can be used to install it, and it has no dependencies.

Installing Gunicorn

Run the command python -m pip install gunicorn to install the package.

Using Gunicorn's generic WSGI Application to Run Django

A unicorn command that launches the Gunicorn server process is available once Gunicorn has been installed. The simplest way to use Gunicorn is to pass the URL of a module that contains the WSGI application object named application. This would look like this for a typical Django project.

gunicorn my project.wsgi

One process with one listening thread will be started at 127.0.0.1:8000. This command must be run from the same directory as your manage.py file in order to ensure that your project is on the Python path, which is the easiest way to do it.

How to Use Django with uWSGI?

A developer and system administrator-friendly application container server written entirely in C, uWSGI is quick and self-healing.

Prerequisite: uWSGI

Several installation processes are described in the uWSGI wiki. You can installl any version of uWSGI` with a single command by using pip, the Python package manager. Consider this:

uWSGI model

Client-server architecture is used by uWSGI. To serve dynamic content, a django-uwsgi "worker" process interacts with your web server (such as nginx or apache).

Setting up and Starting the Django uWSGI Server

The process configuration options supported by uWSGI are varied. See the uWSGI configuration manual.

The following command will launch an uWSGI server:

This assumes you have a WSGI application object and a module called mysite/wsgi.py in your top-level project package called mysite. This is the layout you'll get if you use a recent version of Django and the command django-admin startproject mysite (replacing my site with the name of your own project). You'll need to make this file if it doesn't already exist. For information on what should be in this file by default and what else you can add, refer to the How to Deploy with WSGI documentation.

Here, there are options specific to Django:

chdir: The location of the directory that included the mysite package, which must be on the Python import path.

module: The WSGI module that should be used is probably mysite.wsgi, which startproject generates.

env: At the very least, it ought to include DJANGO_SETTINGS_MODULE.

home: An optional route to the virtual environment for your project.

Ini configuration file shows an example:

Use of an example ini configuration file:

uwsgi --ini uwsgi.ini

For file uploads, fixing the UnicodeEncodeError

  • Ensure uWSGI is set up to accept non-ASCII file names by adding the following to your uwsgi.ini if you encounter a UnicodeEncodeError when uploading files with file names that do not contain ASCII characters.
  • Env = LANG = en_US.UTF-8
  • For information, consult the Files chapter of the Unicode reference manual.

How to Use Django with Apache and mod_wsgi?

A tried-and-true method for deploying Django into production is Apache and mod_wsgi.

Any Python WSGI application, including Django, can be hosted by mod_wsgi, an Apache module. As long as Apache supports mod_wsgi, Django will function.

Your go-to resource for all information on using mod_wsgi is the official mod_wsgi documentation. The installation and configuration documentation is where you should probably start.

Standard Configuration

Edit the httpd.conf file on your Apache server and add the following after installing and activating mod_wsgi.

The base URL path you wish to use to serve your application is indicated by the first bit in the WSGIScriptAlias line (/ denotes the root url), and the second bit specifies where on your system a "WSGI file" is located (see below), often inside of your project package (mysite in this example). This instructs Apache to use the WSGI application listed in that file to handle any requests that are lower than the specified URL.

Use WSGIPythonHome to add the path if you installed your project's Python dependencies inside of a virtual environment. For further information, refer to the mod wsgi virtual environment manual.

The WSGIPythonPath line makes sure that import mysiteis functional and that your project package is accessible for import on the Python path.

The <Directory> component makes sure that Apache can read your wsgi.py file.

  • When many Django sites are launched simultaneously in a single mod wsgi process, the settings of the first one to launch will be used by all of them. You can fix this by altering:
  • os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings")
  • in wsgi.py, to:
  • os.environ["DJANGO_SETTINGS_MODULE"] = "{{ project_name }}.settings"
  • Alternatively, run each site in its daemon process while utilizing mod_wsgi daemon mode.

Fixing UnicodeEncodeError for file uploads

  • Make sure Apache is set up to handle UTF-8 encoding if you encounter a UnicodeEncodeError when uploading or writing files that contain non-ASCII characters in the file names or content:
  • export LANG='en_US.UTF-8'
  • export LC_ALL='en_US.UTF-8'
  • This configuration should typically go in /etc/apache2/envvars.
  • Alternately, if you're using the mod_wsgi daemon mode, you can modify the WSGIDaemonProcess directive by adding the lang and locale options:
  • WSGIDaemonProcess example.com lang='en_US.UTF-8' locale='en_US.UTF-8'
  • Details can be found in the Unicode reference manual's Files section.

Using mod_wsgi daemon Mode

The recommended setting for utilizing mod wsgi is daemon mode (on non-Windows platforms). You must include the proper WSGIDaemonProcess and WSGIProcessGroup directives to construct the necessary daemon process group and assign the Django instance to execute in it. If you utilize utilized, you must also update the settings described above. Instead of using WSGIPythonPath, you must use the python-path option to WSGIDaemonProcess, as in the following example:

You can add WSGIScriptAlias to the settings above to serve your project from a subdirectory (in this case, https://example.com/mysite):

WSGIScriptAlias /mysite /path/to/mysite.com/mysite/wsgi.py process-group=example.com

Details on configuring daemon mode can be found in the official mod_wsgi documentation.

Serving files

Regardless of your web server, Django does not handle file serving on your behalf.

For serving media, we advise utilizing a different web server—one that isn't also running Django. Here are some excellent options:

  • Nginx
  • a streamlined variation of Apache

You can configure Apache to serve some URLs as static media and others utilizing the mod_wsgi interface to Django if serving media files within the same Apache VirtualHost as Django is your only option.

This example installs Django at the root of the website while serving static files for robots.txt, favicon.ico, and other content found in the /static/ and /media/ URL spaces. mod_wsgi will be utilized to serve all additional URLs:

Serving the Admin Files

The Django development server will automatically serve the static files for the admin app when django.contrib. static files are present in INSTALLED_APPS` (and any other installed apps). However, this is not the case when you employ any other server configuration. Setting up Apache, or whatever other web server you choose, is your responsibility to serve the admin files.

The Django distribution's (django/contrib/admin/static/admin) is where the admin files are located.

Although we strongly advise using django.contrib.staticfiles to manage the admin files (along with a web server as described in the preceding section; this requires using the collectstatic management command to gather the static files in STATIC_ROOT and afterward configuring your web server to serve STATIC_ROOT at STATIC_URL), here are three other options:

  • From your document root, generate a symbolic link toward the admin static files (your Apache configuration may need to include +FollowSymLinks for this).
  • To alias the correct URL to the true position of the admin files (likely STATIC URL + admin/), use an Alias directive, as shown above.
  • Please make a copy of the admin static files and place them in your Apache document root.

How to Authenticate against Django’s User Database from Apache?

You can set up Apache to authenticate against Django's authentication system directly because retaining multiple authentication databases in sync is a problem when working with Apache. mod_wsgi 2.0 and Apache >= 2.2 are needed for this. For illustration, you could:

  • Only serve static/media files directly from Apache to users who have been verified.
  • Verify Django users with specific permission for access to a Subversion repository.
  • Permit only specific users to access a WebDAV share made with mod_dav.

To utilize this default auth handler, your installed custom user model must support the is_active attribute. The relation 'groups' on your custom user must refer to a related object with a 'name' field if you want to use group-based authorization. If your customer cannot meet these requirements, you can also specify your unique mod_wsgi auth handler.

Authentication with mod_wsgi

The configurations below assume that just one Django application is running on your Apache instance, which is why WSGIApplicationGroup %{GLOBAL} is used. Kindly refer to the Defining Application Groups segment of the mod_wsgi docs for more information on this setting if you are running multiple Django applications.

Assume that mod_wsgi has been set up with Apache and that you have followed the instructions for installing and activating it.

After that, modify your Apache configuration to include a location that only authorized users should be able to access:

With the user name and password it receives from the prompt, the WSGIAuthUserScript directive instructs mod_wsgi to run the check_password function in the designated wsgi script. The WSGIAuthUserScript used in this example is the same as the WSGIScriptAlias used by django-admin startproject to define your application.

  • Using authentication with Apache 2.2
  • Do not forget to load mod_auth_basic and mod_authz_user.
  • These might be statically compiled into Apache, or you may need to use LoadModule in your httpd.conf to load them dynamically:
  • LoadModule auth_basic_module modules/mod_auth_basic.so
  • LoadModule authz_user_module modules/mod_authz_user.so

Finally, import the check_password function into your WSGI script mysite. wsgi to connect Apache authentication to your site's authentication mechanisms:

Users must now authenticate before making requests that start with the string /secret/.

Additional information and details about additional authentication options are available in the mod wsgi access control mechanisms documentation.

Authorization with mod_wsgi and Django Groups

Additionally, mod_wsgi offers the ability to limit access to a specific location to group members.

The Apache configuration in this situation should resemble:

A similar WSGI script called mysite. wig has been added to support the WSGIAuthGroupScriptdirective. Thegroups_for_user` function, which returns a list of groups to which the specified user belongs, also needs to be imported by wsgi.

from django.contrib.auth.handlers.modwsgi import check_password, groups_for_user

The "secret-agents" group membership is now a requirement for requests to /secret/.

The Application Object

The application callable, which is something the application server has used to communicate with your code, is the central idea of deploying with WSGI. It is frequently offered as an application-named object in a server-accessible Python module.

Such an application callable is created in the file <project name>/wsgi.py by the start project command.

It is utilized by the Django development server as well as real-world WSGI deployments.

The path to the application callable is obtained by WSGI servers from their configuration. The runserver command on the built-in Django server reads it from the WSGI_APPLICATION setting. It is pre-configured to be <project name>.wsgi.application, which directs users to the <project_name>/wsgi.py file's application callable, is used.

Configuring the Settings Module

Django must import the settings module as that is where your entire application is outlined and where it will be loaded by the WSGI server.

To find the correct settings module, Django uses the environment variable DJANGO_SETTINGS_MODULE. It needs to include the dotted path toward the settings module. Depending on how your settings are organizedd you might use a different value for production and development.

The default setting for this variable, if it isn't set, is mysite.settings, in which mysite is the title of your project. Runserver finds the default settings file in this manner by default.

When you run multiple Django sites in the same process, this doesn't work because environment variables are process-wide. mod_wsgi causes this to occur.

Use mod wsgi's daemon mode with each site running in a separate daemon process to get around this issue, or override the environment value by setting os.environ["DJANGO SETTINGS MODULE"] = "mysite.settings" in your wsgi.py file.

Applying WSGI Middleware

Wrapping the application object allows you to use WSGI middleware. The following lines, for instance, could be added to wsgi.py's bottom:

Suppose you wanted to combine a Django application with a WSGI application of another framework. In that case, you could also swap out the Django WSGI application for a custom WSGI application that is later delegated to the Django WSGI application.

Conclusion

  • WSGI and ASGI are the two interfaces that Django currently supports.
  • Although only supporting synchronous code, WSGI is the primary Python standard for establishing communication between web servers and applications.
  • Your Django site will be able to use asynchronous Python features and asynchronous Django features as they become available, thanks to the new, asynchronous-friendly ASGI standard.
  • Additionally, think about how your application will deal with static files and error reporting.
  • Finally, to make sure your configurations are appropriate before deploying your application to production, go through our deployment checklist.