Rails and Passenger app deployment error: rake-13.0.6 Bundler::GemNotFound

Note that the server paths to Apache, Ruby, and your app web folder will vary depending on your operating system and server configuration.

After deploying a Rails app to a server environment via Capistrano, the following generic Phusion Passenger error screen is being shown:

I ssh to the server and check the Apache logs for errors:

➜ tail -f /etc/httpd/logs/error_log
App 29384 output: Error: The application encountered the following error: Could not find rake-13.0.6 in any of the sources (Bundler::GemNotFound)
App 29384 output: /opt/ruby-2.5/lib64/ruby/gems/2.5.0/gems/bundler-1.17.3/lib/bundler/spec_set.rb:91:in `block in materialize'

I note that Bundler is looking for a Gem in /opt/ruby-2.5, however the app’s ./.ruby-version is set to 2.7.4.

My hunch is that the Passenger configuration is set to an old version of Ruby, which has missing dependencies. In a way the missing deps error is lucky, because otherwise the app would be running on an outdated Ruby version compared to dev.

To validate my theory, I check the Passenger config for my app.

➜ ssh [email protected]
➜ sudo su
➜ ls /etc/httpd/conf.d/vhost
my-app-name-int.conf my-app-name-uat.conf

After identifying the correct config file, I check the contents. Sure enough, the Ruby version is set incorrectly to 2.5:

➜ cat /etc/httpd/conf.d/vhost/my-app-name-uat.conf
PassengerRuby /opt/ruby-2.5/bin/ruby

I backup the config file, then update the Ruby version to be correct:

➜ cp /etc/httpd/conf.d/vhost/my-app-name-uat.conf /etc/httpd/conf.d/vhost/my-app-name-uat.conf.bak # backup the current configuration
➜ vim /etc/httpd/conf.d/vhost/my-app-name-uat.conf # edit the current config
# PassengerRuby /opt/ruby-2.5/bin/ruby
PassengerRuby /opt/ruby-2.7/bin/ruby
➜ service httpd reload # reload Apache to apply the changes

# ➜ apachectl restart # if Apache issues encountered, restart Apache

Note: if PassengerRuby is already correct here, the Ruby version might still be missing gems – continue to the next steps

Finally, I manually install the missing Ruby deps. Note: these commands are run using the appropriate app service account, not root.

➜ cd /var/www/my-app-name-uat/current
➜ export PATH=/opt/ruby-2.7/bin:$PATH
➜ bundle install

Passenger now successfully launches my app when the url is visited in a web browser.

Note that this complete update process must be done on each server node if using a load balanced group.

If further bundler errors are encountered, the system gems might need to be updated:

PATH=/opt/ruby-2.7/bin:$PATH gem update --system

Note: make sure to to include the –system flag here, otherwise other apps on the server might be impacted.

Full Error Trace

➜ tail -f /etc/httpd/logs/error_log

App 29384 output: [passenger_native_support.so] not found for current Ruby interpreter.
App 29384 output: This library provides various optimized routines that make
App 29384 output: Phusion Passenger faster. Please run 'sudo yum install passenger-devel-6.0.7'
App 29384 output: so that Phusion Passenger can compile one on the next run.
App 29384 output: [passenger_native_support.so] not downloading because PASSENGER_DOWNLOAD_NATIVE_SUPPORT_BINARY=0
App 29384 output: [passenger_native_support.so] will not be used (can't compile or download)
App 29384 output: --> Passenger will still operate normally.
App 29384 output: Error: The application encountered the following error: Could not find rake-13.0.6 in any of the sources (Bundler::GemNotFound)
App 29384 output: /opt/ruby-2.5/lib64/ruby/gems/2.5.0/gems/bundler-1.17.3/lib/bundler/spec_set.rb:91:in block in materialize' App 29384 output: /opt/ruby-2.5/lib64/ruby/gems/2.5.0/gems/bundler-1.17.3/lib/bundler/spec_set.rb:85:inmap!'
App 29384 output: /opt/ruby-2.5/lib64/ruby/gems/2.5.0/gems/bundler-1.17.3/lib/bundler/spec_set.rb:85:in materialize' App 29384 output: /opt/ruby-2.5/lib64/ruby/gems/2.5.0/gems/bundler-1.17.3/lib/bundler/definition.rb:170:inspecs'
App 29384 output: /opt/ruby-2.5/lib64/ruby/gems/2.5.0/gems/bundler-1.17.3/lib/bundler/definition.rb:237:in specs_for' App 29384 output: /opt/ruby-2.5/lib64/ruby/gems/2.5.0/gems/bundler-1.17.3/lib/bundler/definition.rb:226:inrequested_specs'
App 29384 output: /opt/ruby-2.5/lib64/ruby/gems/2.5.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:108:in block in definition_method' App 29384 output: /opt/ruby-2.5/lib64/ruby/gems/2.5.0/gems/bundler-1.17.3/lib/bundler/runtime.rb:20:insetup'
App 29384 output: /opt/ruby-2.5/lib64/ruby/gems/2.5.0/gems/bundler-1.17.3/lib/bundler.rb:107:in setup' App 29384 output: /opt/ruby-2.5/lib64/ruby/gems/2.5.0/gems/bundler-1.17.3/lib/bundler/setup.rb:20:in'
App 29384 output: /opt/ruby-2.5/lib64/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in require' App 29384 output: /opt/ruby-2.5/lib64/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:inrequire'
App 29384 output: /usr/share/ruby/vendor_ruby/phusion_passenger/loader_shared_helpers.rb:365:in activate_gem' App 29384 output: /usr/share/ruby/vendor_ruby/phusion_passenger/loader_shared_helpers.rb:221:inblock in run_load_path_setup_code'
App 29384 output: /usr/share/ruby/vendor_ruby/phusion_passenger/loader_shared_helpers.rb:529:in running_bundler' App 29384 output: /usr/share/ruby/vendor_ruby/phusion_passenger/loader_shared_helpers.rb:220:inrun_load_path_setup_code'
App 29384 output: /usr/share/passenger/helper-scripts/rack-preloader.rb:91:in preload_app' App 29384 output: /usr/share/passenger/helper-scripts/rack-preloader.rb:189:inblock in '
App 29384 output: /usr/share/ruby/vendor_ruby/phusion_passenger/loader_shared_helpers.rb:382:in run_block_and_record_step_progress' App 29384 output: /usr/share/passenger/helper-scripts/rack-preloader.rb:188:in'
App 29384 output: /usr/share/passenger/helper-scripts/rack-preloader.rb:30:in <module:PhusionPassenger>' App 29384 output: /usr/share/passenger/helper-scripts/rack-preloader.rb:29:in'
[ E 2022-08-02 17:37:44.7235 2524/T8h age/Cor/App/Implementation.cpp:221 ]: Could not spawn process for application /var/www/my-app-name/current: The application encountered the following error: Could not find rake-13.0.6 in any of the sources (Bundler::GemNotFound)
Error ID: 60047415
Error details saved to: /tmp/passenger-error-DEwgnV.html

[ E 2022-08-02 17:37:44.7526 2524/Te age/Cor/Con/CheckoutSession.cpp:276 ]: [Client 4-2281] Cannot checkout session because a spawning error occurred. The identifier of the error is 60047415. Please see earlier logs for details about the error.

Rails and WebPacker: SSL_connect error

When implementing SSO for a legacy Rails 5 application with a Puma dev environment, I encountered an issue with JavaScript content not loading on some pages. The server output the following error message:

➜ bundle exec rails s -b "ssl://localhost:3000?key=config/cert.key&cert=config/cert.crt"
=> Booting Puma
=> Rails LTS application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Puma version: 5.6.4 (ruby 2.7.4-p191) ("Birdie's Version")
Started GET "/" for at 2022-06-21 17:07:43 +1000
2022-06-21 17:17:21 +1000 Rack app ("GET /packs/js/form-2c133051829ab02ebb74.js" - ( #<OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: wrong version number>

The Fix

It looks like the local dev environment had previously been run under HTTP, not HTTPS. Updating the webpacker config and restarting the server resolved the issue:

➜ vim config/webpacker.yml
  <<: *default
  compile: true
  warnings: true

    host: localhost
    port: 3035
    hmr: false
    https: false # <-- set this to true

➜ ./bin/webpack-dev-server

Rails: Python2 error on yarn install

I recently worked on a legacy codebase that requires Python2, which has been deprecated for some time and is no longer available via homebrew.

Using this Stack Overflow thread I was able to resolve the issue as below. Note that the “pyenv global” command might interfere with with your Python3 environment.

The Error

➜ yarn install --check-files
gyp verb command configure []
gyp verb check python checking for Python executable "python2" in the PATH
gyp verb `which` failed Error: not found: python2

➜ which python
python not found

➜ which python2
python2 not found

The Fix

➜ brew install pyenv
➜ pyenv install 2.7.18
➜ pyenv global 2.7.18
➜ PATH=$(pyenv root)/shims:$PATH
➜ which python2

➜ yarn install --check-files
yarn install v1.22.19
Done in 10.26s

Add to ~/.bashrc or ~/.zshrc to make available in future shell sessions:

# make python exe available globally
PATH=$(pyenv root)/shims:$PATH

Rails: Puma MiniSSL::SSLError

The problem

When setting up a dev environment for older Rails projects, Puma can sometimes have trouble serving https:// pages. Puma boots ok but will begin choking with a MiniSSL::SSLError:

➜ bundle exec rails s -b "ssl://"
=> Booting Puma
=> Rails application starting in development

2022-03-03 17:19:21 +1100: SSL error, peer:, peer cert: , # <Puma::MiniSSL::SSLError: OpenSSL error: error:141F7065:SSL routines:final_key_share:no suitable key share - 337604709>

The fix

This error is caused by a bug in older versions of Puma. To fix, simply update the version of Puma in the Rails gemfile:

#gem 'puma', '~> 3.11'
gem 'puma', '~> 4.3.8'

Then install the new version of the Puma gem and test:

➜ bundle install
➜ bundle exec rails s -b "ssl://"
=> Booting Puma
=> Rails application starting in development

Puma should now run and serve https pages successfully.

Rails 6 & Node: Yarn error on install around ‘remove_cv_t’

This error can occur when setting up a development environment for an existing Rails 6 project and the node dependencies are being installed. It seems to be caused by an incompatibility between node-sass and Node 16.

Here are step by step instructions on how to fix the problem by specifying the version of node to use in the project folder using NVM.

➜ bundle exec rails server # rails won't boot, yarn error
  Your Yarn packages are out of date!
  Please run `yarn install --check-files` to update.

➜ yarn install --check-files # yarn install fails...
/Users/user/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: no template named 'remove_cv_t' in namespace 'std'; did you mean 'remove_cv'?

➜ brew install nvm # install Node Version Mgr if needed
➜ echo "14.18.2" > .nvmrc # create a version file for NVM (do this in your rails project directory)
➜ cat .nvmrc

➜ node -v # check the current node version

➜ nvm use
Found '/Users/user/project/.nvmrc' with version <14.18.2>
Now using node v14.18.2 (npm v6.14.15)

➜ node -v # verify we're now using the correct node version

➜ yarn install --check-files # install should now complete ok
✨  Done in 8.73s.

➜ bundle exec rails server # rails should now boot
=> Booting Puma

Here’s the full error trace:

In file included from /Users/user/.node-gyp/16.13.1/include/node/v8.h:30:
/Users/user/.node-gyp/16.13.1/include/node/v8-internal.h:492:38: error: no template named 'remove_cv_t' in namespace 'std'; did you mean 'remove_cv'?
            !std::is_same<Data, std::remove_cv_t<T>>::value>::Perform(data);
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/type_traits:710:50: note: 'remove_cv' declared here
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS remove_cv
1 error generated.
make: *** [Release/obj.target/binding/src/binding.o] Error 1
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/Users/user/project/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack     at ChildProcess.emit (node:events:390:28)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
gyp ERR! System Darwin 21.2.0
gyp ERR! command "/Users/user/.nvm/versions/node/v16.13.1/bin/node" "/Users/user/project/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
gyp ERR! cwd /Users/user/project/node_modules/node-sass
gyp ERR! node -v v16.13.1
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok

RSpec error – Host header or origin header is specified and is not whitelisted or localhost.

I encountered the following head-scratcher when trying to run the following RSpec test on MacOs:

➜ bundle exec rspec ./spec/features/some_spec.rb:12

Capybara starting Puma…
Version 4.3.8 , codename: Mysterious Traveller
Min threads: 0, max threads: 4
Listening on tcp://

unexpected response, code=500, content-type="text/html"
Host header or origin header is specified and is not whitelisted or localhost.

After much fruitless poking around in ./spec/rails_helper.rb, I checked my /etc/hosts file and realised I had mapped to a custom name. I updated /etc/hosts to include only the following lines: localhost my.localdev

And hey presto, Selenium would now run the rest of my (still failing) tests.

As an aside, I tried passing the options '--headless', '--disable-web-security', '-–allow-file-access-from-files', '--allowed-origins=*‘ to Capybara in ./spec/rails_helper.rb, and none seemed to have any effect.

Rails HTTPs error on localhost – getaddrinfo SocketError

I recently began developing a Rails Plugin gem, and running the dummy app locally using HTTP worked flawlessly out of the box. However, when it came time to test HTTPS, I encountered the following error:

➜ rails s -b "ssl://"
=> Booting WEBrick
=> Rails 5.2.6 application starting in development on http://ssl://
=> Run rails server -h for more startup options
INFO WEBrick 1.4.4
`getaddrinfo': getaddrinfo: nodename nor servname provided, or not known (SocketError)

