Django mod_wsgi и apache: ошибка "модуль не найден
Я пытаюсь перенести свой проект django в продакшн, используя apache2 и mod_wsgi. Я продолжаю получать wsgi_error "ModuleNotFoundError" в логах apache.
После просмотра различных постов в Интернете я все еще ничего не добился, поэтому сейчас я начал с нуля, создав новый пример приложения django. Возникает та же ошибка.
PS, Когда я использую "runserver", приложение django прекрасно отображается в браузере. Также простое приложение wsgi "hello_world" работает нормально в apache. Так что я думаю, что базовая настройка в порядке.
Я создал тестовое приложение django "mytest" с помощью django-admin startproject mytest
Проект создан в /home/user/myprojects/mytest, группа всех каталогов - www-data
В моем тесте у меня обычная структура django
home/user/myprojects/mytest
manage.py
mytest
asgi.py
__init__.py
settings.py
urls.py
wsgi.py
В wsgi.py есть:
"""
WSGI config for mytest project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.1/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mytest.settings')
application = get_wsgi_application()
В apache 000-default.conf:
WSGIDaemonProcess mytest
WSGIProcessGroup mytest
WSGIScriptAlias /mytest /home/user/myprojects/mytest/mytest/wsgi.py
<Directory /home/user/myprojects/mytest/mytest>
Require all granted
</Directory>
При такой настройке, если я запускаю "python manage.py runserver my_ip_addr" (my_ip_addr добавлен в разрешенные хосты в файле настроек), я могу перейти к my_ip_addr и отображается сообщение "установка прошла успешно"
Запуск через стандартный веб (apache) показывает: ModuleNotFoundError: Нет модуля с именем 'mytest'
Если я уберу часть django и get_wsgi_aplication и добавлю код для отображения Hello_World, например:
import os
def application(environ, start_response):
status = '200 OK'
output = b'Hello World!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
Тогда действительно отображается hello_world
Однако я не могу найти, почему приложение wsgi mytest не запускается
Скорее должно быть так:
WSGIScriptAlias / /home/user/myprojects/mytest/mytest/wsgi.py
вместо:
WSGIScriptAlias /mytest /home/user/myprojects/mytest/mytest/wsgi.py
Я думаю, что я решил эту проблему окончательно, благодаря этому сообщению:
Django+Apache ModuleNotFoundError: Нет модуля с именем 'myproject'
Мне пришлось добавить пути к папкам проекта в wsgi.py следующим образом:
sys.path.append('home/user/project/mytest')
sys.path.append('home/user/project/mytest/mytest')
Ссылка на страницу django-served: http://ip_addr/mytest/mytest
Комментарий @NixonSparrow о WSGIScriptAlias также имеет смысл: изменение его на WSGIScriptAlias / /home/user/project/mytest/mytest/wsgi.py
затем изменило ссылку браузера на http://ip_addr/mytest
Установка, которая сработала, следующая:
Конфигурация Apache:
WSGIScriptAlias / /home/user/project/mytest/mytest/wsgi.py
<Directory /home/user/project/mytest/mytest>
Require all granted
</Directory>
wsgi.py:
python_home='/home/user/.virtualenvs/project'
activate_this= python_home + '/bin/activate_this.py'
with open(activate_this)as f:
code=compile(f.read(),activate_this,'exec')
exec(code, dict(__file__=activate_this))
import os
import sys
sys.path.append('home/user/project/mytest')
sys.path.append('home/user/project/mytest/mytest')
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mytest.settings')
application = get_wsgi_application()
settings.py, installed_aps:
INSTALLED_APPS = [
'mytest',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
urls.py:
urlpatterns = [
path('mytest/',views.index,name='index'),
path('admin/', admin.site.urls),
]
views.py:
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
return HttpResponse("<h1>MyTest Hello World ....</h1>")