nix-community / npmlock2nix

nixify npm based packages [maintainer=@andir]
Apache License 2.0
130 stars 42 forks source link

Expose as a nix flake #159

Open cmoog opened 2 years ago

cmoog commented 2 years ago

For ease of use with other flakes, it'd be nice if a flake.nix was added to this repo that exposed npmlock2nix.overlay as a nixpkg overlay.

danielphan2003 commented 2 years ago

I believe having packages.<system>.default and overlays.default would also make it easier to use npmlock2nix on Nix 2.7+

TLATER commented 2 years ago

FYI, you can use still this in a flake. Here's how I got a shell up:

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05";
    npmlock2nix = {
      url = "github:nix-community/npmlock2nix";
      flake = false;
    };
  };

  outputs = {
    self,
    nixpkgs,
    npmlock2nix,
  }: let
    # At the moment, we only deploy to x86_64-linux. Update when we
    # care about another platform.
    system = "x86_64-linux";
    overlays = [
      (final: prev: {
        npmlock2nix = import npmlock2nix {pkgs = prev;};
      })
    ];
  in {
    devShells.${system} = let
      pkgs = import nixpkgs {inherit system overlays;};
      inherit (pkgs) npmlock2nix;
    in {
      default = npmlock2nix.shell {
        src = self;
      };
    };
  };
}

If you want to use the niv-pinned input versions, just remove the pkgs = prev bit from the import in the overlay.

a-h commented 12 months ago

I also noticed that it's not possible to copy npmlock2nix using nix copy, which makes it harder (impossible?) to use the project in an air-gapped environment. I've been exporting flakes, then copying them over via a USB stick, and using the nix copy operation on the other side.

Executing a copy...

nix copy github:nix-community/npmlock2nix --to file:///home/a-h/nix-exports/npmlock2nix

Results in this error...

error: getting status of '/nix/store/adcajk19i9r7h1kp7swq5c653r0n1yms-source/flake.nix': No such file or directory

Adding a flake.nix to the project would resolve the issue.

andir commented 12 months ago

Just download an archive of the contents or a git clone and copy that around? Whats the benefit of having a flake for that?

a-h commented 11 months ago

Thanks!

I thought that the nix copy command seemed to be the standard way to copy things around between systems, and since it requires a flake.nix, it would be useful to have one.

I was worried that there might be some other dependencies not included if I just cloned the source code. nix copy reads the flake and includes all dependencies in its target output, so I thought it would the least risky way of doing it.

I think what you're saying is that to use the tool on a machine without an internet connection, I'd clone the repo with an Internet connection, copy it to the remote machine via USB, and swap the github reference for a local filesystem reference?

So instead of having this in my flake.nix:

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/23.05";
    npmlock2nix = {
      url = "github:nix-community/npmlock2nix";
      flake = false;
    };
  };

I'd have:

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/23.05";
    npmlock2nix = {
      path = "/dependencies/github.com/nix-community/npmlock2nix";
      type = "path";
      flake = false;
    };
  };

I know there's a flake-registry.json that seems to be able to redirect things too. In an offline system, I've populated it with a reference to nixpkgs rather than letting it download from the Internet. So rather than update each flake.nix, it may be possible to redirect with the flake-registry.json on a per-machine basis, like this?

{
  "flakes": [
    {
      "from": {
        "id": "nixpkgs",
        "type": "indirect"
      },
      "to": {
        "path": "/dependencies/github.com/NixOS/nixpkgs/",
        "type": "path"
      }
    },
    {
      "from": {
        "id": "github:nix-community/npmlock2nix",
        "type": "indirect"
      },
      "to": {
        "path": "/dependencies/github.com/nix-community/npmlock2nix",
        "type": "path"
      }
    }
  ],
  "version": 2
}
a-h commented 11 months ago