This was puzzling at first as I had other apps running fine using HTTPS. After closer inspection I discovered the other apps were running under the Puma webserver, while my gem had defaulted to using WEBrick.


The solution was to find the latest version of Puma and add it to my gem:

➜ gem search puma
puma (5.5.2 ruby java java, 5.4.0, 4.3.10)

edit ./Gemfile:
gem "puma", "5.5.2"

Install the gem:

➜ bundle install
Installing puma 5.5.2 with native extensions

The Rails app then booted into HTTPs successfully under Puma:

➜ rails s -b "ssl://"
=> Booting Puma
Listening on ssl://

Rails: Error installing gem mysql2 on MacOs

When installing gems on a new project under MacOs using bundler, I encountered the following error for MySql:

Installing mysql2 0.5.2 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

linking shared-object mysql2/mysql2.bundle
ld: library not found for -lssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mysql2.bundle] Error 1

It seems the clang compiler couldn’t find an SSL library on the system. The solution was:

> brew install openssl
> bundle config --global build.mysql2 --with-opt-dir="$(brew --prefix openssl)
> bundle

# This also works:
> export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/opt/openssl/lib/

Rails 6: Beware the master.key

Checking encrypted credentials into git using Rails 6 feels weird but is pretty great.

What isn’t great is getting this error when deploying to Heroku:

