我正在尝试设置 Apache 和 Passenger 来为 Rails 应用提供服务。但是,我还需要它为 /public 以外的目录中的静态文件提供服务,并让这些静态文件优先于 Rails 应用中的任何内容。
Rails 应用程序位于 中/home/user/apps/testapp
,静态文件位于 中/home/user/public_html
。由于各种原因,静态文件不能简单地移动到 Rails 公共文件夹。另请注意,根目录http://domain.com/应该由public_html文件夹中的index.html文件提供服务。
这是我正在使用的配置:
<VirtualHost *:80>
ServerName domain.com
DocumentRoot /home/user/apps/testapp/public
RewriteEngine On
RewriteCond /home/user/public_html/%{REQUEST_FILENAME} -f
RewriteCond /home/user/public_html/%{REQUEST_FILENAME} -d
RewriteRule ^/(.*)$ /home/user/public_html/$1 [L]
</VirtualHost>
这可以很好地服务于 Rails 应用程序,但对于来自 public_html 的任何静态内容,都会出现 404 错误。我还尝试过一种使用配置DocumentRoot /home/user/public_html
,但这根本不服务于 Rails 应用程序,大概是因为 Passenger 不知道如何处理请求。
有趣的是,如果我将条件更改为 !-f 和 !-d,并将重写规则更改为重定向到另一个域,它会按预期工作(例如http://domain.com/doesnt_exist
重定向到http://otherdomain.com/doesnt_exist
)
我该如何配置 Apache 来提供这样的静态文件,但允许所有其他请求继续发送给 Passenger?
答案1
问题是一个小学生的 mod_rewrite 错误 - 为了运行 RewriteRule,上面的两个 RewriteCond 语句都需要满足,当然它们永远不会满足。这是我的错误,因为我从负面条件测试中复制了这个,而没有意识到它们必须分开。虽然我需要两个 RewriteRule 语句很烦人,但这很完美:
RewriteCond /home/user/public_html%{REQUEST_URI} -f
RewriteRule ^ /home/user/public_html%{REQUEST_URI} [L]
RewriteCond /home/user/public_html%{REQUEST_URI} -d
RewriteRule ^ /home/user/public_html%{REQUEST_URI} [L]