Creating docker image from dev flake

Hello,

I’m currently working on a project with a backend in rust and a frontend in nuxt. I’m leveraging a Nix flake for the development environment

And I have a Dockerfile for building the released version of the app.

I feel the docker file is redundent and I’d like to only use Nix for the project: is there a way I can add an output to the flake that would be the equivalent of the Dockerfile, but using the flake ? I feel it would also help me speed up builds if I leverage something like Cachix.

Thanks for your help !

Yes, Nix is perfect for building docker images.

Roughly speaking, in your case there are three required steps:

  1. Write a Nix derivation for your backend. You can use pkgs.rustPlatform.buildRustPackage for that: nixpkgs/doc/languages-frameworks/rust.section.md at 06164c1e58ce2f5df4c93691b741d1131fe64ecf · NixOS/nixpkgs · GitHub
  2. Write a Nix derivation for your frontend. You are using Yarn 1, so you can have a look at nixpkgs/doc/languages-frameworks/javascript.section.md at 06164c1e58ce2f5df4c93691b741d1131fe64ecf · NixOS/nixpkgs · GitHub
  3. Bundle it in a Docker image. See Nix is a better Docker image builder than Docker's image builder - Xe Iaso, nixpkgs/doc/build-helpers/images/dockertools.section.md at 06164c1e58ce2f5df4c93691b741d1131fe64ecf · NixOS/nixpkgs · GitHub and/or GitHub - nlewo/nix2container: An archive-less dockerTools.buildImage implementation
1 Like

Thank you for the insights !

Here is my application of the steps, but I cannot manage to build the frontend (it is a single page app, static files I want to add a derivation with the build result and serve this).

backend = rustPlatform.buildRustPackage rec {
  name = "safehaven-backend";
  version = "current";
  src = ./backend;
  cargoSha256 = "sha256-t1q0CNiRtHohMmAkQ7LdGsOk4NWKndYdCmuYCDIIg3o=";
};

frontend = pkgs.mkYarnPackage {
  name = "safehaven-frontend";
  version = "current";
  src = ./frontend;

  buildPhase = ''
    export HOME=$(mktemp -d)
    yarn --offline generate
    cp -rv dist $out/static
  '';
};

dockerImage = pkgs.dockerTools.buildImage {
  name = "safehaven";
  tag = "latest";
  contents = [backend frontend];
  config = {
    Cmd = ["${backend}/bin/safehaven"];
    Env = [
      "SAFEHAVEN_serve_public_path=${frontend}"
    ];
    ExposedPorts = {"28669/tcp" = {};};
  };
};

It gives me this output:

error: builder for '/nix/store/adgxyvclfiykn41qfknys0wykg4b6jav-safehaven-frontend.drv' failed with exit code 127;
       last 10 log lines:
       > source root is frontend
       > Running phase: patchPhase
       > Running phase: updateAutotoolsGnuConfigScriptsPhase
       > Running phase: configurePhase
       > Running phase: buildPhase
yarn run v1.22.22
$ nuxt generate
       > /bin/sh: nuxt: not found
error Command failed with exit code 127.

I do not understand how I’m supposed to use the mkYarnPackage to build the files. Do you have any idea ?

EDIT: Turns out it was related to Node 20, it works properly with Node 18.

1 Like