Other Blog Posts
Prepare Django applications for Kubernetes using Docker multi-stage builds
2024-07-23
For production deployments Django has a concept of serving static files through a webserver rather than through the actual application. When running Django on Kubernetes you will therefore need to provide an additional webserver container, even more so since Traefik is only intended as a reverse proxy and has no built in functionality for serving static files.
Django provides the collectstatic
command line utility to prepare static files for production deployment on a webserver.
The filesystem location for the collectstatic
output is configured with the STATIC_ROOT
Django setting.
Here I'm using a Docker Multi-stage build to provide both the Django application container image and the static files. This helps me to keep the runtime images small and also makes it easier to keep the static files being served in sync with the application code.
In addition to the actual application container the build provides:
- a custom Nginx build with static files baked into the container and alternatively
- a tarball containing the static files made available on the build host. You can then extract the tarball in a persistent volume claim mounted into a stock Nginx container image.
FROM python:3.12-alpine as builder
RUN apk add --update xz
COPY your-django-app /opt/django
WORKDIR /opt/django
RUN python -m venv .
RUN bin/pip install -r requirements.txt
# The next line needs to match STATIC_ROOT in your settings.py
RUN mkdir /opt/static
RUN bin/python manage.py collectstatic --noinput
WORKDIR /opt
RUN tar cJf djangostatic.txz static
FROM python:3.12-alpine as djangoapp
RUN apk add --update libgcc
COPY --from=builder --chown=1000:0 /opt/django /opt/django
USER 1000
WORKDIR /opt/django
EXPOSE 8002
# change to fit your cmd line, depending e.g. on WSGI server used
CMD ["/opt/django/bin/python", "/opt/django/wsgi.py"]
FROM nginx as djangostatic
COPY --from=builder /opt/static /usr/share/nginx/html/static
FROM scratch as tarball
COPY --from=builder /opt/djangostatic.txz /djangostatic.txz
Build stages:
-
djangoapp
The actual Django application, build with:
podman build -t djangoapp --target djangoapp .
-
djangostatic
Nginx webserver serving staticfiles, build with:
podman build -t djangostatic --target djangostatic .
-
tarball
This stage runs collectstatic and creates a tarball in the root of the container filesystem. If you have a recent
buildah
version ordocker-buildx
installed, you can then download the staticfiles archive with e.g. (docker-buildx
):docker buildx build . --output djangostatic --target copytohost
This will create a
./djangostatic
directory on the host containing the tarball. You can then extract the tarball in a persistent volume claim mounted into a stock Nginx container image.