Home Explore Blog CI



nixpkgs

4th chunk of `doc/languages-frameworks/beam.section.md`
16a4f89e997f274a324ebd1b86fcb09ef3b0bc1b4e0bce9c0000000100000e8c
##### 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 {
  inherit
    src
    pname
    version
    mixFodDeps
    ;
  # if you have build time environment variables add them here
  MY_ENV_VAR = "my_value";

  postBuild = ''
    ln -sf ${nodeDependencies}/lib/node_modules assets/node_modules
    npm run deploy --prefix ./assets

    # for external task you need a workaround for the no deps check flag
    # https://github.com/phoenixframework/phoenix/issues/2690
    mix do deps.loadpaths --no-deps-check, phx.digest
    mix phx.digest --no-deps-check
  '';
}
```

Setup will require the following steps:

- Move your secrets to runtime environment variables. For more information refer to the [runtime.exs docs](https://hexdocs.pm/mix/Mix.Tasks.Release.html#module-runtime-configuration). On a fresh Phoenix build that would mean that both `DATABASE_URL` and `SECRET_KEY` need to be moved to `runtime.exs`.
- `cd assets` and `nix-shell -p node2nix --run "node2nix --development"` will generate a Nix expression containing your frontend dependencies
- commit and push those changes
- you can now `nix-build .`
- To run the release, set the `RELEASE_TMP` environment variable to a directory that your program has write access to. It will be used to store the BEAM settings.

#### Example of creating a service for an Elixir - Phoenix project {#example-of-creating-a-service-for-an-elixir---phoenix-project}

In order to create a service with your release, you could add a `service.nix`
in your project with the following

```nix
{
  config,
  pkgs,
  lib,
  ...
}:

let
  release = pkgs.callPackage ./default.nix;
  release_name = "app";
  working_directory = "/home/app";
in
{
  systemd.services.${release_name} = {
    wantedBy = [ "multi-user.target" ];
    after = [
      "network.target"
      "postgresql.service"
    ];
    # note that if you are connecting to a postgres instance on a different host
    # postgresql.service should not be included in the requires.
    requires = [
      "network-online.target"
      "postgresql.service"
    ];
    description = "my app";
    environment = {
      # RELEASE_TMP is used to write the state of the
      # VM configuration when the system is running
      # it needs to be a writable directory
      RELEASE_TMP = working_directory;
      # can be generated in an elixir console with
      # Base.encode32(:crypto.strong_rand_bytes(32))
      RELEASE_COOKIE = "my_cookie";
      MY_VAR = "my_var";
    };
    serviceConfig = {
      Type = "exec";
      DynamicUser = true;
      WorkingDirectory = working_directory;
      # Implied by DynamicUser, but just to emphasize due to RELEASE_TMP
      PrivateTmp = true;
      ExecStart = ''
        ${release}/bin/${release_name} start

Title: Phoenix Project Example and Service Creation with Nix
Summary
This section provides a complete example of a `default.nix` file for a Phoenix project, showcasing how to use `mixRelease` with `mixFodDeps` and manage node dependencies. It emphasizes the importance of runtime environment variables for secrets and describes the process of generating a Nix expression for frontend dependencies. The section also details the necessary steps to build the project with Nix and run the release. Furthermore, it includes an example `service.nix` file for creating a systemd service, covering service configuration, environment variables, and dependencies for an Elixir-Phoenix application.