Nix: reproducible build







Hello Habrousers!







Today we will continue our series of articles on Nix and how we use it at Typeable.







The first post in a series covering the basics of the Nix language can be read here .







Haskell , , Haskell . , .







Github.









CI — . . Nix , . Nix , , .









, , . , Haskell, Hello world.







Main.hs



:







module Main where

main :: IO ()
main = putStrLn "Hello, World!"
      
      





Nix stack



( ). stack stack.yaml



, resolver



. — Hackage, Haskell, , (NB ): ).







stack.yaml



:







resolver: lts-17.11

packages:
- hello-world
      
      





hello-world.cabal



:







cabal-version:      2.4
name:               hello-world
version:            1.0
synopsis:           Hello World
license:            MIT
license-file:       LICENSE
author:             Nick

executable hello-world
    main-is:          Main.hs
    build-depends:    base >= 4 && < 5
    hs-source-dirs:   src
    default-language: Haskell2010
    ghc-options:      -Wall -O2
      
      





Nix , . , , :







$ stack run hello-world
Hello, World!
      
      





Come to the dar^Wnix side, we have cookies!



stack — Haskell, . Haskell Nix haskell.nix, IOHK. - . , , Nix.







Haskell.nix .cabal



- stack.yaml



derivation



Nix.







nix/stackyaml.nix



:







{
  #    haskell.nix  GitHub   Nixpkgs   .
  haskellNix ? import (builtins.fetchTarball "https://github.com/input-output-hk/haskell.nix/archive/b0d03596f974131ab64d718b98e16f0be052d852.tar.gz") {}
  #       Nixpkgs.  21.05   :)
, nixpkgsSrc ? haskellNix.sources.nixpkgs-2009
, nixpkgsArgs ? haskellNix.nixpkgsArgs
, pkgs ? import nixpkgsSrc nixpkgsArgs
}:

let
  #     stack.   Cabal   cabalProject.
  project = pkgs.haskell-nix.stackProject {
    name = "hello-world";

    # Derivation    .
    #  cleanGit      ,    git-.
    src = pkgs.haskell-nix.haskellLib.cleanGit {
      name = "hello-world";

      #  src     ,  stack.yaml.
      src = ../.;

      # keepGitDir   .git  .
      #    , ,      .
      keepGitDir = true;
    };

    #   modules         ,      .
    modules = [{
      # doCheck    -   ,       .
      #     ,       false     
      # .
      doCheck = false;

      #    Hello World  -Werror.
      packages.hello-world.components.exes.hello-world.ghcOptions = [ "-Werror" ];
    }];
  };

#       project --  ,   pkgs --  nixpkgs,     .
in { inherit project; inherit pkgs; }
      
      





, Nix. nix build



. , result



, .







$ nix build project.hello-world.components.exes
$ ./result/bin/hello-world
Hello, World!
      
      





! , . !







Dockerfile? Dockerfile?



2021 , Docker . Typeable . nixpkgs



dockerTools



. , , . nix/docker.nix



.







, . Nix - , , , . , , . CentOS.







sourceImage = dockerTools.pullImage {
  imageName = "centos";
  imageDigest = "sha256:e4ca2ed0202e76be184e75fb26d14bf974193579039d5573fb2348664deef76e";
  sha256 = "1j6nplfs6999qmbhjkaxwjgdij7yf31y991sna7x4cxzf77k74v3";
  finalImageTag = "7";
  finalImageName = "centos";
};
      
      





, - Docker. Nix, Docker Registry sourceImage



.







dockerTools buildImage



. , , :







makeDockerImage = name: revision: packages: entryPoint:
  dockerTools.buildImage {
    name = name;
    tag = revision;
    fromImage = sourceImage;
    contents = (with pkgs; [ bashInteractive coreutils htop strace vim ]) ++ packages;
    config.Cmd = entryPoint;
  };
      
      





makeDockerImage



: , ( Typeable git ), , , . CentOS (fromImage



), , .







, , .







hello-world = project.hello-world.components.exes.hello-world;
helloImage = makeDockerImage "hello" 
  (if imageTag == null then "undefined" else imageTag)
  [ hello-world ]
  [ "${hello-world}/bin/hello-world"
  ];
      
      





, project.hello-world...



. , makeDockerImage



, hello-world



. imageTag



, , "undefined" .







:







$ nix build --argstr imageTag 1.0 helloImage
[4 built, 0.0 MiB DL]

 $ ls -l result
lrwxrwxrwx 1 user users 69 May 11 13:12 result -> /nix/store/56qqhiwahyi46g6mf355fjr1g6mcab0b-docker-image-hello.tar.gz
      
      





result



, . , .







$ docker load < result 
76241b8b0c76: Loading layer [==================================================>]  285.9MB/285.9MB
Loaded image: hello:1.0
$ docker run hello:1.0
Hello, World!
      
      







, , Haskell. , haskell.nix - , : nixpkgs C/C++, Python, Node .







, Nix. Stay tuned!








All Articles