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.
- A base dockerfile for production
- Another one for dev that uses it the base
The entrypoint runs the django server with --reload
Observations
- When serving a working server, any change in any file (namely
urls.py
andviews.py
) is ignored. Adding syntax errors or any change is not reflected. - 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. - 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?