我有以下设置:
- nginx 作为反向代理
- Apache(带 Passenger)用于提供内容
现在我有了简单的 Sinatra 应用程序,如果我尝试访问不同的东西,就会发生以下情况:
domain.com/hi
- Sinatra 用密码跟我说“嗨”domain.com/readme.txt
(静态文件)- nginx 从 'public_html' 文件夹中正确获取最后——
domain.com/
或者domain.com
——403错误
在最后一种情况下,nginx 可能会尝试创建列表,但这是不必要的(我希望它将“/”请求传递给 apache)。权限本身没有问题。
错误本身(来自/var/log/nginx/error.log
):
2012/05/12 23:39:40 [error] 19012#0: *1 directory index of "/home/com_domain/public_html/" is forbidden, client: 66.77.88.99, server: domain.com, request: "GET / HTTP/1.1", host: "domain.com"
和配置:
server {
listen 80;
server_name domain.com;
access_log /var/log/nginx/com_domain.access.log;
charset utf-8;
root /home/com_domain/public_html;
# Include @apache location
include /etc/nginx/sites-available/_apache;
location ~ /\.ht {
deny all;
}
location / {
try_files $uri $uri/ @apache;
}
}
答案1
首先,关于设置的一点需要提及 - 反向代理到 Apache 乍一看似乎是一个不错的选择 - 静态文件由 Nginx 提供,您仍然保留了 Apache 的功能。但是,额外的服务器增加了不少开销 - 您增加了系统的复杂性和额外的层。由于 Nginx 可以与其他服务器(如 Passenger 和 PHP-FPM)交互,因此您可以以更少的开销匹配 Apache 的大多数功能。摆脱 Apache 将降低设置的复杂性和维护性,从而提高整体性能和稳定性,并使未来的调试更容易。
Nginx 正在尝试显示根目录的内容 - 您已告诉它在代理到 apache 之前尝试提供指定的文件和指定的目录。Nginx 将查找与 index 指令指定的文件匹配的文件,如果没有匹配,它将尝试显示目录的内容(即目录列表),但这是失败的地方。
如果您有想要提供的索引文件,则应更新指令index
以包含该文件。如果您没有这样的文件,并且希望 Apache 完全处理请求,则需要创建匹配的位置块并向proxy_pass
Apache 发送请求。
根据Nginx 维基百科,位置指令按特定顺序匹配:
- 带有“=”前缀的指令与查询完全匹配(文字字符串)。如果找到,则搜索停止。
- 所有剩余指令均带有常规字符串。如果此匹配项使用了“^~”前缀,则搜索停止。
- 正则表达式,按照它们在配置文件中定义的顺序。
- 如果 #3 匹配成功,则使用该结果。否则,将使用 #2 的匹配结果。
location
因此,创建一个与根路径完全匹配(即使用等号)的附加块将允许您为该单个位置指定特殊规则。如果要正常工作,此位置块应该将请求代理到 Apache。:
location = / {
#proxy_pass ...;
#error 200 = @apache;
#include proxy_info;
#try_files non_existent_file @apache;
}
根据您的设置,可能有几种方法可以将请求传递给代理,其中一些方法上面提到过。
您仍应保留您的location / {}
块 - 它将匹配其他位置块未匹配的所有请求。请注意,虽然try_files
指令可能在块下工作server {}
,但最好在location
块下工作,因为它只会被选择性地处理。