We'll also take a look at how to serve Django static and media files via Nginx.
For production environments, we'll add on Nginx and Gunicorn. This is a step-by-step tutorial that details how to configure Django to run on Docker with MySQL. 4 min read Photo by Mohammad Rahmani / Unsplash Introduction.See the note at the end of the uWSGI documentation on HTTP support for further detail.
Since you won't need to install requirements again after the Docker image has been created, this can be added to the pip install command.
Next, we copy our application code to the image, set some default environment variables, and run collectstatic. It's important to keep this all on one line so that Docker will cache the entire operation as a single layer. We extend from the "slim" flavor of the official Docker image for Python 3.7, install a few dependencies for running our application (i.e., that we want to keep in the final version of the image), copy the folder containing our requirements files to the container, and then, in a single line, (a) install the build dependencies needed, (b) pip install the requirements themselves (edit this line to match the location of your requirements file, if needed), (c) remove the C compiler and any other OS packages no longer needed, and (d) remove the package lists since they're no longer needed. RUN groupadd -r $ # Uncomment after creating your docker-entrypoint.sh # ENTRYPOINT # Start uWSGI CMD A couple of the benefits of uWSGI are that (1) it's almost entirely configurable through environment variables (which fits well with containers), and (2) it includes native HTTP support, which can circumvent the need for a separate HTTP server like Apache or Nginx.įROM python:3.7-slim # Create a group and user to run our app There are many WSGI servers available for Python, and we use both Gunicorn and uWSGI at Caktus. The Debian-based "slim" images are still relatively small the bare-minimum image described below increases from about 170 MB to 227 MB (~33%) when switching from python:3.7-alpine to python:3.7-slim (and updating all the corresponding system packages). But now, I'm switching to a Debian- and glibc-based image, because I found an inconvenient workaround was required for musl libc's strftime() implementation. In a previous version of this post, I used Alpine Linux as the base image for thisĭockerfile. The specific tools I use are: Docker (of course), the python:3.7-slim Docker image (based on Debian Stretch), and uWSGI. There are many ways to containerize a Python/Django app, no one of which could be considered "the best." That being said, I think the following approach provides a good balance of simplicity, configurability, and container size.