ActiveSupport::MessageEncryptor::InvalidMessage: ActiveSupport::MessageEncryptor::InvalidMessage

After running EDITOR=vim bundle exec rails credentials:edit Rails will create a master.key file which works fine, but expects all your environments to be in a single credentials file and creates a master.key to decrypt the file.

Subsequently running EDITOR=vim bundle exec rails credentials:edit --environment staging appears to not use the master key and instead autocreates a ./config/credentials/staging.key.

In Heroku, the RAILS_MASTER_KEY environment variable needs to be set to the value of staging.key, not master.key, otherwise the MessageEncryptor error is thrown. This wasn’t clear to me from various tutorials and StackOverflow posts.

adding a blocklist break-glass header for Rack::Attack

When blocklisting broad IP ranges using the Rails Rack::Attack gem, it can be valuable to have a break-glass HTTP header so that legitimate users in a blocked range can still access the webapp.

The Rack::Attack docs provide most of the information on how to do this, however the syntax in the current example does not match the format of a header injected into the browser using an extension such as SimpleModifyHeaders.

As it turns out, any such headers are uppercased and prefixed with HTTP_. So if in your browser extension you set your header as SuperSecretKey, Rack::Attack would pass it through as HTTP_SUPERSECRETKEY.

The below code snippet illustrates, and also dumps out all headers to the console as a comma delimited list.

class Rack::Attack

  p "~~~~~~~~ RAAAACK ATTAAAAAAAACK ~~~~~~~~"

  # safelist by HTTP header
  Rack::Attack.whitelist("mark any authenticated user as safe") do |request|

    p "~~ HEADER CHECK ~~"

    p request.env.sort.compact.reject(&:empty?).join(',')

    puts request.env.key?("HTTP_SUPERSECRETKEY")
    puts request.env["HTTP_SUPERSECRETKEY"]
    request.env["HTTP_SUPERSECRETKEY"] == "Hunter2"