I worked out how to not have a flake input, by using the fetchFromGithub function to pull the source code and then import it from there.

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/23.05";
  };

  outputs = { self, nixpkgs }:
    let
      pkgs = nixpkgs.legacyPackages."x86_64-linux";
      npmlock2nixSrc = pkgs.fetchFromGitHub {
        owner = "nix-community";
        repo = "npmlock2nix";
        rev = "9197bbf397d76059a76310523d45df10d2e4ca81";
        hash = "sha256-sJM82Sj8yfQYs9axEmGZ9Evzdv/kDcI9sddqJ45frrU=";
      };
      npmlock2nix = import npmlock2nixSrc { inherit pkgs; };
      app = npmlock2nix.v2.build {
        src = ./.;
        nodejs = pkgs.nodejs-18_x;
        buildCommands = [ "HOME=$PWD" "npm run build" ];
        installPhase = ''
          mkdir -p $out
          cp -r .next/standalone $out/app
          cp -r public $out/app/public
          mkdir -p $out/app/.next
          cp -r .next/static $out/app/.next/static
        '';
      };
      nextUser = pkgs.runCommand "user" {} ''
        mkdir -p $out/etc
        echo "nextjs:x:1000:1000:nextjs:/home/nextjs:/bin/false" > $out/etc/passwd
        echo "nextjs:x:1000:" > $out/etc/group
        echo "nextjs:!:1::::::" > $out/etc/shadow
      '';
      dockerImage = pkgs.dockerTools.buildImage {
        name = "app";
        tag = "latest";
        copyToRoot = [
          # Uncomment the coreutils and bash if you want to be able to use a shell environment
          # inside the container.
          #pkgs.coreutils
          #pkgs.bash
          nextUser
          pkgs.nodejs-18_x
          app
        ];
        config = {
          Cmd = [ "node" "server.js" ];
          User = "nextjs:nextjs";
          Env = [ "NEXT_TELEMETRY_DISABLED=1" ];
          ExposedPorts = {
              "3000/tcp" = {};
          };
          WorkingDir = "/app";
        };
      };
    in
    {
      packages."x86_64-linux".default = app;
      packages."x86_64-linux".docker = dockerImage;
    };
}

But this doesn't seem to solve the problem that I think Flakes would help with.

In this setup, I can use nix copy --to file:///export to export the build outputs for import into another machine store, but nix copy --derivation --to file:///export doesn't copy everything required to build the product on the airgapped machine:

warning: you don't have Internet access; disabling some network-dependent features
warning: Git tree '/app-nodejs' is dirty
error: builder for '/nix/store/6cqbpij6khzrcs8xkmdczv0d7w3gd89x-curl-8.0.1.tar.bz2.drv' failed with exit code 1;
       last 4 log lines:
       > error:
       >        … writing file '/nix/store/fqpmn0x3f3mzn24d90d0vvqgpayc3z1b-curl-8.0.1.tar.bz2'
       >
       >        error: unable to download 'https://curl.haxx.se/download/curl-8.0.1.tar.bz2': Couldn't resolve host name (6)
       For full logs, run 'nix log /nix/store/6cqbpij6khzrcs8xkmdczv0d7w3gd89x-curl-8.0.1.tar.bz2.drv'.
error: 1 dependencies of derivation '/nix/store/4axap2njrg4xzfh28gcafp9y1z2yp6jk-curl-8.0.1.drv' failed to build
error:
       … while calling the 'import' builtin

         at /nix/store/krfk8cshw7wrm6h5nn7s2q5san4zvnw6-source/flake.nix:15:21:

           14|       };
           15|       npmlock2nix = import npmlock2nixSrc { inherit pkgs; };
             |                     ^
           16|       app = npmlock2nix.v2.build {

       … while realising the context of path '/nix/store/adcajk19i9r7h1kp7swq5c653r0n1yms-source'

         at «none»:0: (source not available)

       error: 1 dependencies of derivation '/nix/store/n0shp26j2szy0amw0d2qpf648wdmbl5r-source.drv' failed to build