I have a django project with pdm and docker compose and I set up the codebase volume to enable django hot reload and debugging in the container. Building with the compose config works fine but when I try to run the server with docker compose up -d
I hit a python error as if the libs were not picked up properly.
The project has the following architecture
project/
├── config/
│ ├── settings.py
│ └── urls.py
│ └── ...
├── some_django_app/
│ └── ...
├── compose.yaml
├── Dockerfile
├── README.md
├── pyproject.toml
└── pdm.lock
the compose file is as follows
services:
web:
build:
dockerfile: Dockerfile
command: pdm run python manage.py runserver 0.0.0.0:8000
ports:
- 8000:8000
volumes:
- .:/app
env_file:
- .env
my dockerfile is as follows
# Use an official Python runtime as a parent image
FROM python:3.13.2-slim-bullseye
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# Set the working directory in the container
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
# Install PDM
RUN pip install --no-cache-dir pdm
# Copy the project files into the container
COPY . /app
# Accept build argument for ENVIRONMENT
ARG ENVIRONMENT=prod
# Install project dependencies using PDM
pdm install --prod --no-lock --no-editable;
Here is the trace of the error when I up the container
INFO: The saved Python interpreter does not exist or broken. Trying to find another one.
INFO: __pypackages__ is detected, using the PEP 582 mode
Traceback (most recent call last):
File "/app/manage.py", line 12, in main
from django.core.management import execute_from_command_line
ModuleNotFoundError: No module named 'django'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/app/manage.py", line 23, in <module>
main()
~~~~^^
File "/app/manage.py", line 14, in main
raise ImportError(
...<3 lines>...
) from exc
ImportError: Couldn't import Django. Are you sure it's installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?
It is as if pdm couldn't pick up my local libs. When I remove the container line in my compose file and rebuild, django runs fine. What is wrong with my configuration?
I ended up using a multistage approach as described with the PDM doc so PDM is used only during the build and not at runtime. To make sure the container .venv is not overwritten by the codebase venv, I also added a specific named container as follows:
services:
web:
build:
dockerfile: Dockerfile
command: pdm run python manage.py runserver 0.0.0.0:8000
ports:
- 8000:8000
volumes:
- .:/app
- venv:/app/.venv
env_file:
- .env
volumes:
venv:
This solved my problem: I can still use pdm and docker during development and have a volume for the codebase.