Django daphne ModuleNotFoundError docker error
Я получил эту ошибку «ModuleNotFoundError: Нет модуля с именем 'project'» при контаризации моего веб-приложения. Я использовал Django с daphne. мои настройки здесь:
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
И моя директория:
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
А это ошибка:
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
)
),
),
})
Как я могу решить эту проблему? Где я допустил ошибку? Я искал, но ничего не нашел или не смог решить эту проблему. Я новичок в docker. Спасибо.
По умолчанию Python ищет модули в текущем каталоге. Если вы импортируете project.asgi
, Python ожидает, что он будет находиться в project/asgi.py
под текущим каталогом. В Dockerfile вы задали, чтобы WORKDIR
находился в каталоге project
, поэтому вы не видите этой структуры модулей.
Я бы сохранил первую строку WORKDIR
, которая у вас есть, и не менял бы каталоги после этого. В различных местах, где это имеет значение, я бы воспользовался преимуществом нахождения в текущем каталоге и не повторял абсолютный путь без необходимости.
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"]
Другая вещь, в которой вам нужно убедиться, - это не переписывать код образа с помощью Compose volumes:
. Показанный вами volumes:
будет работать только в том случае, если расположение директории хоста в точности соответствует тому, что указано в образе, и будет скрывать работу строки manage.py collectstatic
в Dockerfile. Вам также нужно убедиться, что вы не переопределите working_dir:
в образе с неправильным значением.
Вы можете упростить многие из представленных вариантов; я бы сократил это до
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:
Вы можете внести аналогичные изменения в другие сервисы, обязательно удалив volumes:
для воспроизводимости и особенно удалив networks:
везде, чтобы каждый контейнер использовал предоставленную Compose сеть default
.
Я не понял, что вы сказали о 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 ./
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"]
и ошибка :
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
Мой английский недостаточно хорош. Можете ли вы объяснить это более подробно, пожалуйста? Спасибо.
Я думаю, что проблема здесь:
services:
web:
build:
context: .
dockerfile: dockerfile
container_name: c_django
working_dir: /backend/project # <-- here
Вы уже находитесь в этой директории, поэтому django не может найти этот модуль.
Просто измените на backend
и все будет работать нормально.