使用 Nginx/Fastcgi 在子 URL 下部署 django
Posted
技术标签:
【中文标题】使用 Nginx/Fastcgi 在子 URL 下部署 django【英文标题】:Deploying django under a sub-URL with Nginx/Fastcgi 【发布时间】:2011-03-24 23:13:16 【问题描述】:我一辈子都不知道如何使用 nginx/fastcgi 在非 root 位置下部署 django 站点,例如http://localhost:8080/myproject/ 而不是 http://localhost:8080/;我看到的所有示例都假设 Apache 或安装在站点的根目录。这是我nginx.conf
的相关部分:
server
listen 8080;
server_name localhost;
location /myproject/
# host and port to fastcgi server
fastcgi_pass 127.0.0.1:3030;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
#fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
还有一个最小的urls.py
:
from django.http import HttpResponse
from django.conf.urls.defaults import patterns
urlpatterns = patterns('',
(r'^hello$', lambda request: HttpResponse('Hello world!')),
)
尝试访问 http://localhost:8080/myproject/hello 时会出现 404。我尝试了以下所有组合均未成功:
评论/取消评论fastcgi_param PATH_INFO $fastcgi_script_name;
评论/取消评论fastcgi_param SCRIPT_NAME $fastcgi_script_name;
在 settings.py 中设置FORCE_SCRIPT_NAME = '/myproject/'
。
【问题讨论】:
【参考方案1】:我自己刚刚解决了同样的问题 - 事实证明,您在 ServerFault 上提供的指向 Django change doc 的链接是解决问题的关键。
Django > 1.0 使用 SCRIPT_NAME
和 PATH_INFO
来路由 URL,正如文档解释的那样。所以我拿着它跑了。对于您希望植根于 mydomain.com/myproject/ 的名为“myproject”的项目,试试这个。
location ~ /myproject/(.*)$
fastcgi_pass 127.0.0.1:8080;
fastcgi_param PATH_INFO /$1;
SCRIPT_NAME /myproject;
我在另一个站点范围的配置文件中拥有的其余 fastcgi 参数。所以你的例子看起来像
server
listen 8080;
server_name localhost;
location /myproject/
# host and port to fastcgi server
fastcgi_pass 127.0.0.1:3030;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME /myproject;
fastcgi_param PATH_INFO /$1;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
使用相同的 urls.py。到目前为止,我遇到的唯一问题是保持 DRY 的小问题,例如 settings.py 需要绝对 URL,而 Django 不认为在 URL 上添加 SCRIPT_NAME
(想想 settings.LOGIN_URL
、settings.MEDIA_URL
)。
这可能很明显,但也要确保您有另一个指向静态和管理媒体的位置。
【讨论】:
@gsakkis,这对你有帮助吗? 它帮助了我...我使用这种方法在 nginx.conf 中的同一台服务器上托管了两个 webapp。但我的问题是两者都需要不同的静态和媒体网址......在这里做什么??【参考方案2】:试试这个配置
location /myproject
fastcgi_split_path_info ^(/myproject)(.*)$;
fastcgi_pass 127.0.0.1:8080;
include fastcgi_params;
其中,fastcgi_params 文件包含
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
# php only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
它对我有用。
请参阅有关 fastcgi_split_path_info 的文档
【讨论】:
【参考方案3】:因为我自己遇到了子 URL 问题,所以偶然发现了您的问题。我的服务器使用 Apache 作为其主服务器,所以我的配置有所不同,但它可以工作。也许这会对某人有所帮助:
Apache 在端口 80(主 Web 服务器)上 localhost:3033 上的 nginx(随机端口) 在 localhost:3034 上的 manage.py fastcgi那么 Apache 配置看起来像这样(nginx 的代理):
<Location /blogsite/>
Order deny,allow
Allow from all
ProxyPass http://127.0.0.1:3033/
ProxyPassReverse http://127.0.0.1:3033/
</Location>
而nginx站点配置为:
server
listen 127.0.0.1:3033;
server_name localhost;
location /
fastcgi_pass 127.0.0.1:3034;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_pass_header Authorization;
fastcgi_intercept_errors off;
access_log /var/log/nginx/blogsite.access_log;
error_log /var/log/nginx/blogsite.error_log;
我认为您遇到的问题是由于某种方式的 nginx 配置,而不是 Django 部署的问题。您可能想试试我发布的解决方案是否适合您。
【讨论】:
以上是关于使用 Nginx/Fastcgi 在子 URL 下部署 django的主要内容,如果未能解决你的问题,请参考以下文章
nginx+fastcgi php 使用file_get_contentscurlfopen读取localhost本站点.php异常的情况