远程CentOS7 Apache部署Django/React时路由匹配失败求助
Django/React部署到CentOS7 Apache的路由问题
技术栈
- Django 3.2.23
- React 18.2.0
- CentOS7 Linux
- Apache 2.4.6
- Mod_WSGI 4.7.1
- Webpack 5.89.0
- Python3.6虚拟环境
问题详情
开发服务器在内部端口8000运行正常,转发到外部端口40731后可正常访问(如http://www.hostsite.com:40731)。但通过内部端口80正式部署后,远程通过外部端口40730访问http://www.hostsite.com:40730/cambraatz时出现问题,仅正式部署场景有此问题,开发环境无异常。
访问该地址时,index.html可成功加载(页面标题显示正常),但页面空白,开发者工具抛出No routes matched location "/cambraatz"错误。Apache访问日志返回200状态码,无新增错误日志。请求/admin和/api路径时返回标准Django 404页面(当前DEBUG=True)。
已确认本地访问服务器时同样出现空白页面,推测问题可能源于Mod_WSGI配置,Django路由在开发环境运行正常,服务器无明显错误日志。
文件目录结构
cambraatz | +-- cb-venv (虚拟环境目录) | +-- Pipfile | +-- Pipfile.lock | +-- website | +-- api | | | +-- (存储联系信息模型的Django API子目录) | +-- frontend | | | +-- (Django托管的React前端应用子目录) | +-- website | | | +-- (主Django应用,包含urls.py、wsgi.py、settings.py等) | +-- db.sqlite3 | +-- manage.py
配置文件详情
/etc/httpd/conf.d/django.conf
<VirtualHost *:80> <Directory /home/django-server-cb/cambraatz/website/website> <Files wsgi.py> Require all granted </Files> </Directory> WSGIDaemonProcess cambraatz WSGIProcessGroup cambraatz WSGIScriptAlias /cambraatz /home/django-server-cb/cambraatz/website/website/wsgi.py process-group=cambraatz Alias /static /home/django-server-cb/cambraatz/website/frontend/static <Directory /home/django-server-cb/cambraatz/website/frontend/static> Require all granted </Directory> </VirtualHost>
/home/django-server-cb/cambraatz/website/manage.py
#!/usr/bin/env python """Django's command-line utility for administrative tasks.""" import os import sys def main(): """Run administrative tasks.""" os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'website.settings') try: from django.core.management import execute_from_command_line except ImportError as exc: raise ImportError( "Couldn't import Django. Are you sure it's installed and " "available on your PYTHONPATH environment variable? Did you " "forget to activate a virtual environment?" ) from exc execute_from_command_line(sys.argv) if __name__ == '__main__': main()
/home/django-server-cb/cambraatz/website/website/wsgi.py
python_home = '/home/django-server-cb/cambraatz/cb-venv' 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 from django.core.wsgi import get_wsgi_application BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'website.settings') application = get_wsgi_application()
/home/django-server-cb/cambraatz/website/website/urls.py
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('api.urls')), path('', include('frontend.urls')), ]
/home/django-server-cb/cambraatz/website/website/settings.py
from pathlib import Path import os __import__('pysqlite3') import sys sys.modules['sqlite3'] = sys.modules.pop('pysqlite3') BASE_DIR = Path(__file__).resolve().parent.parent SECRET_KEY = os.environ.get('DJANGO_CB_SECRET_KEY', 'django-insecure-n^vlgpk!vxzj16l0%j70f5_gn%1l$&j0cu5t+0m-mt*^(i%16o') DEBUG = 'False' SESSION_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True SECURE_SSL_REDIRECT = False ALLOWED_HOSTS = ['*'] INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'api.apps.ApiConfig', 'rest_framework', 'phone_field', 'frontend.apps.FrontendConfig', ] 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 = 'website.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 = 'website.wsgi.application' DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': 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_TZ = True STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'static') MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
可提供更多文件细节或补充说明,恳请帮忙解决此问题。
内容的提问来源于stack exchange,提问作者Cameron Braatz
相关产品推荐
相关产品推荐

