dream2nix
                                
                                
                                
                                    dream2nix copied to clipboard
                            
                            
                            
                        Node.js examples - not sure how to use...
Hi,
I was trying to port an npmlock2nix project over to dream2nix, and I don't know where to start based on reading the repo examples etc. The documentation site seems broken.
This blog post has a nice looking example - https://johns.codes/blog/building-typescript-node-apps-with-nix but it appears out of date.
The examples here look more complete, but are out-of-date - https://github.com/nix-community/dream2nix/blob/a5e098038c42528bf4dff2db6cb958b1777b00e3/examples/nodejs_eslint/flake.nix#L20
From reading the code at https://github.com/nix-community/dream2nix/blob/main/examples/dream2nix-packages-nodejs/no-lock/default.nix I have no idea where to start. I don't know where "config" comes from.
Any pointers on how to proceed? Here's the npmlock2nix example.
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/23.05";
    npmlock2nix = {
      url = "github:nix-community/npmlock2nix";
      flake = false;
    };
  };
  outputs = { self, nixpkgs, npmlock2nix }:
    let
      pkgs = nixpkgs.legacyPackages."x86_64-linux";
      nl2nix = import npmlock2nix {inherit pkgs;};
      app = nl2nix.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;
    };
}
And here's my non-working attempt to get it running:
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/23.05";
    gitignore = {
      url = "github:hercules-ci/gitignore.nix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    dream2nix.url = "github:nix-community/dream2nix";
  };
  outputs = { self, nixpkgs, gitignore, dream2nix }:
    let
      pkgs = nixpkgs.legacyPackages."x86_64-linux";
      d2n = dream2nix.modules.drv-parts.nodejs-granular;
      node = {
        imports = [
          dream2nix.modules.drv-parts.nodejs-node-modules
        ];
        mkDerivation = {
          src = ./.;
        };
        deps = {nixpkgs, ...}: {
          inherit
            (nixpkgs)
            fetchFromGitHub
            mkShell
            stdenv
            ;
        };
        # How do I set build command?
        #buildCommands = [ "HOME=$PWD" "npm run build" ];
        # How do I set the node version?
        #nodejs = pkgs.nodejs-18_x;
        # How do I configure the install phase?
        #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
        #'';
        name = "my-app";
        version = "2.8.7";
      };
      # This doesn't work.
      app = node.mkDerivation {};
      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;
    };
}
                                    
                                    
                                    
                                
It looks like npmlock2nix is no longer required, since nix itself has a buildNpmPackage function now, as per https://zero-to-nix.com/start/nix-build
However, it requires you to define the hash in advance as npmDepsHash rather than it becoming part of the flake.lock.
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/23.05";
  };
  outputs = { self, nixpkgs }:
    let
      # Systems supported
      allSystems = [
        "x86_64-linux" # 64-bit Intel/AMD Linux
        "aarch64-linux" # 64-bit ARM Linux
        "x86_64-darwin" # 64-bit Intel macOS
        "aarch64-darwin" # 64-bit ARM macOS
      ];
      # Helper to provide system-specific attributes
      forAllSystems = f: nixpkgs.lib.genAttrs allSystems (system: f {
        pkgs = import nixpkgs { inherit system; };
      });
    in
    {
      packages = forAllSystems ({ pkgs }: {
        default = pkgs.buildNpmPackage {
          name = "zero-to-nix-javascript";
          buildInputs = with pkgs; [
            nodejs-18_x
          ];
          src = ./.;
          npmBuild = "npm run build";
          npmDepsHash = "sha256-s1Kze9LuYSDVxm1jxMG1yoGCYVRBsnwJ0Zi0NcT5lzg=";
          installPhase = ''
            mkdir -p $out
            cp dist/* $out
            cp hello.sh $out/hello
            chmod +x $out/hello
          '';
        };
      });
    };
}
                                    
                                    
                                    
                                
Hey @a-h we have been overhauling the architecture within the last couple of months and it was a bit messy. By now we have removed all the legacy things and it should be a lot less confusing.
You might want to check the docs and ./examples once more. We'd be happy to get some feedback.
Thanks, I'm afraid I still can't work out how to package a Node app based on the examples.
Looking at this file, I can't see where the derivation is output: https://github.com/nix-community/dream2nix/blob/main/examples/packages/single-language/nodejs-project/default.nix
There's a mkDerivation function, but I don't know why - should I call that? There's also a node-js-granular function. Are two things being packaged in the same file, can I call either of these functions?
I don't know where the entrypoint is. How would I connect this file up to a flake.nix? The example https://github.com/nix-community/dream2nix/blob/main/examples/dream2nix-repo-flake/flake.nix uses a dream2nix function called import packages - is there an importPackage function and that's how mkDerivation gets called? Does it magically know how to pass the config parameter?
I saw that the config parameter is still there. I googled around more, and found https://nixos.org/guides/nix-pills/nixpkgs-parameters.html#id1442 - so I guess that's what the config param is, and it can be null? But... its used on line 17 to get "deps" - I don't know how that gets populated.
I don't know why there's a lock.lockFileRel parameter, and what it might be used for. Where does that file come from?
A fully standalone minimal example would be very useful for me. 😁
similarly I've had a look at the examples and what confuses me is why packagesDir start with a / : packagesDir = "/packages"; . In my repo the package.json is at the root of the repo so what should I set packagesDir to ? looks like it is mandatory. (I am using the flake example).
Hi, I've been struggling a lot as well with building a node app with dream2nix. I've only read good things about it and I'd like to give it a try, but I don't get it. Looking at the docs here for example: https://nix-community.github.io/dream2nix/options/nodejs-node-modules.html I have no idea what I'm supposed to do. Same with reading the examples, the node-project doesn't explain what kind of project, what's the difference between this and package? both use evalModules and it's not clear how the default.nix are different. I've been using flake-parts and I cannot find any mentions in the docs, but I see folders related to flake-parts.
It would be awesome if something like https://diataxis.fr/ was followed for dream2nix, I don't mind reviewing all the documentation PR's, and once I'm more familiarized also sending PR's.
Some tutorials that I think would be useful are migration tutorials:
- From 
pkgs.rustPlatform.buildRustPackagetodream2nix.buildRustPackage - From 
buildNpmPackagetodream2nix.lib.evalModules? 
That would help people understand where they are standing and how to transition. And it would also create a space for people to send their migration guides PR's when they transition from another tool to dream2nix.
Thanks again for the project and the effort, it's really what I'm dreaming for 💪🏻
I'm in a similar situation and it seems to be really difficult to find help.
Would be great to have a simple example like: build a single node package from GitHub and use it in a NixOS configuration.
For anyone that stumbled across this in the last months: @DavHau cleaned up a lot of the examples recently (42838c590971da17a4b6483962707b7fb7b8b9a7) and as far as i tested it the nodejs examples are now easy to build and adapt. Just cd into the directory and 'nix build'. There are still some quirks regarding specific npm packages but many projects can be built without any problems. I think this issue can be closed.
Agreed, just looped back around this, and the examples work, and are relatively easy to adapt now.