Rails executable can't find gems with bundix

I’m currently trying to develop a rails app on NixOS and have managed to get it started at first. But somehow it broke and I am not sure what, so I’d like to ask some help on how I could go to debug this?

My current setup is:

shell.nix

with (import <nixpkgs> { });
let
  env = bundlerEnv {
    name = "boulder-bundler-env";
    inherit ruby;
    gemdir = ./.;
    gemfile = ./Gemfile;
    lockfile = ./Gemfile.lock;
    gemset = ./gemset.nix;
  };
in
stdenv.mkDerivation {
  name = "boulder";
  buildInputs = [ env ruby bundix yarn nodejs ];
}

Gemfile

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.7.4'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
gem 'rails', '~> 6.1.4', '>= 6.1.4.1'
# Use sqlite3 as the database for Active Record
gem 'sqlite3', '~> 1.4'
# Use Puma as the app server
gem 'puma', '~> 5.0'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 5.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.4', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 4.1.0'
  # Display performance information such as SQL time and flame graphs for each request in your browser.
  # Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
  gem 'rack-mini-profiler', '~> 2.0'
  gem 'listen', '~> 3.3'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 3.26'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

Now, when I try to run rails db:migrate for example, I get the following error:

❯ rails db:migrate
Could not find rake-13.0.6 in any of the sources
Run `bundle install` to install missing gems.

rails itself is a wrapped file with the following contents:

#!/nix/store/ybvqnbdqi094xk5ymxq21kfiw3ih5pb0-ruby-2.7.4/bin/ruby
#
# This file was generated by Nix.
#
# The application 'rails' is installed as part of a gem, and
# this file is here to facilitate running it.
#

ENV["BUNDLE_GEMFILE"] = "/nix/store/f7rybafy68m2xzr3v4vzikvg1gi50yb6-gemfile-and-lockfile/Gemfile"
ENV.delete 'BUNDLE_PATH'
ENV['BUNDLE_FROZEN'] = '1'

Gem.paths = { 'GEM_HOME' => "/nix/store/6amvp6km7slfalbfg28qsl5nr2lq6yfz-boulder-bundler-env/lib/ruby/gems/2.7.0" }

$LOAD_PATH.unshift "/nix/store/ggqacj06n6qfm1iww0bih9ph0j89wcna-bundler-2.1.4/lib/ruby/gems/2.7.0/gems/bundler-2.1.4/lib"

require 'bundler'
Bundler.setup()

load Gem.bin_path("railties", "rails")

So I checked whether the referenced GEM_HOME actually contains the rake gem/executable:

❯ ls /nix/store/6amvp6km7slfalbfg28qsl5nr2lq6yfz-boulder-bundler-env/lib/ruby/gems/2.7.0/gems/ | grep rake
rake-13.0.6 -> /nix/store/x0x7p632yb99mrrnsi1yc7sdcymilah5-ruby2.7.4-rake-13.0.6/lib/ruby/gems/2.7.0/gems/rake-13.0.6

And sure enough, it is there! (Same for the binary)

At this point I am just scratching my head, as it seems like things are setup correctly and yet still fail.

Has anyone encountered this issue?

Things I have tried:

  • Re-run bundix -l or just bundix → No change
  • Use the wrappedRuby from the env in my shell.nix → No change
  • Don’t have ruby in the shell.nix → No change
  • Run bin/rails db:migrate instead of the environment rails → Same error

Thank you for any pointers!

2 Likes

After searching some more on what could be the difference, I’ve tried removing the .bundle folder that I must have somehow generated. I am not sure why this causes the rest to fail. But here we go.

The solution is to make sure that you do not have a .bundle folder, which I assume causes bundler to try and use its contents which is not what nix has then installed.

2 Likes

So, after this happened again without a .bundle file or anything else, it seems that some component is doing unpure builds or declaring the wrong hashes. Since after gc-ing all the paths and roots and re-building with the updated gemset.nix it worked just fine. It could also be that me doing this triggered some other problem to be fixed (since rails does heavy caching on its components, maybe Zeitwerk is the culprit?).

2 Likes