Каковы правильные разрешения и виртуальные хосты для запуска Django в подкаталоге?
Я пытаюсь установить и запустить Django в подкаталоге, чтобы он был отделен от статического html-сайта в корне, и у меня возникают проблемы с разрешениями на файлы/папки или виртуальными хостами
Эти два вопроса не помогли и очень старые: install django on subdirectory и Configure django on sub directory
Это проблема прав доступа к файлам/папкам или виртуальных хостов? Почему .py файлы не выполняются?
- Работает Ubuntu 20.04.3 LTS .
- Apache2 уже установлен и работает
- Python3 и Django установлены
- libapache2-mod-wsgi установлен и включен
- Apache перезапускался несколько раз
Я выполнил обычные команды оболочки для запуска проекта Django:
django-admin.py startproject contact
и затем я успешно запустил createsuperuser, collectstatic и т.д.
https://example.com/contact/index.html работает нормально,
Но вот что я получаю на example.com/contact/contact:
Вот структура моего файла:
settings.py:
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = '...'
DEBUG = True
ALLOWED_HOSTS = []
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'contact.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'contact.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
Это 000-default.conf от Apache2:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
Alias /static /var/www/html/example.com/public_html/contact/static
<Directory /var/www/html/example.com/public_html/contact/static>
Require all granted
</Directory>
<Directory /var/www/html/example.com/public_html/contact/contact>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess contact python-path=/var/www/html/example.com/public_html/contact python-home=/var/www/html/example.com/public_html/contact/contact
WSGIProcessGroup contact
WSGIScriptAlias /contact/contact /var/www/html/example.com/public_html/contact/contact/wsgi.py
WSGISocketPrefix run/wsgi
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
Похоже, что директория имеет приоритет перед директивой WSGIScriptAlias /contact/contact /var/www/html/example.com/public_html/contact/contact/wsgi.py. Поскольку каталог /contact/contact существует в файловой системе, директива WSGIScriptAlias, похоже, не используется.
Вы можете попробовать переместить скрипты за пределы DocumentRoot, поскольку это также защищает исходный код файлов от раскрытия, если произойдет событие, подобное описанному выше. Кроме того, это позволяет избежать конфликтов между каталогами/папками в файловой системе и директивами *ScriptAlias.
Также, вы можете попробовать отключить 'redirect to slash for directories' с помощью DirectorySlash Off, а затем очистить кэш браузера.
Кроме того, вы уверены, что обращаетесь к http://example.com, а не к https://example.com? Если вы обращаетесь к https://, вам также нужно добавить WSGIScriptAlias /contact/contact /var/www/html/example.com/public_html/contact/contact/wsgi.py (и другие вещи) к <VirtualHost *:443> в default-ssl.conf или куда-нибудь еще, где они есть.
Одна строка вашего 000-default.conf определяет путь к исполняемому файлу python :
WSGIDaemonProcess contact python-path=/var/www/html/example.com/public_html/contact python-home=/var/www/html/example.com/public_html/contact/contact
Если вы хотите позволить apache найти python, используемый в оболочке, вам следует удалить аргумент python-path
WSGIDaemonProcess contact python-home=/var/www/html/example.com/public_html/contact/contact
Или сделайте так, чтобы он указывал на вашу установку python3
WSGIDaemonProcess contact python-path=/my/python3/path python-home=/var/www/html/example.com/public_html/contact/contact
Таким образом у вас перестанет появляться предупреждение об использовании python2.7, и это может помочь вашему проекту работать
Вы также должны убедиться, что ваш mod-wsgi был установлен с использованием python3, а не python2.7
Вот что наконец сработало для меня:
Мне нужно было добавить #added lines в wsgi.py
(из https://www.metaltoad.com/blog/hosting-django-sites-apache )
import os
import sys #added
sys.path.append('/var/www/html/contact') #added
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'contact.settings')
application = get_wsgi_application()
Вместо того, чтобы редактировать /etc/apache2/sites-available/default-ssl.conf, я отредактировал /etc/apache2/apache2.conf:
Alias /static /var/www/html/example.com/public_html/contact/static
Alias /media /var/www/html/example.com/public_html/contact/media
<Directory /var/www/html/example.com/public_html/contact/static>
Require all granted
</Directory>
<Directory /var/www/html/example.com/public_html/contact/media>
Require all granted
</Directory>
WSGIScriptAlias /contact /var/www/html/example.com/public_html/contact/contact/wsgi.py process-group=contact
WSGIDaemonProcess contact python-path=/var/www/html/example.com/public_html/contact
WSGIProcessGroup contact
<Directory /var/www/html>
Options Indexes FollowSymLinks
AllowOverride all
Require all granted
<Files wsgi.py>
Require all granted
</Files>
</Directory>

