Search code examples
containersnix

Building a nix derivation within a module


I created the following module services/invidious.nix

{ pkgs, stdenv, ... }:
stdenv.mkDerivation {
  name = "invidious";
  container = pkgs.dockerTools.buildLayeredImage {
    name = "invidious";
    contents = [ pkgs.busybox pkgs.bash pkgs.invidious ];
    config = {
      Cmd = [ "/bin/bash" ];
      Env = [];
      Volumes = {};
    };
  };
}

My eventual goal is to have several services in modules and use nix-build to build each of those services as containers, and write the resulting image names to a file:

let
  config = import ./config.nix;
  pkgs = config.pkgs;
  invidious = import ./services/invidious.nix;
in rec {
  serviceimages = pkgs.writeText "images.txt" ''
    ${invidious(pkgs)}
  '';
}

and my config.nix just has the pkgs pinned version:

{
  # nixos-22.05 / https://status.nixos.org/
  pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/d86a4619b7e80bddb6c01bc01a954f368c56d1df.tar.gz") {};
}

However, when I use nix-build, I get the following error:

nix-build services.nix -A serviceimages
these 2 derivations will be built:
  /nix/store/dbl3bzc05pssq3q9g8wd2i92xpmwf5bb-invidious.drv
  /nix/store/4x31hx9nxcbbksi2hsim08djrsj4h1zh-images.txt.drv
building '/nix/store/dbl3bzc05pssq3q9g8wd2i92xpmwf5bb-invidious.drv'...
unpacking sources
variable $src or $srcs should point to the source
error: builder for '/nix/store/dbl3bzc05pssq3q9g8wd2i92xpmwf5bb-invidious.drv' failed with exit code 1;
       last 2 log lines:
       > unpacking sources
       > variable $src or $srcs should point to the source
       For full logs, run 'nix log /nix/store/dbl3bzc05pssq3q9g8wd2i92xpmwf5bb-invidious.drv'.

If I try to pull the full logs using the command given, I get the following:

nix log /nix/store/dbl3bzc05pssq3q9g8wd2i92xpmwf5bb-invidious.drv
error: experimental Nix feature 'nix-command' is disabled; use '--extra-experimental-features nix-command' to override

...and if I enable the experimental feature, I see the following:

nix --extra-experimental-features nix-command log /nix/store/dbl3bzc05pssq3q9g8wd2i92xpmwf5bb-invidious.drv
@nix { "action": "setPhase", "phase": "unpackPhase" }
unpacking sources
variable $src or $srcs should point to the source

If I just try to build the same service in a single file, it successfully builds the image:

let
  # nixos-22.05 / https://status.nixos.org/
  pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/d86a4619b7e80bddb6c01bc01a954f368c56d1df.tar.gz") {};
in rec {

  docker = pkgs.dockerTools.buildLayeredImage {
    name = "invidious";
    contents = [ pkgs.busybox pkgs.bash pkgs.invidious ];
    config = {
      Cmd = [ "/bin/sh" ];
      Env = [];
      Volumes = {};
    };
  };

  results = pkgs.writeText "images.txt" ''
    ${docker}
  '';
}

What am I doing wrong with my attempt to use modules?


Solution

  • I figured it out. I didn't need the mkDerivation. I just need the buildLayeredImage

    { pkgs, ... }:
    pkgs.dockerTools.buildLayeredImage {
        name = "invidious";
        contents = [ pkgs.busybox pkgs.bash pkgs.invidious ];
        config = {
          Cmd = [ "/bin/bash" ];
          Env = [];
          Volumes = {};
        };
    }
    

    The service.nix and config.nix stay the same:

    let
      config = import ./config.nix;
      pkgs = config.pkgs;
      invidious = import ./services/invidious.nix;
    in rec {
      serviceimages = pkgs.writeText "images.txt" ''
        ${invidious(pkgs)}
      '';
    }
    
    {
      # nixos-22.05 / https://status.nixos.org/
      pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/d86a4619b7e80bddb6c01bc01a954f368c56d1df.tar.gz") {};
    }