Django doesn’t serve files itself; it leaves that job to whichever Web server you choose. We recommend using a separate Web server – i.e., one that’s not also running Django – for serving media. Here are some good choices:
- A stripped-down version of Apache
If, however, you have no option but to serve media files on the same Apache
VirtualHost as Django, you can set up Apache to serve some URLs as static media, and others using the
mod_wsgi interface to Django.
This example sets up Django at the site root, but explicitly serves
favicon.ico, any CSS file, and anything in the
/media/ URL space as a static file. All other URLs will be served using mod_wsgi:
If you are using a version of Apache older than 2.4, replace
Require all granted with
Allow from all and also add the line
Order deny,allow above it.
Serving The Admin Files
django.contrib.staticfiles is in
INSTALLED_APPS, the Django development server automatically serves the static files of the admin app (and any other installed apps). This is however not the case when you use any other server arrangement. You’re responsible for setting up Apache, or whichever Web server you’re using, to serve the admin files.
The admin files live in (
django/contrib/admin/static/admin) of the Django distribution. We strongly recommend using
django.contrib.staticfiles to handle the admin files (along with a Web server as outlined in the previous section; this means using the
collectstatic management command to collect the static files in
STATIC_ROOT, and then configuring your Web server to serve
STATIC_URL), but here are three other approaches:
- Create a symbolic link to the admin static files from within your document root (this may require
+FollowSymLinksin your Apache configuration).
- Use an
Aliasdirective, as demonstrated above, to alias the appropriate URL (probably
admin/) to the actual location of the admin files.
- Copy the admin static files so that they live within your Apache document root.
If You Get a Unicodeencodeerror
If you’re taking advantage of the internationalization features of Django and you intend to allow users to upload files, you must ensure that the environment used to start Apache is configured to accept non-ASCII file names. If your environment is not correctly configured, you will trigger
UnicodeEncodeError exceptions when calling functions like the ones in
os.path on filenames that contain non-ASCII characters.
To avoid these problems, the environment used to start Apache should contain settings analogous to the following:
Consult the documentation for your operating system for the appropriate syntax and location to put these configuration items;
/etc/apache2/envvars is a common location on Unix platforms. Once you have added these statements to your environment, restart Apache.
Serving Static Files in Production
The basic outline of putting static files into production is simple: run the
collectstatic command when static files change, then arrange for the collected static files directory (
STATIC_ROOT) to be moved to the static file server and served.
STATICFILES_STORAGE, files may need to be moved to a new location manually or the
post_process method of the
Storage class might take care of that.
Of course, as with all deployment tasks, the devil’s in the details. Every production setup will be a bit different, so you’ll need to adapt the basic outline to fit your needs.
Below are a few common patterns that might help.
Serving The Site and Your Static Files from the Same Server
If you want to serve your static files from the same server that’s already serving your site, the process may look something like:
- Push your code up to the deployment server.
- On the server, run
collectstaticto copy all the static files into
- Configure your web server to serve the files in
STATIC_ROOTunder the URL
You’ll probably want to automate this process, especially if you’ve got multiple web servers. There’s any number of ways to do this automation, but one option that many Django developers enjoy is Fabric.
Below, and in the following sections, we’ll show off a few example fabfiles (i.e. Fabric scripts) that automate these file deployment options. The syntax of a fabfile is fairly straightforward but won’t be covered here; consult Fabric’s documentation, for a complete explanation of the syntax. So, a fabfile to deploy static files to a couple of web servers might look something like:
Serving Static Files from a Dedicated Server
Most larger Django sites use a separate Web server – i.e., one that’s not also running Django – for serving static files. This server often runs a different type of web server – faster but less full-featured. Some common choices are:
- A stripped-down version of Apache
Configuring these servers is out of scope of this document; check each server’s respective documentation for instructions. Since your static file server won’t be running Django, you’ll need to modify the deployment strategy to look something like:
- When your static files change, run
- Push your local
STATIC_ROOTup to the static file server into the directory that’s being served.
rsyncis a common choice for this step since it only needs to transfer the bits of static files that have changed.
Here’s how this might look in a fabfile:
Serving Static Files from a Cloud Service or CDN
Another common tactic is to serve static files from a cloud storage provider like Amazon’s S3 and/or a CDN (content delivery network). This lets you ignore the problems of serving static files and can often make for faster-loading webpages (especially when using a CDN).
When using these services, the basic workflow would look a bit like the above, except that instead of using
rsync to transfer your static files to the server you’d need to transfer the static files to the storage provider or CDN. There’s any number of ways you might do this, but if the provider has an API a custom file storage backend will make the process incredibly simple.
If you’ve written or are using a 3rd party custom storage backend, you can tell
collectstatic to use it by setting
STATICFILES_STORAGE to the storage engine. For example, if you’ve written an S3 storage backend in
you could use it with:
Once that’s done, all you have to do is run
collectstatic and your static files would be pushed through your storage package up to S3. If you later needed to switch to a different storage provider, it could be as simple as changing your
STATICFILES_STORAGE setting. There are 3rd party apps available that provide storage backends for many common file storage APIs. A good starting point is the overview at