Django Server ignores file changes with --reload in docker

TL;DR

How to make django respond to changes I make in my code (in docker)?

I will post the way I run my server in docker.

  1. A base dockerfile for production
  2. Another one for dev that uses it the base

The entrypoint runs the django server with --reload

Observations

  1. When serving a working server, any change in any file (namely urls.py and views.py) is ignored. Adding syntax errors or any change is not reflected.
  2. When serving a server with syntax errors in urls.py for example, and when the server is still running removing the syntax error, the change does work, but any subsequent changes don't work.
  3. I checked that the files do change inside the docker container, and still Django ignores them.

Here is the relevant code:

Dockerfile (the base)

# Use Python 3.11.3 as the base image
FROM python:3.11.3-slim

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV DJANGO_SETTINGS_MODULE=config.settings

# Set work directory
WORKDIR /app

# Install system dependencies and debugging tools
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    curl \
    netcat-openbsd \
    && rm -rf /var/lib/apt/lists/*

# Install Python dependencies
COPY requirements.txt /app/
RUN pip install --upgrade pip && \
    pip install --no-cache-dir -r requirements.txt

# Copy project
COPY . /app/

# Create a directory for static files
RUN mkdir -p /app/staticfiles && chmod 755 /app/staticfiles

# Create log directory and file
RUN mkdir -p /var/log && \
    touch /var/log/app.log && \
    chmod 666 /var/log/app.log

# Add these lines to print some debug info
RUN echo "Python version:" && python --version
RUN echo "Pip packages:" && pip list
RUN echo "Contents of /app:" && ls -la /app

RUN python -c "import django; print(f'Django version: {django.__version__}')"
RUN python -c "import sys; print(f'Python path: {sys.path}')"

# Expose port
EXPOSE 8080

# This is important for the version endpoint
RUN mkdir /build_artifacts; TZ=America/Argentina/Buenos_Aires date +"%Y-%m-%d %H:%M:%S" > /build_artifacts/build_time.txt

COPY docker_entrypoint_common.sh /app/docker_entrypoint_common.sh
COPY docker_entrypoint.sh /app/docker_entrypoint.sh
RUN chmod +x /app/docker_entrypoint.sh /app/docker_entrypoint_common.sh

ENTRYPOINT ["/app/docker_entrypoint.sh"]

Dockerfile.dev (the one actually running the image)

# Dockerfile.dev

# Use the production image as the base
FROM personal-website-backend

# Install debugpy for debugging
RUN pip install debugpy

# Expose the debugging port
EXPOSE 5678

# Copy the common and development entrypoint scripts
COPY docker_entrypoint_common.sh /app/docker_entrypoint_common.sh
COPY docker_entrypoint_dev.sh /app/docker_entrypoint.sh
RUN chmod +x /app/docker_entrypoint.sh /app/docker_entrypoint_common.sh

# Mount your source code for hot-reloading (optional, see note below)
# This step is typically done at run time with a volume mount, not in the Dockerfile

# Set the entrypoint
ENTRYPOINT ["/app/docker_entrypoint.sh"]

entrypoint_common.sh

#!/bin/bash

set -e  # Exit immediately if a command exits with a non-zero status

# Common functionality for both production and development

# Set build time environment variable if needed
if [ -f "/build_artifacts/build_time.txt" ]; then
    export BUILD_TIME=$(cat /build_artifacts/build_time.txt)
    echo "Build time set to: $BUILD_TIME"
else
    echo "ERROR: build_time.txt file not found."
    exit 1
fi

entrypoint.dev.sh

#!/bin/bash

# Source the common entrypoint script
source /app/docker_entrypoint_common.sh

# Development-specific functionality

# Start Gunicorn with reload and debugpy for debugging
echo "Starting Gunicorn with reload and debugpy..."



# Source the common entrypoint script
source /app/docker_entrypoint_common.sh

# Development-specific functionality

# Start Django development server with debugpy for debugging
echo "Starting Django development server with debugpy..."
exec python -m debugpy --listen 0.0.0.0:5678 manage.py runserver 0.0.0.0:8080 --reload

Building with

docker build -t personal-website-backend .
dockebuild -f Dockerfile.dev -t personal-website-backend_dev .

And running with

dockerun -it     -p 8080:8080     -p 5678:5678     -v $(pwd):/app     -e GCP_PROJECT_ID=my_id     --env-file /home/noams/src/personal_website/backend/.secrets_backend     --env-file /home/noams/src/personal_website/backend/.env     personal-website-backend_dev     /bin/bash

The Question

How to make django respond to changes I make in my code?

Вернуться на верх