OpenSSL and node-gyp errors when using a docker image built by `nix build` with a flake

Hello, I have a doubt regarding building docker images with nix (and using nix inside those containers). My case is that I have a project where I would like to provision a docker container using nix. The project consists of several subprojects that use mainly nodejs and rust. They work and build correctly in the host machine using nix develop with the shared flake.nix (the host machine is using NixOS).

I have tried a couple of approaches, one is by provisioning the container with certain packages and running nix develop, other is to run npm install directly in the same container.

The first approach:

This is the flake.nix file, which is also used in the other approach.

flake.nix
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };
  outputs = {
    self,
    nixpkgs,
    flake-utils,
  }:
    flake-utils.lib.eachDefaultSystem
    (
      system: let
        pkgs = import nixpkgs {
          inherit system;
        };
        all_pkgs = with pkgs; [nodejs rustup awscli2 vim openssl];
        docker_local = pkgs.dockerTools.buildImage {
          name = "personal-project";
          tag = "latest";
          config = {
            User = "foo";
            WorkingDir = "/app";
          };
          copyToRoot = pkgs.buildEnv {
            name = "image-root";
            paths = with pkgs;
              [
                bashInteractive
                cacert
                coreutils
                gcc
                git
                gnumake
                nix
                sudo
                zlib
              ]
              ++ all_pkgs;
            pathsToLink = ["/bin"];
          };
          runAsRoot = ''
            #!${pkgs.runtimeShell}
            ${pkgs.dockerTools.shadowSetup}
            mkdir -p /etc/nix
            echo 'experimental-features = flakes nix-command' >> /etc/nix/nix.conf
            groupadd nixbld
            useradd -rm -u 1000 foo
            usermod -a -G nixbld foo
            mkdir /app
            chown foo /app
          '';
        };
      in
        with pkgs; {
          devShells.default = mkShell {
            buildInputs = all_pkgs;
          };
          packages.docker_local = docker_local;
        }
    );
}

With this, I run in the host docker load < $(nix build .#docker_local) and the docker image is built correctly. Then I run docker run --rm -it -v $(pwd):/app personal-project bash and I can start on the bash shell also correctly. At this point, when I run nix develop from inside the container, I get a series of errors:

Errors
warning: '/nix/var/nix' does not exist, so Nix will use '/home/foo/.local/share/nix/root' as a chroot store
warning: Git tree '/app' is dirty
warning: error: unable to download 'https://cache.nixos.org/nix-cache-info': SSL connect error (35); retrying in 275 ms
warning: error: unable to download 'https://cache.nixos.org/nix-cache-info': SSL connect error (35); retrying in 545 ms
warning: error: unable to download 'https://cache.nixos.org/nix-cache-info': SSL connect error (35); retrying in 1066 ms

However this nix develop works well from the host. I’ve tried for a while (as you can see, many of the packages added into the container are probably not needed). Some extra info, both $SSL_CERT_FILE and $NIX_SSL_CERT_FILE are empty inside the container (also in the host so not sure if related, but I saw some posts mentioning these variables).

I also tried to clone a random repository with git clone https://github.com/NixOS/nixpkgs.git --depth 1 and it also has an SSL error:

fatal: unable to access 'https://github.com/NixOS/nixpkgs.git/': OpenSSL/3.0.9: error:16000069:STORE routines::unregistered scheme

The second approach:

Using the same flake.nix as above and docker command, I start the bash shell. But instead of running nix develop, I directly run npm install inside the container. Interestingly, seems there are no SSL errors. The project is using gatsby, which uses node-gyp, there is the following error:

Error
npm ERR! path /app/node_modules/@parcel/cache/node_modules/lmdb
npm ERR! command failed
npm ERR! command sh -c node-gyp-build-optional-packages
npm ERR! sh: line 1: /app/node_modules/@parcel/cache/node_modules/.bin/node-gyp-build-optional-packages: cannot execute: required file not found

This command npm install also works in the host machine. So I am not sure if these errors are inter-connected, due to the way I am building the docker image, or they are completely different.

I am still beginning in NixOS, but I am especially a beginner when using it for building docker containers (I’ve been running nix for a while in the host machine though), so maybe there is something wrong with that way of generating the image. It would be great if anyone had any tips for any of the two errors or how to better prepare the docker image. Many thanks.

For the issue in the first approach (SSL errors), it looks fixed by adding this in the docker configuration:

config = {
  User = "foo";
  WorkingDir = "/app";
  Env = ["SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt"];
};

After adding this, and creating the /tmp directory during the image setup, running nix develop worked inside the docker container. Also there were no errors when cloning the git repository. So with that I can reuse the same flake setup packages inside the container.

However, for the node-gyp issue, I haven’t been able to fix it yet. I will comment if I find a solution. It looks like it is possible to install with npm install --ignore-scripts, but that skips building some required modules. Running the JS file directly with ./node_modules/.bin/gatsby doesn’t work due to the shebang inside that file: #!/usr/bin/env node, since usr/bin/env doesn’t exist inside the container (but it exists in the host NixOS). If I run node ./node_modules/.bin/gatsby, it has some other issues (it is missing a module that is built during installation).

3 Likes

The error message that you are facing when using a docker image built, I found a helpful resource guide you can check out at:- https://cheapsslweb.com/blog/fixing-unable-to-get-issuer-cert-locally-error/. Maybe it will be helpful as it explains in detailed steps for the solution.