I have setup for my django project using nginx and uwsgi, similar to what is described here
I am now trying to use docker
/ docker compose
to maintain it.
For the container with the django application, everything seems to be working fine when I use docker build
, but when I use docker compose
, the files do not seem to be updated properly.
The Dockerfile
is:
FROM python:3.10-alpine
# Install Imagemagick package
# gcc and more are required to build the uswgi wheel
RUN apk add imagemagick imagemagick-dev imagemagick-pdf gcc python3-dev build-base linux-headers pcre-dev curl
# set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
COPY requirements.txt /
RUN pip install -r requirements.txt
COPY django_app/ /app
COPY uwsgi.ini /
WORKDIR /app
RUN python ./manage.py migrate
RUN python ./manage.py collectstatic --noinput
docker-compoose.yml
:
services:
redis:
image: redis:7-alpine
celery_worker:
build:
context: .
dockerfile: ./Dockerfile
image: celery
command: celery -A bg_upgrades worker -l info
env_file:
- ./docker_env
depends_on:
- redis
uwsgi:
build:
context: .
dockerfile: ./Dockerfile
image: uwsgi
env_file:
- ./docker_env
command: uwsgi --ini /uwsgi.ini
volumes:
- django_app:/app/
- socket:/sock/
depends_on:
- redis
nginx:
build:
context: ./nginx
dockerfile: ./Dockerfile
volumes:
- django_app:/app/
- socket:/sock/
depends_on:
- redis
- uwsgi
- celery_worker
ports:
- 80:80
volumes:
django_app:
socket:
Looking at other answers, here are a few things I've tried:
docker compose up -d --build --force-recreate
docker compose build --no-cache
docker-compose.yml
fileRUN rm -Rf /app/*
before the COPY
in the Dockerfiledocker compose down
before restartingSpecifically, the file I am changing (and I don't see the changes reflected int he container) is at django_app/my_app/template/pattern_form.html.j2
Again, when I use docker build -t my_app:0.1 .
, the file is updated properly (no change to the Dockerfile
).
This volume mount is causing the behavior:
volumes:
- django_app:/app/
Whatever content is in the django_app
named volume will be mounted on /app
, hiding whatever was in your image. Nothing will ever update this volume's content, and it's an unusual behavior of Docker that anything is in this volume at all. (A similar setup using a host directory or a Kubernetes volume would yield an empty directory.)
Never mount anything over your application code. Avoid relying on Docker's behavior of automatically copying content into volumes.
The easiest way to fix this is to make sure you've configured Django's static-file service. If you have, remove any sort of static-file handling from Nginx. Its configuration should pretty much just have
upstream django {
server uwsgi:8001
}
server {
# No /media or /static paths
location / {
uwsgi_pass django;
}
}
Once you've done that then you can delete the volumes:
blocks from all of the non-database containers and the corresponding entries in the top-level volumes:
. Since you're not mounting a stale named volume over your application code, you'll see the updates when your image is rebuilt.