我在http://localhost:12345上运行了一个django应用程序。 我希望用户通过网址http://my.server.com/myapp访问它。 我使用nginx来反向代理,如下所示:
... ...
server_name my.server.com;
location /myapp {
rewrite /myapp(.*) $1 break;
... ... # proxy param
proxy_pass http://localhost:12345;
}
... ...
问题是,当如上配置时,如何使我的响应页面中的URL具有前缀“/ myapp”,以便nginx可以正确地将它们引导到myapp。例如,像“/ foo / far”这样的页面中的url应该更改为“/ myapp / foo / bar”以允许nginx代理到myapp。 什么是正确的nginx配置用于实现这一目标?
我可以使用django的设置变量来指定根网址前缀,但它不能灵活,因为变量必须根据不同的nginx配置进行修改(比如说有一天nginx可能会改变“/ myapp”的郊区“to”/ anotherapp“)。
答案 0 :(得分:13)
由于前缀是在Nginx中设置的,托管Django应用程序的Web服务器无法知道URL前缀。正如orzel所说,如果你使用甚至nginx + gunicorn / uwsgi的apache + mod_wsgi(带有一些额外的配置),你可以使用Django自动读取的WSGIScriptAlias值。
当我需要使用URL前缀时,我通常将它自己放在我的root urls.py中,其中我只有一行,前缀为前缀并包含其他urls.py
(r'^/myapp/', include('myapp.urls')),
但我想这与在settings.py中设置前缀有相同的瓶颈,你在nginx和Django中有冗余配置。
您需要在承载Django应用程序的服务器上执行以下操作:12345。您可以在那里设置前缀,并使用WSGIScriptAlias或其等效的外部mod_wsgi将其传递给Django。我不能提供更多信息,因为我不知道你的Django应用程序是如何运行的。另外,也许你应该考虑使用uWSGI或gunicorn直接从Django运行你的Django应用程序。
要从网络服务器将前缀传递给Django,您可以使用:
proxy_set_header SCRIPT_NAME /myapp;
更多信息here
答案 1 :(得分:9)
您需要更新设置:
USE_X_FORWARDED_HOST = True
FORCE_SCRIPT_NAME = /myapp
并相应地更新您的MEDIA_URL
和STATIC_URL
。
我没有在nginx下部署的经验,但在apache下,它运行正常。 请参阅:https://docs.djangoproject.com/en/dev/ref/settings/#use-x-forwarded-host
答案 2 :(得分:2)
这是我的nginx配置的一部分,但是肯定没有设置FORCE_SCRIPT_NAME,但是,我没有使用子目录。也许在nginx而不是Django中设置与USE_X_FORWARDED_HOST相关的选项会很有用。
upstream app_server_djangoapp {
server localhost:8001 fail_timeout=0;
}
server {
listen xxx.xxx.xx.xx:80;
server_name mydomain.com www.mydomain.com;
if ($host = mydomain.com) {
rewrite ^/(.*)$ http://www.mydomain.com/$1 permanent;
}
...
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://app_server_djangoapp;
break;
}
}
...
}