5

A simple Rails development environment using nix-shell

 3 years ago
source link: https://jamesmead.org/blog/2020-09-10-a-simple-rails-development-environment-using-nix-shell
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

A simple Rails development environment using nix-shell

This follows on from my previous article about setting up a simple Ruby development environment using nix-shell. The next thing I wanted to try was to set up a simple Rails development environment. To this end I decided to focus on the GFR website which is a Rails app, but has the advantage that it doesn't use a database.

The Gemfile for this project specified Ruby v2.5.7 and so as before, I upgraded it to use the latest v2.5 patch version, v2.5.8, so that I could use the ruby_2_5 package provided by nix.

In a similar vein, the Gemfile.lock was BUNDLED WITH v1.17.3 of bundler; whereas the bundler version provided by nixpkgs was v2.1.4. The line in Gemfile.lock wasn't an enforced constraint and I didn't want to break our Heroku deployment, so I compromised and upgraded to the v2 version of bundler supported by the Heroku Ruby buildpack, i.e. v2.0.2.

My shell.nix ended up like this:

with (import <nixpkgs> {});
let
  env = bundlerEnv {
    name = "site-bundler-env";
    ruby = ruby_2_5;
    gemdir  = ./.;
  };
in mkShell {
  buildInputs = [ env env.wrappedRuby ];
}

The full set of changes including the gemset.nix generated by bundix are in this commit.

At this point I was surprised to discover that I could run rails server from within my nix-shell and everything worked perfectly! 🚀

$ nix-shell

# ...

$ rails s
=> Booting Puma
=> Rails 5.2.4.3 application starting in development
=> Run `rails server -h` for more startup options

# ...

Started GET "/" for ::1 at 2020-09-10 18:05:37 +0100
Processing by PagesController#show as HTML

# ...

Completed 200 OK in 170ms (Views: 23.9ms)

Observations

It's worth noting that early on in the shenanigans above, I got stuck for a while with the wrong version of Ruby and nothing I did would change it. In the end I deleted a bunch of things in my /nix/store directory to fix the problem. While this probably wasn't the right way to fix it, I really appreciated the way it's relatively easy to work out how various executables are being made available to your environment, i.e. via a series of symbolic links.

I also worked out that it's not possible (at least not when using bundlerEnv) to specify the version of bundler you want to use - it seems to be fixed at v2.1.4.

Next steps

I'm still interested in working out how to have a project use a specific patch version of Ruby and to be able to lockdown the exact version of bundler. I've been reading about nix flakes and although I haven't completely got my head around them, I think they might be what I'm looking for, because they have a "lock file" which I believe can pin your dependencies to ensure reproducibility.

However, I still feel as if that's a bit of a tangent. My main aim is to be able to have multiple Rails projects on the same computer with various flavours and versions of databases, etc. So I think my next step should be to setup a development environment for a Rails project which uses a database.

Update: I've belatedly realised that some run-time dependencies (e.g. node.js & yarn) were satisfied by OS packages installed in my OSX environment, i.e. I forgot to isolate the nix shell from this environment like I did when investigating the dependency on node.js in my previous article. I plan to tackle doing this soon.

Further reading

If you'd like to know more about nix flakes, I can recommend these articles by Eelco Dolstra:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK