summary of issue: after compiling nginx/dynamic passenger module by hand, I can't tell if passenger is starting up or what the problem is serving my application, but no matter what page I try I get 403 forbidden or 404 not found.
details: I had a working rails app under the passenger+nginx bundle but due to security alert on nginx 1.18 and my company's security policy, I had to clear out my nginx setup and start over, manually compiling everything according to this link. After a half day of struggling, nginx will start however when i try to access my site via browser, I get this in the error log:
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>"
What I think is happening is that passenger is starting but is having some error when it tries to run the rails app. But I can't be sure since
passenger-status
, I get an error as per this question that passenger can't find its instance registry folder. Setting the appropriate env. variable PASSENGER_INSTANCE_REGISTRY_DIR
to /tmp didn't fix this for me even though I do see passenger files are created there.I have these settings in my 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
:
I have these settings in sites-enabled/default:
root /home/<app name>/staging/current/public;
passenger_enabled on;
passenger_app_env staging;
And I am able to run passenger standalone by going to the rails apps directory and running RAILS_ENV=staging passenger start
. No apparent problems starting the app. Nor with the rails server
.
How can I diagnose what's going on? How can I know if passenger is even the source of the error log entry? I am totally stuck after 2 days of trying everything I can find in SO.
thanks in advance for any help.
edits
After my initial question, I noticed that sudo service nginx status
was complaining that Passenger was not correctly installed/compiled. However, I cleared out everything (nginx, passenger) and set it up again from scratch, and I am back to the above problems, but there is NO error about passenger when I now check the status.
I also became convinced Passenger is not being called at all because if I put a "hello, world" in index.html in my app's public directory, it gets served by Nginx. Nor do I see Passenger processes when I check passenger=memory-stats
. So I think Passenger is not starting up.
I answered my own question.
A moment after the last edit, I fixed a minor problem (I had temporarily commented out passenger_root
and passenger_ruby
directives in my nginx.conf file) and then everything was working.
So now I will outline the whole procedure I used to upgrade both Nginx and Phusion passenger to latest stable versions on Ubuntu 20.04 and hopefully it will help someone out in the future. In my case it was because Nginx 1.20+ was mandated but Ubuntu's apt only provided 1.18, which had a known vulnerability from about 6 months ago.
This procedure is needed when (as it has been for several months) the passenger-nginx package supplied by Phusion is using an outdated, vendor-supplied Nginx.
Step 1. Purge existing ubuntu-supplied nginx and passenger:
sudo apt-get remove nginx*
sudo apt-get remove passenger
Step 2. Download latest stable nginx (in my case 1.20.2) from nginx.org's apt repository instead of Ubuntu. I followed the instructions at this link under the Ubuntu heading.
Step 3. I already had ruby managed by rvm, but you should install that or whatever app environment that you need. My instructions going forward are for ruby/rails.
Step 4. Install passenger through ruby gem command:
gem install passenger
Step 5. Go to passenger directory and rake it:
cd ~/.rvm/gems/ruby-2.6.5/gems/passenger-6.0.12
rvmsudo rake nginx:as_dynamic_module CACHING=false
Note use of rvmsudo here. Because passenger was installed in the rvm directory then rvmsudo
should be used instead of sudo
with respect to passenger executables.
Step 6. Download nginx source code to match the stable version you installed in step 2: As per this page you get it from this URI:
https://nginx.org/download/nginx-${NGINX_VERSION_HERE}.tar.gz
and unpack it with tar -xf nginx-${NGINX_VERSION_HERE}.tar.gz
Step 7. As per the above link, get the compatible directives for your upcoming compile. Run sudo nginx -V
which 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...
EDIT copy everything from "--prefix" onwards.
Step 8. Configure the compile. Go to the nginx source directory and execute:
./configure {paste from clipboard} --add-dynamic-module=$(passenger-config --nginx-addon-dir)
make
sudo make install
Step 9. Configure 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
the last line puts a symbolic link to the created dynamic library for passenger, that was created at the location defined by --modules-path
parameter of step 7.
then, make sure nginx sees the module, and knows where to find itself and the ruby interpreter needed by Passenger. In nginx.conf, make sure these lines are there:
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
:
of course the exact location depends on your rvm version, and passenger version.
Step 10. Configure your site. This is beyond the scope of this, but the key lines to have are:
:
root /home/<app name>/staging/current/public;
passenger_enabled on;
passenger_app_env staging; #rails environment (not needed for production, only development or staging)
:
}