Home Explore Blog CI



nixpkgs

3rd chunk of `doc/languages-frameworks/beam.section.md`
27a6cbb2551b9f9658bd3e4a99020e9b259fa23c0f4131250000000100000fa2
Note that currently mix2nix can't handle git dependencies inside the mix.lock file. If you have git dependencies, you can either add them manually (see [example](https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/pleroma/default.nix#L20)) or use the FOD method.

The advantage of using mix2nix is that nix will know your whole dependency graph. On a dependency update, this won't trigger a full rebuild and download of all the dependencies, where FOD will do so.

Practical steps:

- run `mix2nix > mix_deps.nix` in the upstream repo.
- pass `mixNixDeps = with pkgs; import ./mix_deps.nix { inherit lib beamPackages; };` as an argument to mixRelease.

If there are git dependencies.

- You'll need to fix the version artificially in mix.exs and regenerate the mix.lock with fixed version (on upstream). This will enable you to run `mix2nix > mix_deps.nix`.
- From the mix_deps.nix file, remove the dependencies that had git versions and pass them as an override to the import function.

```nix
{
  mixNixDeps = import ./mix.nix {
    inherit beamPackages lib;
    overrides = (
      final: prev: {
        # mix2nix does not support git dependencies yet,
        # so we need to add them manually
        prometheus_ex = beamPackages.buildMix rec {
          name = "prometheus_ex";
          version = "3.0.5";

          # Change the argument src with the git src that you actually need
          src = fetchFromGitLab {
            domain = "git.pleroma.social";
            group = "pleroma";
            owner = "elixir-libraries";
            repo = "prometheus.ex";
            rev = "a4e9beb3c1c479d14b352fd9d6dd7b1f6d7deee5";
            hash = "sha256-U17LlN6aGUKUFnT4XyYXppRN+TvUBIBRHEUsfeIiGOw=";
          };
          # you can re-use the same beamDeps argument as generated
          beamDeps = with final; [ prometheus ];
        };
      }
    );
  };
}
```

You will need to run the build process once to fix the hash to correspond to your new git src.

###### FOD {#fixed-output-derivation}

A fixed output derivation will download mix dependencies from the internet. To ensure reproducibility, a hash will be supplied. Note that mix is relatively reproducible. An FOD generating a different hash on each run hasn't been observed (as opposed to npm where the chances are relatively high). See [elixir-ls](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/beam-modules/elixir-ls/default.nix) for a usage example of FOD.

Practical steps

- start with the following argument to mixRelease

```nix
{
  mixFodDeps = fetchMixDeps {
    pname = "mix-deps-${pname}";
    inherit src version;
    hash = lib.fakeHash;
  };
}
```

The first build will complain about the hash value, you can replace with the suggested value after that.

Note that if after you've replaced the value, nix suggests another hash, then mix is not fetching the dependencies reproducibly. An FOD will not work in that case and you will have to use mix2nix.

##### mixRelease - example {#mix-release-example}

Here is how your `default.nix` file would look for a phoenix project.

```nix
with import <nixpkgs> { };

let
  # beam.interpreters.erlang_26 is available if you need a particular version
  packages = beam.packagesWith beam.interpreters.erlang;

  pname = "your_project";
  version = "0.0.1";

  src = builtins.fetchgit {
    url = "ssh://git@github.com/your_id/your_repo";
    rev = "replace_with_your_commit";
  };

  # if using mix2nix you can use the mixNixDeps attribute
  mixFodDeps = packages.fetchMixDeps {
    pname = "mix-deps-${pname}";
    inherit src version;
    # nix will complain and tell you the right value to replace this with
    hash = lib.fakeHash;
    mixEnv = ""; # default is "prod", when empty includes all dependencies, such as "dev", "test".
    # if you have build time environment variables add them here
    MY_ENV_VAR = "my_value";
  };

  nodeDependencies = (pkgs.callPackage ./assets/default.nix { }).shell.nodeDependencies;

in
packages.mixRelease {

Title: Packaging Mix Dependencies: mix2nix vs. Fixed-Output-Derivation (FOD)
Summary
This section compares two methods for packaging Mix dependencies in Nix: `mix2nix` and Fixed-Output-Derivation (FOD). `mix2nix` generates a Nix expression from a mix.lock file, enabling Nix to understand the entire dependency graph and avoid full rebuilds on updates. However, it currently doesn't handle Git dependencies directly, requiring manual addition or the use of FOD. FOD downloads dependencies from the internet, relying on a hash for reproducibility. Practical steps and examples are provided for both methods, including handling Git dependencies with `mix2nix` and initial setup for FOD with `fetchMixDeps`.