英文:
Multiple Django Projects on Apache Server with mod_wsgi is trying to load wrong project libraries?
问题
I'm trying to run multiple Django projects on one server. The server is Windows and I am using mod_wsgi with Apache.
Normally, each project lives on its own server and everything works great - but for dev/staging purposes I am trying to just serve them all from the same server (I've done this successfully with other groups of projects on another server, but they were Flask applications)
My structure looks similar to this:
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
My VirtualHost setup is pretty straightforward:
<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>
When I access ProjectA
in the browser (https://dev.projecta.mydomain.com) everything fires up and works as I would expect. I login and everything works.
When I visit a link to ProjectB
I get a 500 error - the error is recorded in projectb_error.log
and states this:
[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', referer: https://dev.projectb.mydomain.com/
There is no appa2
in ProjectB
; so I'm not sure why it's still trying to access it.
If I restart Apache and visit ProjectB
first? Everything loads fine for ProjectB (this is important to keep in mind).
When I visit a link to any other project (for example: ProjectA
) I get a 500 error - the error is recorded in projecta_error.log
and states this:
[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', referer: https://dev.projecta.mydomain.com/
In essence, when I restart Apache - the first site I visit loads fine, but the subsequent sites I visit show a similar error in the logs (stating that it can't find a module that is specific to the previous site).
It works when these projects are on different servers - but not on the same server. That's the only difference.
The .wsgi
for each project isn't very complex either:
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()
I've double-checked my .env
files to ensure they are correct.
I'm not sure how best to continue troubleshooting this - I am not sure if this error is related to Apache and how it's set up, or more related to Django and perhaps sessions or cookies causing an issue? Maybe it's mod_wsgi
?
I've not run into something as odd as this before.
TL;DR: Apache loads first site fine - 500's on all subsequent projects because it's trying to reference a module specific to the first site visited. If Apache is restarted the second site will load fine, but any other site will 500 with references to a module specific to the second site.
英文:
I'm trying to run multiple Django projects on one server. The server is Windows and I am using mod_wsgi with Apache.
Normally, each project lives on it's own server and everything works great - but for dev/staging purposes I am trying to just serve them all from the same server (I've done this successfully with other groups of projects on another server, but they were Flask applications)
My structure looks similar to this:
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
My VirtualHost setup is pretty straightforward:
<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>
When I access ProjectA
in the browser (https://dev.projecta.mydomain.com) everything fires up and works as I would expect. I login and everything works.
When I visit a link to ProjectB
I get a 500 error - the error is recorded in projectb_error.log
and states this:
[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/
There is no appa2
in ProjectB
; so I'm not sure why it's still trying to access it.
If I restart Apache and visit ProjectB
first? Everything loads fine for ProjectB (this is important to keep in mind).
When I visit a link to any other project (for example: ProjectA
) I get a 500 error - the error is recorded in projecta_error.log
and states this:
[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/
In essence, when I restart Apache - the first site I visit loads fine, but the subsequent sites I visit show a similar error in the logs (stating that it can't find a module that is specific to the previous site).
It works when these projects are on different servers - but not on the same server. That's the only difference.
The .wsgi
for each project isn't very complex either:
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()
I've double checked my .env
files to ensure they are correct.
I'm not sure how best to continue troubleshooting this - I am not sure if this error is related to Apache and how it's setup, or more related to Django and perhaps sessions or cookies causing an issue? Maybe it's mod_wsgi
?
I've not ran into something as odd as this before.
TL;DR: Apache loads first site fine - 500's on all subsequent projects because it's trying to reference a module specific to the first site visited. If Apache is restarted the second site will load fine, but any other site will 500 with references to a module specific to the second site.
答案1
得分: 1
尝试为每个应用添加不同的应用程序组:
WSGIScriptAlias / "d:/.... /wsgi.py" application-group=app_name1
关于mod_wsgi和虚拟主机的更多提示,请参考此处的回答:https://stackoverflow.com/questions/75141768/how-to-deploy-multiple-django-apps-on-apache-in-windows/75145306#75145306
更新:这很可能与错误的settings.py文件有关。
尝试以下操作:
更改:
# 加载Django应用程序
settings_module = env.str("DJANGO_SETTINGS_MODULE")
if not settings_module:
# 在每个项目中将`projecta`更改为相应的`projectb`和`projectc`
os.environ["DJANGO_SETTINGS_MODULE"] = "projecta.settings.base"
为:
os.environ["DJANGO_SETTINGS_MODULE"] = "projecta.settings.base"
英文:
try to add different application groups for each app
WSGIScriptAlias / "d:/.... /wsgi.py" application-group=app_name1
and some more hints about mod_wsgi and virtual hosts in the answer here: https://stackoverflow.com/questions/75141768/how-to-deploy-multiple-django-apps-on-apache-in-windows/75145306#75145306
update: most certainly this has to do with wrong settings.py file.
try the following:<br>
change:
# 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"
to simply
os.environ["DJANGO_SETTINGS_MODULE"] = "projecta.settings.base"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论