[Solved] Old Python with Conda environment in a Nix build in containers: "required file not found"

Solution below

I am trying to containerise an old legacy Python application using Nix. I managed to use stdenv.mkDerivation to create a derivation that builds the program and I can run it when using nix run .#myService.

I cannot share very much code because this is company code, but here is the derivation a bit changed that is to build the container:

{ pkgs ? import <nixpkgs> { }, myService, registryPrefix ? "" }:
pkgs.dockerTools.buildLayeredImage {
  name = "${registryPrefix}${myService.name}";
  tag = myService.version;
  contents = [
    myService
  ];
  config = {
    Entrypoint = [
      "${myService}/bin/myService"
    ];
  };
}

This builds fine, but when I docker load and docker run it, I get:

/nix/store/3w9plzigvyakxixm7jrgbrk1sglhqwsq-myService/bin/myService: line 3: /nix/store/ja6aizw3kd02a8xiv7qxw7gphhpknv3i-myService-env-0.0.6/bin/python3.8: cannot execute: required file not found

The python3.8 executable exists at this location in the container, and ldd also shows nothing suspicious:

        linux-vdso.so.1 (0x00007ffffff89000)
        libpthread.so.0 => /nix/store/0wydilnf1c9vznywsvxqnaing4wraaxp-glibc-2.39-52/lib/libpthread.so.0 (0x00007ff9b7116000)
        libdl.so.2 => /nix/store/0wydilnf1c9vznywsvxqnaing4wraaxp-glibc-2.39-52/lib/libdl.so.2 (0x00007ff9b7111000)
        libutil.so.1 => /nix/store/0wydilnf1c9vznywsvxqnaing4wraaxp-glibc-2.39-52/lib/libutil.so.1 (0x00007ff9b710c000)
        libm.so.6 => /nix/store/0wydilnf1c9vznywsvxqnaing4wraaxp-glibc-2.39-52/lib/libm.so.6 (0x00007ff9b7026000)
        libc.so.6 => /nix/store/0wydilnf1c9vznywsvxqnaing4wraaxp-glibc-2.39-52/lib/libc.so.6 (0x00007ff9b6e2f000)
        librt.so.1 => /nix/store/0wydilnf1c9vznywsvxqnaing4wraaxp-glibc-2.39-52/lib/librt.so.1 (0x00007ff9b6e28000)
        /lib64/ld-linux-x86-64.so.2 => /nix/store/0wydilnf1c9vznywsvxqnaing4wraaxp-glibc-2.39-52/lib64/ld-linux-x86-64.so.2 (0x00007ff9b7482000)

What should I try next, before using our Company Gitlab, Dockerfiles and classic imperative gitlab-ci and Kaniko to build the container?


Solution

Yesterday I remembered having had this problem with a container I built with classic Dockerfiles and using Alpine as a base image, and it went away when I changed that to Ubuntu. So I tried just using an Ubuntu image as a fromImage:

{ pkgs ? import <nixpkgs> { }, myService, registryPrefix ? "" }:
pkgs.dockerTools.buildLayeredImage {
  name = "${registryPrefix}${myService.name}";
  tag = myService.version;

  # Solution:
  fromImage = pkgs.dockerTools.pullImage {
    imageName = "docker.io/ubuntu";
    imageDigest = "sha256:c920ba4cfca05503764b785c16b76d43c83a6df8d1ab107e7e6610000d94315c";
    finalImageName = "ubuntu";
    finalImageTag = "24.04";
    sha256 = "sha256-HYcO+KPBczsykZj5TkVuIzGnvHqb1ujE4fJuvLKATB0=";
    os = "linux";
    arch = "x86_64";
  };

  contents = [
    myService
  ];

  config = {
    Entrypoint = [
      "${myService}/bin/myService"
    ];
  };
}

With the Ubuntu in the image, the Conda Python is happy.