在子文件夹上托管 Django
Posted
技术标签:
【中文标题】在子文件夹上托管 Django【英文标题】:Host Django on subfolder 【发布时间】:2018-06-05 01:58:10 【问题描述】:我已经使用 Gunicorn 和 nginx 部署了 Django,如果 Django 应用程序在根 url 上提供服务,它可以正常工作,配置如下:
server
listen 80;
location = /favicon.ico access_log off; log_not_found off;
location /
include proxy_params;
proxy_pass http://unix:my_app.sock;
但是,当我尝试在另一个 URL 上提供 Django 应用程序时,它不起作用。 如果我尝试访问http://domain/my_app/admin/,那么 Django 会告诉我它找不到视图。
这是 NGINX 配置:
server
listen 80;
location = /favicon.ico access_log off; log_not_found off;
location /my_app
include proxy_params;
proxy_pass http://unix:/var/my_app/app.sock;
我怎样才能做到这一点?到目前为止,我找不到任何解决方案来指定类似“BASE_URL”的内容。
【问题讨论】:
您要查找的设置是FORCE_SCRIPT_NAME
- 您也可以让 nginx 将标头 X-Script-Name
设置为 /my_app
【参考方案1】:
我的评论没有显示完整的图片。当我在子文件夹上运行 Django 站点时,我喜欢使用动态配置,这样您仍然可以直接访问机器(无需代理)并拥有一个正常工作的网络应用程序。这可以帮助调试像这样难以在开发中重现的棘手问题。
如果您无法传递标头或修改 wsgi.py,您仍然可以在 Django 设置中设置FORCE_SCRIPT_NAME
。
三个步骤:
-
在网络服务器前面设置一个代理,将子文件夹从 URL 中剥离出来
设置
X-Script-Name
标头,以便您的 Django 站点生成其 url,其前面带有 /myapp/
- 确保您使用的是 % url %
标记和 reverse
,而不是硬编码!李>
修改myapp/wsgi.py,将新的头文件X-Script-Name读入wsgi环境变量SCRIPT_NAME
(基于this flask snippet)
这是一个用于代理的 Nginx 配置示例,它指向子目录上的 Django 站点并设置 X-Script-Name(步骤 1 和 2),请注意,这不使用 unix 套接字,因此它是与OP的问题略有不同。欢迎编辑:
nginx.conf
location /my_app
proxy_pass https://mywebapp.com/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Script-Name /my_app;
proxy_cookie_path / /my_app;
并阅读 X-Script-Name:
myapp/wsgi.py
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
_application = get_wsgi_application()
def application(environ, start_response):
# http://flask.pocoo.org/snippets/35/
script_name = environ.get('HTTP_X_SCRIPT_NAME', '')
if script_name:
environ['SCRIPT_NAME'] = script_name
path_info = environ['PATH_INFO']
if path_info.startswith(script_name):
environ['PATH_INFO'] = path_info[len(script_name):]
scheme = environ.get('HTTP_X_SCHEME', '')
if scheme:
environ['wsgi.url_scheme'] = scheme
return _application(environ, start_response)
【讨论】:
如果这在几年前有效,现在就不再适用了。 @JJK - 这个配置应该仍然有效。我对代理服务器的 NGINX 配置做了一个小的编辑,应该可以简化一些事情。这里假设您在https://mywebapp.com/
有一个工作应用程序,并且有一个单独的域设置子文件夹(假设它是https://user-facing-domain.com/my_app/
)。 https://user-facing-domain.com
的代理运行上面的 NGINX 配置。
...“将子文件夹从 URL 中剥离”... 似乎是其中的重要组成部分!
这似乎是部分解决方案。 CSS 不起作用,因为页面正在寻找 /static。
@Brendon - 对于您的用例,您需要创建一个存储后端,在确定STATIC_URL
时考虑SCRIPT_NAME
。请记住,它可能需要在开发和生产之间进行不同的处理。我认为使用 CDN 处理静态文件时不会出现这个问题。以上是关于在子文件夹上托管 Django的主要内容,如果未能解决你的问题,请参考以下文章
Django VirtualHosting:如何在一个 VPS 上托管具有不同域的多个 django 项目
如何解决 Heroku 上托管的 django 项目中的迁移问题?