6.1 KiB
permalink | title | published_date | layout | data | tags | |||
---|---|---|---|---|---|---|---|---|
/{{ year }}/{{ month }}/{{ day }}/old-ruby-on-modern-nix | Old Ruby on modern Nix | 2023-07-24 14:40:00 +0200 | post.liquid |
|
|
The other day I had to deploy an old Ruby 2.7 application. As I've recently started experimenting with NixOS I used this as an opportunity to figure out how to reliably and consistently deploy this application. Along the way I had to figure out a couple of things and the available Nix documentation was either outdated or things didn't work as specified.
A dev shell for old Ruby
To get started all I wanted was a dev shell with the right Ruby version available. So I started with ruby-nix:
nix flake init -t github:inscapist/ruby-nix/main
That got me a basic flake.nix
installing Ruby 3.2.
I trimmed that down just slightly and swapped in Ruby 2.7 (here's the list of available Ruby version):
{
description = "An old Ruby application";
nixConfig = {
extra-substituters = "https://nixpkgs-ruby.cachix.org";
extra-trusted-public-keys =
"nixpkgs-ruby.cachix.org-1:vrcdi50fTolOxWCZZkw0jakOnUI1T19oYJ+PRYdK4SM=";
};
inputs = {
nixpkgs.url = "nixpkgs";
ruby-nix = {
url = "github:inscapist/ruby-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
fu.url = "github:numtide/flake-utils";
bob-ruby = {
url = "github:bobvanderlinden/nixpkgs-ruby";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, fu, ruby-nix, bob-ruby }:
with fu.lib;
eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ bob-ruby.overlays.default ];
};
rubyNix = ruby-nix.lib pkgs;
ruby = pkgs."ruby-2.7.8";
in rec {
inherit (rubyNix {
inherit ruby;
name = "old-ruby-app";
})
env;
devShells = rec {
default = dev;
dev = pkgs.mkShell {
buildInputs = [ env ];
};
};
});
}
The important line is this:
ruby = pkgs."ruby-2.7.8";
pkgs
contains the bob-ruby
overlay and so the previously listed Ruby versions are all directly available.
Now on to installing it into a shell:
nix develop
And boom:
error: Package ‘openssl-1.1.1u’ in /nix/store/b1l1kkp1g07gy67wglfpwlwaxs1rqkpx-source/pkgs/development/libraries/openssl/default.nix:210 is marked as insecure, refusing to evaluate.
Known issues:
- OpenSSL 1.1 is reaching its end of life on 2023/09/11 and cannot be supported through the NixOS 23.05 release cycle. https://www.openssl.org/blog/blog/2023/03/28/1.1.1-EOL/
You can install it anyway by allowing this package, using the
following methods:
a) To temporarily allow all insecure packages, you can use an environment
variable for a single invocation of the nix tools:
$ export NIXPKGS_ALLOW_INSECURE=1
Note: For `nix shell`, `nix build`, `nix develop` or any other Nix 2.4+
(Flake) command, `--impure` must be passed in order to read this
environment variable.
b) for `nixos-rebuild` you can add ‘openssl-1.1.1u’ to
`nixpkgs.config.permittedInsecurePackages` in the configuration.nix,
like so:
{
nixpkgs.config.permittedInsecurePackages = [
"openssl-1.1.1u"
];
}
c) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
‘openssl-1.1.1u’ to `permittedInsecurePackages` in
~/.config/nixpkgs/config.nix, like so:
{
permittedInsecurePackages = [
"openssl-1.1.1u"
];
}
That's ... unfortunate, but at least it tells us what to do:
NIXPKGS_ALLOW_INSECURE=1 nix develop --impure
And that works:
$ NIXPKGS_ALLOW_INSECURE=1 nix develop --impure
(nix:nix-shell-env)
; ruby -v
ruby 2.7.8p225 (2023-03-30 revision 1f4d455848) [arm64-darwin22]
Partial success!
A failed attempt to deploy this on NixOS
I set up a server running NixOS recently and wanted to deploy something like the above to it.
So I added my custom flake as an input and then references it in my configuration.nix
.
Lo and behold, it failed with an error message like the one above. But hey, option b) in there said what to do:
{
nixpkgs.config.permittedInsecurePackages = [
"openssl-1.1.1u"
];
}
Except no matter where, when and how I added this in my configuration it did not work. I spent a couple of hours trying out every solution I could find on the internet. None of them worked and neither the error messages nor the documentation could clear this up.
Failure.
The hack: Ignoring vulnerabilities
Vulnerabilities in nixpkgs
are declared by adding a meta.knownVulnerabilities
list.
That's what triggers the error above and the erorr message includes the custom description.
For OpenSSL 1.1 this Vulnerability is declared in pkgs/development/libraries/openssl/default.nix
.
Knowing this I later stumbled upon a StackOverflow question: Nix(OS): Set "permittedInsecurePackages" only for one package build (in an overlay?),
which had an answer: Patch the package to just contain an empty knownVulnerabilities
list.
So I changed my flake.nix
in the Ruby app to override that just for the Ruby version:
ignoringVulns = x: x // { meta = (x.meta // { knownVulnerabilities = []; }); };
ruby = pkgs."ruby-2.7.8".override {
openssl = pkgs.openssl_1_1.overrideAttrs ignoringVulns;
};
And now it works without any issues:
$ nix develop
(nix:nix-shell-env)
; ruby -v
ruby 2.7.8p225 (2023-03-30 revision 1f4d455848) [arm64-darwin22]
No more changes to my NixOS configuration required. Only this particular flake overrides the openssl
version and that's good enough for this deployment.
Success.