Apache服务器上多个带有mod_wsgi的Django项目试图加载错误的项目库?

nhaq1z21  于 2023-05-18  发布在  Apache
关注(0)|答案(1)|浏览(146)

我正在尝试在一台服务器上运行多个Django项目。服务器是Windows,我使用Apache的mod_wsgi。
通常情况下,每个项目都在自己的服务器上运行,一切都很好-但出于开发/登台的目的,我试图从同一台服务器上为所有项目提供服务(我已经成功地在另一台服务器上为其他项目组提供服务,但它们是Flask应用程序)
我的结构看起来像这样:

ProjectA (this project contains the authentication / login / logout)
  - appa1 (shared templates / static files)
  - appa2
ProjectB 
  - appa1 (shared templates / static files)
  - appb1
  - appb2
ProjectC
  - appa1 (shared templates / static files)
  - appc1
  - appc2

我的VirtualHost设置非常简单:

<VirtualHost dev.projecta.mydomain.com:80>
    ServerName dev.projecta.mydomain.com
    Redirect / https://dev.projecta.mydomain.com
</VirtualHost>
<VirtualHost dev.projecta.mydomain.com:443>
    ServerName dev.projecta.mydomain.com
    WSGIScriptAlias / "C:/projecta/projecta.wsgi"
    CustomLog "logs/projecta_access.log" common
    ErrorLog "logs/projecta_error.log"
    SSLEngine on
    SSLCertificateFile "C:/path/to/projecta_cert/cert.cer"
    SSLCertificateKeyFile "C:/path/to/projecta_cert/project.key"
    <Directory C:\projecta>
        Require all granted
    </Directory>
</VirtualHost>
<VirtualHost dev.projectb.mydomain.com:80>
    ServerName dev.projectb.mydomain.com
    Redirect / https://dev.projectb.mydomain.com
</VirtualHost>
<VirtualHost dev.projectb.mydomain.com:443>
    ServerName dev.projectb.mydomain.com
    WSGIScriptAlias / "C:/projectb/projectb.wsgi"
    CustomLog "logs/projectb_access.log" common
    ErrorLog "logs/projectb_error.log"
    SSLEngine on
    SSLCertificateFile "C:/path/to/projectb_cert/cert.cer"
    SSLCertificateKeyFile "C:/path/to/projectb_cert/project.key"
    <Directory C:\projectb>
        Require all granted
    </Directory>
</VirtualHost>
<VirtualHost dev.projectc.mydomain.com:80>
    ServerName dev.projectc.mydomain.com
    Redirect / https://dev.projectc.mydomain.com
</VirtualHost>
<VirtualHost dev.projectc.mydomain.com:443>
    ServerName dev.projectc.mydomain.com
    WSGIScriptAlias / "C:/projectc/projectc.wsgi"
    CustomLog "logs/projectc_access.log" common
    ErrorLog "logs/projectc_error.log"
    SSLEngine on
    SSLCertificateFile "C:/path/to/projectc_cert/cert.cer"
    SSLCertificateKeyFile "C:/path/to/projectc_cert/project.key"
    <Directory C:\projectc>
        Require all granted
    </Directory>
</VirtualHost>

当我在浏览器(https://dev.projecta.mydomain.com)中访问ProjectA时,一切都会启动,并按照我的预期工作。我登录,一切正常。
当我访问ProjectB的链接时,我得到一个500错误-错误记录在projectb_error.log中,并声明如下:

[Wed May 10 09:13:49.594211 2023] [wsgi:error] [pid 17300:tid 1400] [client 9.26.10.10:15429] ModuleNotFoundError: No module named 'appa2'\r, referer: https://dev.projectb.mydomain.com/

ProjectB中没有appa2;所以我不知道它为什么还在尝试访问它
如果我重新启动Apache并首先访问ProjectB?对于ProjectB*,一切都加载正常 *(记住这一点很重要)。
当我访问到任何其他项目的链接时(例如:ProjectA)我得到一个500错误-错误记录在projecta_error.log中,并声明如下:

[Wed May 10 09:15:49.594211 2023] [wsgi:error] [pid 17300:tid 1400] [client 9.26.10.10:15429] ModuleNotFoundError: No module named 'appb1'\r, referer: https://dev.projecta.mydomain.com/

本质上,当我重新启动Apache时,我访问的第一个站点加载正常,但我访问的后续站点在日志中显示类似的错误(说明它找不到特定于前一个站点的模块)。
当这些项目位于不同的服务器上时,它可以工作-但不是在同一个服务器上。这是唯一的区别。
每个项目的.wsgi也不是很复杂:

import os
import platform
import sys
from pathlib import Path

# Activate the project specific virtual environment
path = Path(__file__).resolve().parent.parent
# Set the path to the project root in the system PATH
sys.path.insert(0, str(path))
activate_dir = "Scripts" if platform.system() == "Windows" else "bin"
activate_script = "activate_this.py"
activate_path = path / "venv" / activate_dir / activate_script
if activate_path.is_file():
    exec(
        compile(open(activate_path).read(), activate_path, "exec"),
        dict(__file__=activate_path),
    )

# Import django-environ which is installed in the venv
import environ

ROOT_DIR = Path(__file__).parent.parent
# `projecta` is changed to `projectb` and `projectc` in each project appropriately
env = environ.Env(
    DJANGO_SETTINGS_MODULE=(str, "projecta.settings.base"),
)
env.read_env(ROOT_DIR / ".env")

# Load up the django application
settings_module = env.str("DJANGO_SETTINGS_MODULE")
if not settings_module:
    # `projecta` is changed to `projectb` and `projectc` in each project appropriately
    os.environ["DJANGO_SETTINGS_MODULE"] = "projecta.settings.base"

from django.core.wsgi import get_wsgi_application

application = get_wsgi_application()

我已经仔细检查了我的.env文件,以确保它们是正确的。
我不确定如何最好地继续解决这个问题-我不确定这个错误是否与Apache及其设置有关,或者更多地与Django有关,也许是会话或cookie导致了问题?可能是mod_wsgi
我以前从没遇到过这么奇怪的事。

TL;DR:Apache在所有后续项目上加载第一个站点fine - 500,因为它试图引用特定于第一个访问的站点的模块。如果重新启动Apache,第二个站点将正常加载,但任何其他站点将500,引用特定于第二个站点的模块。

qmelpv7a

qmelpv7a1#

尝试为每个应用添加不同的应用程序组

WSGIScriptAlias / "d:/.... /wsgi.py" application-group=app_name1

还有一些关于mod_wsgi和虚拟主机的提示在这里的答案:如何在Windows中的Apache上部署多个Django应用程序?
更新:最肯定的是,这与错误的settings.py文件有关。
请尝试以下操作:
变更:

# Load up the django application
settings_module = env.str("DJANGO_SETTINGS_MODULE")
if not settings_module:
    # `projecta` is changed to `projectb` and `projectc` in each project appropriately
    os.environ["DJANGO_SETTINGS_MODULE"] = "projecta.settings.base"

简单地

os.environ["DJANGO_SETTINGS_MODULE"] = "projecta.settings.base"

相关问题