Django daphne ModuleNotFoundError docker error

I got this error "ModuleNotFoundError: No module named 'project'" when I contarize my web app. I used Django with daphne. it's my settings here:

Dockerfile:

FROM python:3.11-slim

RUN apt-get update && apt-get install -y \
    libpq-dev gcc curl \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /backend

COPY requirements.txt /backend/

RUN pip install --no-cache-dir -r /backend/requirements.txt

COPY . /backend/

WORKDIR /backend/project

RUN python /backend/project/manage.py collectstatic --noinput

RUN chown -R www-data:www-data /backend

USER www-data

ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONPATH="."
ENV DJANGO_SETTINGS_MODULE=project.settings

EXPOSE 8000

#CMD ["python","manage.py","runserver"]
CMD ["daphne", "-b", "0.0.0.0", "-p", "8000", "project.asgi:application"]

docker-compose:

version: '3.9'

services:
  web:
    build:
      context: .
      dockerfile: dockerfile
    container_name: c_django
    working_dir: /backend/project
    command: >
      daphne -b 0.0.0.0 -p 8000 project.asgi:application
    #  python manage.py runserver
    volumes:
      - ./backend:/backend:delegated
      - ./backend/project/images:/backend/project/images
      - ./backend/project/staticfiles:/backend/project/staticfiles
    ports:
      - 8000:8000
    environment:
      ALLOWED_HOSTS: '*'
      DEBUG: 'True'
      SECRET_KEY: 1vbl8yp&1*c6)+-o!9r_)_1oo$x*-en^mu0#c*wcojb1j#-=20
      PYTHONPATH: "."
      DJANGO_SETTINGS_MODULE: "project.settings"
      DATABASE_NAME: fitness
      DATABASE_USER: postgres
      DATABASE_PASSWORD: 123456
      DATABASE_HOST: db
      DATABASE_PORT: 5432
      REDIS_URL: redis://redis:6379/1
    depends_on:
      - db
      - redis
    networks:
      - frontend_backend

  db:
    image: postgres:15
    container_name: c_postgres
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: 123456
      POSTGRES_DB: fitness
    ports:
      - 5432:5432
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - frontend_backend

  frontend:
    build:
      context: ../frontend
      dockerfile: Dockerfile
    container_name: c_frontend
    volumes:
      - ../frontend/dist:/usr/share/nginx/html
      - ../frontend/nginx/nginx.conf:/etc/nginx/nginx.conf
    ports:
      - 8080:80
    depends_on:
      - web
    networks:
      - frontend_backend

  nginx:
    image: nginx:latest
    container_name: c_nginx
    volumes:
      - ../frontend/nginx/nginx.conf:/etc/nginx/nginx.conf
      - ../frontend/dist:/usr/share/nginx/html
      - ./backend/project/images:/usr/share/nginx/html/images
      - ./backend/project/static:/usr/share/nginx/html/static
    ports:
      - 80:80
    depends_on:
      - web
      - frontend
    networks:
      - frontend_backend

  redis:
    image: redis:alpine
    container_name: c_redis
    ports:
      - 6379:6379
    networks:
      - frontend_backend

volumes:
  postgres_data:

networks:
  frontend_backend:
    driver: bridge

And my directory:

Directory: C:\Users\emirh\OneDrive\Belgeler\GitHub\drf-vue3-gym-managament\backend\project


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        26.06.2024     04:18                API
d-----        27.05.2024     01:51                ckeditor
d-----        23.06.2024     20:42                fixtures
d-----        31.05.2024     04:44                images
d-----         5.12.2024     22:34                project
d-----        11.01.2025     23:49                staticfiles
-a----        29.04.2024     00:53            685 manage.py



Directory: C:\Users\emirh\OneDrive\Belgeler\GitHub\drf-vue3-gym-managament\backend\project\project


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----         2.02.2025     21:56                __pycache__
-a----        15.01.2025     15:41            624 asgi.py
-a----         2.02.2025     23:44           8259 settings.py
-a----         3.12.2024     01:29            174 urls.py
-a----        29.04.2024     00:53            407 wsgi.py
-a----        29.04.2024     00:53              0 __init__.py

And this is error:

