Search code examples
djangodockergunicorn

ModuleNotFoundError: No module named 'config' gunicorn


I'm trying to run a django project on docker

project
├── manage.py
├── config
│   ├── settings.py
│   ├── wsgi.py
│   └── ...
├──__init__.py
Dockerfile
docker-compose.yml
entrypoint.sh

Dockerfile

...

WORKDIR /app

...
COPY project project 

EXPOSE 8000

COPY entrypoint.sh ./entrypoint.sh
RUN chmod a+x ./entrypoint.sh

ENTRYPOINT ["./entrypoint.sh"]

docker-compose.yml

version: '3.9'

services:
...
  web:
   build: .
   container_name: web
   restart: unless-stopped
   ports:
     - '8000:8000'
   depends_on:
     - db
...

entrypoint.sh

#!/usr/bin/env bash

set -e

RUN_MANAGE_PY='poetry run python project/manage.py'


echo 'Collect static files...'
$RUN_MANAGE_PY collectstatic --no-input

echo 'Running migrations...'
$RUN_MANAGE_PY migrate --no-input

echo 'Starting server...'
exec poetry run gunicorn project.config.wsgi:application --bind 0.0.0.0:8000

wsgi.py

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")

application = get_wsgi_application()

when I run the command docker-compose up I get an error

web    | ModuleNotFoundError: No module named 'config
web    | [2024-04-12 20:07:47 +0600] [15] [INFO] Worker exiting (pid: 15)
web    | [2024-04-12 20:07:47 +0600] [1] [ERROR] Worker (pid:15) exited with code 3
web    | [2024-04-12 20:07:47 +0600] [1] [ERROR] Shutting down: Master
web    | [2024-04-12 20:07:47 +0600] [1] [ERROR] Reason: Worker failed to boot.

collectstatic and migrate are successful

I tried changing the gunicorn command to ... gunicorn project/config.wsgi:application ... I also tried removing the project from the command and tried ... gunicorn wsgi:application... but still got the same error

I have no experience with gunicorn and docker, so any help would be appreciated


Solution

  • Assuming that your project looks like this:

    ├── docker-compose.yml
    ├── Dockerfile
    ├── entrypoint.sh
    ├── project
    │   ├── config
    │   │   ├── __init__.py
    │   │   ├── settings.py
    │   │   ├── urls.py
    │   │   └── wsgi.py
    │   └── manage.py
    └── pyproject.toml
    

    Using same entrypoint.sh as in question.

    🗎 docker-compose.yml

    version: '3.9'
    
    services:
      web:
        build: .
        container_name: web
        restart: unless-stopped
        ports:
          - '8000:8000'
    
      database:
        image: postgres:16
        environment:
          - POSTGRES_DB=movies_database
          - POSTGRES_USER=app
          - POSTGRES_PASSWORD=123qwe
    

    🗎 Dockerfile (There were lots of details missing from the Dockerfile provided in the question, but assuming that it looks something like this. The important thing for resolving the packages was to set PYTHONPATH to /app/project).

    FROM python:3.10-bookworm
    
    WORKDIR /app
    
    ENV POETRY_VERSION=1.8.1
    ENV POETRY_VENV=/app/.venv
    
    ENV PYTHONPATH=/app/project
    
    ENV PATH="${POETRY_VENV}/bin:${PATH}:"
    
    RUN python -m venv $POETRY_VENV && \
        pip install -U pip setuptools && \
        pip install poetry==${POETRY_VERSION}
    
    COPY pyproject.toml poetry.lock* ./
    
    RUN poetry config virtualenvs.in-project true && \
        poetry install --no-root
    
    COPY project project
    
    COPY entrypoint.sh ./entrypoint.sh
    RUN chmod a+x ./entrypoint.sh
    
    ENTRYPOINT ["./entrypoint.sh"]