Ubuntu 20.04 + Nginx 1.20.2 + Passenger 6.0.12 动态模块 + Rails

Ubuntu 20.04 + Nginix 1.20.2 + Passenger 6.0.12 dynamic module + Rails

问题总结: 手动编译nginx/dynamic passenger 模块后,我无法判断passenger 是否正在启动或者问题出在我的应用程序上,但无论我尝试哪个页面,我都会收到 403 forbidden 或 404 not found。

详细信息:我在 passenger+nginx 捆绑包下有一个可用的 rails 应用程序,但由于 nginx 1.18 的安全警报和我公司的安全政策,我不得不清除我的 nginx 设置并重新开始,根据 this link 手动编译所有内容。经过半天的努力,nginx 将启动,但是当我尝试通过浏览器访问我的网站时,我在错误日志中得到了这个:

2022/02/24 00:03:06 [error] 156967#156967: *3 directory index of "/home/<app name>/staging/current/public/" is forbidden, client: <client ip addr>, server: <server ip addr>, request: "GET / HTTP/1.1", host: "<server ip addr>"

认为 正在发生的事情是 passenger 正在启动,但在尝试 运行 rails 应用程序时遇到了一些错误。但我不能确定,因为

  1. 错误消息完全没有信息,我想如果 passenger 没有启动,nginx 会失败并显示类似的消息。
  2. 我不能 运行 passenger-status,根据 this question 我得到一个错误,乘客找不到它的实例注册表文件夹。设置适当的环境。 /tmp 的变量 PASSENGER_INSTANCE_REGISTRY_DIR 并没有为我解决这个问题,尽管我确实看到那里创建了乘客文件。

我的 nginx.conf 中有这些设置:

load_module modules/ngx_http_passenger_module.so

http {
:
passenger_root /home/<app name>/.rvm/gems/ruby-2.6.5/gems/passenger-6.0.12
passenger_ruby /home/<app name>/.rvm/gems/ruby-2.6.5/wrappers/ruby
:

我在 sites-enabled/default 中有这些设置:

root /home/<app name>/staging/current/public;
passenger_enabled on;
passenger_app_env staging;

而且我可以 运行 通过转到 rails 应用程序目录和 运行 宁 RAILS_ENV=staging passenger start 独立乘客。启动应用程序没有明显问题。也不与 rails server.

我如何诊断发生了什么?我怎么知道 passenger 是否是错误日志条目的来源?在尝试了 SO 中可以找到的所有内容 2 天后,我完全陷入困境。

在此先感谢您的帮助。

编辑 在我最初的问题之后,我注意到 sudo service nginx status 抱怨 Passenger 不正确 installed/compiled。但是,我把所有的东西(nginx,passenger)清空,重新设置,又回到了上面的问题,但是现在查看状态,passenger没有报错。

我也确信 Passenger 根本没有被调用,因为如果我在我的应用程序的 public 目录中的 index.html 中放置一个“hello, world”,它将由 Nginx 提供服务。当我检查 passenger=memory-stats 时,我也没有看到 Passenger 进程。所以我认为 Passenger 没有启动。

我回答了我自己的问题。

在最后一次编辑后不久,我修复了一个小问题(我暂时在 nginx.conf 文件中注释掉了 passenger_rootpassenger_ruby 指令),然后一切正常。

所以现在我将概述我在 Ubuntu 20.04 上将 Nginx 和 Phusion passenger 升级到最新稳定版本的整个过程,希望它能帮助将来的人。在我的例子中,这是因为 Nginx 1.20+ 是强制要求的,但 Ubuntu 的 apt 只提供了 1.18,它在大约 6 个月前就有一个已知的漏洞。

当 Phusion 提供的 passenger-nginx 软件包使用过时的 vendor-supplied Nginx 时(已经几个月了)需要此过程。

第 1 步。清除现有 ubuntu-supplied nginx 和 passenger:

sudo apt-get remove nginx*
sudo apt-get remove passenger

第 2 步。从 nginx.org 的 apt 存储库而不是 Ubuntu 下载最新的稳定 nginx(在我的例子中是 1.20.2)。我按照 Ubuntu 标题下 this link 的说明进行操作。

第 3 步。我已经 ruby 由 rvm 管理,但您应该安装它或您需要的任何应用程序环境。我接下来的指示是 ruby/rails.

第四步. 通过ruby gem 命令安装passenger:

gem install passenger

第 5 步。转到乘客目录并搜索它:

cd ~/.rvm/gems/ruby-2.6.5/gems/passenger-6.0.12
rvmsudo rake  nginx:as_dynamic_module CACHING=false

注意这里使用rvmsudo。因为 passenger 安装在 rvm 目录中,所以对于 passenger 可执行文件应该使用 rvmsudo 而不是 sudo

第 6 步。下载 nginx 源代码以匹配您在第 2 步中安装的稳定版本:根据 this page 您可以从此 URI 获取它:

https://nginx.org/download/nginx-${NGINX_VERSION_HERE}.tar.gz

并用tar -xf nginx-${NGINX_VERSION_HERE}.tar.gz

解压

第 7 步。根据上述 link,为即将进行的编译获取兼容的指令。 运行 sudo nginx -V 其中 returns:

nginx version: nginx/1.20.2
built by gcc 9.3.0 (Ubuntu 9.3.0-10ubuntu2) 
built with OpenSSL 1.1.1f  31 Mar 2020
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --wi...

编辑 从“--prefix”开始复制所有内容。

第八步,配置编译。进入nginx源码目录,执行:

./configure {paste from clipboard} --add-dynamic-module=$(passenger-config --nginx-addon-dir)
make
sudo make install

第 9 步. 配置 nginx:

cd /etc/nginx
sudo mkdir modules-enabled  #if directory not already there
cd modules-enabled
sudo ln -s /usr/lib/nginx/modules/ngx_http_passenger_module.so ngx_http_passenger_module.so

最后一行将符号 link 放入为乘客创建的动态库,该动态库是在第 7 步的 --modules-path 参数定义的位置创建的。

然后,确保 nginx 看到模块,并知道在哪里找到自己和 Passenger 需要的 ruby 解释器。在 nginx.conf 中,确保有这些行:

load_module modules/ngx_http_passenger_module.so

http {
:
passenger_root /home/<app name>/.rvm/gems/ruby-2.6.5/gems/passenger-6.0.12
passenger_ruby /home/<app name>/.rvm/gems/ruby-2.6.5/wrappers/ruby
:

当然,具体位置取决于您的 rvm 版本和 passenger 版本。

第 10 步。配置您的站点。这超出了本文的范围,但关键行是:

   :
   root /home/<app name>/staging/current/public;
   passenger_enabled on;
   passenger_app_env staging;  #rails environment (not needed for production, only development or staging)
   :
   }