c_postgres  | 
c_postgres  | PostgreSQL Database directory appears to contain a database; Skipping initialization
c_postgres  | 
c_postgres  | 
c_postgres  | 2025-02-02 20:57:08.744 UTC [1] LOG:  starting PostgreSQL 15.10 (Debian 15.10-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
c_postgres  | 2025-02-02 20:57:08.814 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
c_postgres  | 2025-02-02 20:57:08.814 UTC [1] LOG:  listening on IPv6 address "::", port 5432
c_postgres  | 2025-02-02 20:57:08.818 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
c_postgres  | 2025-02-02 20:57:08.824 UTC [29] LOG:  database system was shut down at 2025-02-02 20:53:24 UTC
c_postgres  | 2025-02-02 20:57:08.838 UTC [1] LOG:  database system is ready to accept connections
c_frontend  | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
c_frontend  | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
c_django    | Traceback (most recent call last):
c_django    |   File "/usr/local/bin/daphne", line 8, in <module>
c_frontend  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
c_django    |     sys.exit(CommandLineInterface.entrypoint())
c_django    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
c_django    |   File "/usr/local/lib/python3.11/site-packages/daphne/cli.py", line 171, in entrypoint
c_django    |     cls().run(sys.argv[1:])
c_django    |   File "/usr/local/lib/python3.11/site-packages/daphne/cli.py", line 233, in run
c_django    |     application = import_by_path(args.application)
c_django    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
c_django    |   File "/usr/local/lib/python3.11/site-packages/daphne/utils.py", line 17, in import_by_path
c_django    |     target = importlib.import_module(module_path)
c_django    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
c_django    |   File "/usr/local/lib/python3.11/importlib/__init__.py", line 126, in import_module
c_django    |     return _bootstrap._gcd_import(name[level:], package, level)
c_django    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
c_django    |   File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
c_django    |   File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
c_django    |   File "<frozen importlib._bootstrap>", line 1126, in _find_and_load_unlocked
c_django    |   File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
c_django    |   File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
c_django    |   File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
c_django    |   File "<frozen importlib._bootstrap>", line 1140, in _find_and_load_unlocked
c_django    | ModuleNotFoundError: No module named 'project'
c_frontend  | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
c_frontend  | 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
c_frontend  | /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
c_frontend  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
c_frontend  | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
c_frontend  | /docker-entrypoint.sh: Configuration complete; ready for start up
c_nginx     | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
c_nginx     | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
c_nginx     | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
c_nginx     | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
c_nginx     | 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
c_nginx     | /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
c_nginx     | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
c_nginx     | /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
c_nginx     | /docker-entrypoint.sh: Configuration complete; ready for start up
c_django exited with code 1
c_nginx     | 2025/02/02 20:57:09 [emerg] 1#1: host not found in upstream "web" in /etc/nginx/nginx.conf:23
c_nginx     | nginx: [emerg] host not found in upstream "web" in /etc/nginx/nginx.conf:23
c_nginx exited with code 1
c_postgres  | 2025-02-02 21:02:08.942 UTC [27] LOG:  checkpoint starting: time
c_postgres  | 2025-02-02 21:02:08.963 UTC [27] LOG:  checkpoint complete: wrote 3 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.005 s, sync=0.003 s, , sync=0.003 s, total=0.022 s; sync files=2, longest=0.002 s, average=0.002 s; distance=0 kB, estimate=0 kB

asgi.py:

import os
import django
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from channels.security.websocket import AllowedHostsOriginValidator
import API.routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
django.setup()

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AllowedHostsOriginValidator(
        AuthMiddlewareStack(
            URLRouter(
                API.routing.websocket_urlpatterns
            )
        ),
    ),
})

How can I solve this problem ? Where did I make a mistake here ? I searched it but did not find anything or I couldn't solve it. I am beginner in docker. Thanks.

By default, Python searches for modules underneath the current directory. If you're importing project.asgi, Python expects that to be in project/asgi.py underneath the current directory. In the Dockerfile, you've set WORKDIR to be in the project directory, though, so you're not seeing that module structure.

I'd keep the first WORKDIR line you have, and not change directories after that. In the various places it matters, I'd take advantage of being in a current directory and not repeat the absolute path unnecessarily.

WORKDIR /backend

# Don't repeat the directory name in these commands
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

# `RUN cd ...` goes away at the end of the current command
RUN cd project && ./manage.py collectstatic --noinput

# Don't chown the directory, the files should not be writable

USER www-data

# The WORKDIR is still /backend, so project/asgi.py exists
CMD ["daphne", "-b", "0.0.0.0", "-p", "8000", "project.asgi:application"]

The other thing you need to make sure to do is not overwrite the image's code with Compose volumes:. The volumes: you show will work only if the host directory layout exactly matches what's in the image, and it will hide work like the manage.py collectstatic line in the Dockerfile. You also need to make sure to not override the image's working_dir: with the incorrect value.

You can simplify many of the options you show; I might cut this down to

version: '3.8'  # last defined 3.x file version
services:
  web:
    build: .  # short form with default Dockerfile and no build args
    ports:
      - 8000:8000
    environment:
      # repeat the settings from the question
      # (except move $DJANGO_SETTINGS_MODULE to the image and remove $PYTHONPATH)
    depends_on:
      - db
      - redis
    # no networks:, use Compose-provided `default`
    # no volumes:
    # do not override image's command: or working_dir:
    # do not need to override Compose-provided container_name:

You can make similar changes to the other services, making sure to delete volumes: for reproducibility and especially making sure to delete networks: everywhere so that every container uses the Compose-provided default network.

I did not understand what u said about dockerfile actually.

This is my new code and I have this mistake:

FROM python:3.11-slim

RUN apt-get update && apt-get install -y \
    libpq-dev gcc curl \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /backend

COPY requirements.txt ./

RUN pip install --no-cache-dir -r requirements.txt

COPY . /backend/

#WORKDIR /backend/project

RUN cd project && ./manage.py collectstatic --noinput

#RUN chown -R www-data:www-data

USER www-data

ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONPATH="."
ENV DJANGO_SETTINGS_MODULE=project.settings

EXPOSE 8000

#CMD ["python","manage.py","runserver"]
CMD ["daphne", "-b", "0.0.0.0", "-p", "8000", "project.asgi:application"]

and mistake :

ERROR [web 8/9] RUN cd project && ./manage.py collectstatic --noinput                                                                             0.2s 
------
 > [web 8/9] RUN cd project && ./manage.py collectstatic --noinput:
0.211 /bin/sh: 1: ./manage.py: not found
------
failed to solve: process "/bin/sh -c cd project && ./manage.py collectstatic --noinput" did not complete successfully: exit code: 127

My english is not good enought. Can you explain it more basically please ? Thanks.

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