-
Notifications
You must be signed in to change notification settings - Fork 548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Passenger AppPreloader reports existing ruby executables as non existing when BUNDLED WITH in Gemfile.lock differs from pre-installed #2577
Comments
it's saying |
Thanks for clarifying. However, this also exists. Including a
To emphasize what I said before: An image which was working fine a week ago and the very same image with exactly same configuration (env, volumes, ...) does no longer work after recreating the container (not the image). |
If you recreate the container from the same image with no changes to how you run it then I don't see how anything we did can have affected it, it's not like we changed the image on you. Have you looked at the error message in the |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
I was suspecting passenger updating itself with the security update check. So, the image built on |
I finally managed to find out when it breaks and how to fix it. If the Bundler version at the end of the Gemfile.lock is specifies the system-wide Bundler version, it works. If they differ, passenger claims the directory was not found. e.g. Ruby 3.1.6 comes with Bundler 2.3.27. When the Gemfile.lock contains
it works. When it contains e.g. When doing
but not with 2.5.12 or 2.3.26 etc. As mentioned before, the problem occurs only with Passenger (both standalone and in nginx), but not with Puma, Rails Console, good_job etc. -- all of them handle bundler switching itself to the directory-local version well. I think (but didn't bother verifying) that having different global and local bundler versions was not a problem for Passenger before. The problem is fully reproducible in the container, but I never saw the issue when running |
@bb oh my friend, you're a life saver. That's weird that we came across the same issue within one week, while it's difficult to find anything related in google, like it's a new issue or something. I wish Passenger improve their errors log to include some really useful information instead of "No such file or directory", especially since both ruby path and app path are in place.. |
Just encounter this today. My Gemfile.lock has v2.5.14 and is working fine with passenger 3.0.6 last week. Today, I deploy it to AWS EC2 and thought all will be fine, but hit with this error:
As pointed out by @bb it is a Bundler version mismatch issues. I go to my local development and upgrade my bundler to the latest v2.5.15 and because the Dockerfile also do I don't remember Passenger to be so picky on bundler version in the past though 🤔 |
I created a repository for reproducing the issue: https://github.com/bb/passenger-not-found-minimal The main branch contains a failing setup using Ruby 3.1.6 and Rails 6.1. All can be fixed by changing Gemfile.lock to contain |
@bb Thanks for raising this. I faced the same issue few days ago and since bundler released another update it started breaking again. I was able to fix this by adding below line in my Dockerfile instead of updating the Gemfile.lock after every release:
I have raised a PR against your failing ruby33 branch and the fix seems to be working fine. |
@tanmayj28 thanks for your PR. So anybody looking for an intermediate fix, use @tanmayj28's solution above. While it's no longer urgent for me, I still hope @CamJN will give it a look someday and fix the root cause which I suspect being somewhere in passenger. |
@bb, I wanted to say THANK YOU! This error had messed me up, and I invested hours into trying to find a solution. You are truly a lifesaver, as @AvaelKross said. |
This issue has been plaguing us for 6-8 weeks... it seems to me it only happens if you are updating bundler within your Dockerfile. Following assumes running on default ruby version... I'm on version 3.0.6 which is ruby 3.3.4 by default.
I'm inclined to just take what the base image gives me for bundler. In odd cases where you want the latest/greatest bundler for whatever reason, then you need to keep the versions in sync (in lieu of some kind of fix I guess) First bullet seems to contradict a bit what @bb had reported, but seems to work for me regardless of what's in lock file if I don't try and update bundler and just take what's pre-installed. Anything else gets this error. UPDATE: |
Nevermind, 3.0.6 had Passenger 6.0.22 which didn't include that change. Actually 3.0.5 and 3.0.6 both have Passenger 6.0.22 so passenger didn't change. Here's the changes between 3.0.5 and 3.0.6: phusion/passenger-docker@rel-3.0.5...rel-3.0.6 aside from time-dependent things, however the big ones (rvm and passenger) didn't change. |
I have suspected the issue isn't really because of a change in passenger itself, but because of a change in bundler.... the problem started to hit with us when bundler 2.5.12 dropped (and our dockerfile was set to always update to latest bundler). I find it curious that 2.5.11 remains the default in even latest versions of ruby (https://stdgems.org/). Something about 2.5.12 and up causes problems somehow. That being said, if you just let bundler update itself using the version in the lock file, it seems to handle it just fine even upgrading past that version. In my case, I removed my manual
|
There are quite a few changes in bundler 2.5.11 → 2.5.12 including some that seem like they could be related rubygems/rubygems@bundler-v2.5.11...bundler-v2.5.12 Since our images include bundler 2.3.27 not 2.5.12 I guess my advice would be to not upgrade to a broken version of bundler? |
Or, oddly enough, if you let bundler itself do the updating it seems to do it in a way that does not break passenger start up. Bundler will look at your lock file BUNDLED WITH and just install the correct version and that worked for me. |
Thank you all, since this was causing me much pain. We're running on bare metal in Nginx, so I'll have to come up with another solution, other than manually remembering to install the correct version of Bundler if it changes in our apps. Of course this was not an issue in dev/qa, because those run in local thin servers and not passenger. (At least for now, this makes me think that needs to change.) I'm not sure where the change needs to happen, but after reading over the Bundler blogs, this new system is probably not going to change. Eventually they want to get to just including Bundler in the Gemfile just like any other gem. I guess that makes sense, but the version mismatch was definitely causing problems, and changing the lock file version by hand allowed us to get our apps into production. (We had already rolled-back once, and were reluctant to do so again. |
Very nice ! it fixed the problem. |
@CamJN This issue is even more complicated than it seems so far. In addition to Bundler having changed its behavior, I've also found this:
I'm going to investigate this further. |
@FooBarWidget I got an e-mail about a comment where you mentioned me, which is now deleted. Please let me know if you still need help or add a rocket emoji, so I know I can delete this comment. |
@bb I was able to reproduce it after all thanks to your repository! No help needed, thanks for providing the repo! |
Okay I've identified the root cause of this problem. A recent Bundler version introduced a mechanism called "auto-restarting". It's triggered under a complex set of conditions. One condition is that the program was invoked using a Bundler version that's different from the Bundler version in Gemfile.lock. It was designed for this typical CLI usage:
It's this last step that blows up in combination with Passenger. Bundler determines the program invocation using various means, one of which is Kernel.exec("/usr/local/rvm/rubies/ruby-3.2.4/bin/ruby", "Passenger AppPreloader: /home/app/webapp") This explains:
What's the fix? In my tests, temporarily reverting $PROGRAM_NAME to its original value, right before loading Bundler, solves this problem. Bundler then success re-executes the preloader. It didn't think it would be this simple, because when Passenger loads a subprocess (whether that's a Ruby process or whatever), the subprocess communicates its progress to Passenger, and this communication protocol was not designed to be restartable. But so far it seems like there are no issues. I will do some more checks, and if all is well, then we can use this fix. There is another potential fix strategy, namely by forcing Bundler not to restart Ruby. A CLI invocation like this does not trigger Bundler to restart the process...
...because $PROGRAM_NAME is But for compatibility, I think it's best to let Bundler restart us, so I definitely prefer the first fix strategy. |
A cleaner way to force bundler to not restart for no good reason would be to set the |
@FooBarWidget Also can you provide a minimal example that triggers the problem without Passenger, I'm trying to let the bundler folks know that their logic for knowing if it's safe to re-exec bundler is broken. The following script does not trigger the problem with a Gemfile.lock that doesn't match any installed bundler, but based on your description I would think it should:
|
I do not think that forcing Bundler not to restart, is a good idea. For maximum compatibility and least surprises, we should make Bundler restart work. Regarding reproduction:
Note that I cannot reproduce this on macOS, Ruby 3.2 installed via ASDF, RubyGems 3.5.3. Triggering this issue requires a specific environment, the details of which I've not fully explored. In particular, one necessary factor (though it may not be the only necessary factor) is that calling |
Is |
@tinco $PROGRAM_NAME is an alias for $0. https://github.com/ruby/ruby/blob/5edf1c8febb105da077b8b690b5e1df9d99099a6/ext/extmk.rb#L30 However what bundler probably wants is |
Yup, bundler doesn't have any problems if you swap |
Good find Camden. We should suggest that to the Bundler team. |
I've reduced the reproduction environment to the following: Dockerfile:FROM ruby:3.2.6
WORKDIR /root
COPY test.rb /root/test.rb
COPY Gemfile /root/Gemfile
COPY Gemfile.lock /root/Gemfile.lock
RUN gem update --system
RUN bundle config set --local deployment "true"
RUN bundle config set --local path vendor/ruby
RUN bundle install
RUN rm -rf /root/vendor/ruby/ruby/3.2.0/gems/bundler-2.5.12
CMD ["ruby", "test.rb"] Gemfile:# frozen_string_literal: true
source "https://rubygems.org"
ruby '3.2.6' Gemfile.lock:
test.rb#!/usr/bin/env ruby
$0 = "this is the program name"
require 'bundler/setup' |
Rails Apps based on this image are not starting up showing "We're sorry, but something went wrong".
/var/log/nginx/error.log
shows:but the file actually exists:
and is really executable:
This happens for images based on
There's no issue with the latest docker/passenger-ruby33 image when using the ruby which comes with the image. I didn't try installing a different version via rvm.
I first noticed this last Friday's nightly CI run (i.e. since 3.0.6 has been released).
It also happens for images built before which worked before but where container is recreated, i.e. already existing images stop working.
Nginx config sets
passenger_ruby /usr/bin/ruby;
but this is just a wrapper forwarding to /usr/local/rvm/wrappers/default/ruby which then references/usr/local/rvm/gems/ruby-3.1.5/environment
which contains:It still doesn't work when setting
passenger_ruby /usr/local/rvm/rubies/ruby-3.1.5/bin/ruby;
Even though I tested quite a few different combinations of image versions and ruby versions, I still don't know where the issue comes from. Newly created containers from images built
FROM phusion/passenger-ruby31
before last Thursday were working before but are now also broken once recreated.The text was updated successfully, but these errors were encountered: