It’s been a while since I had the pleasure of working with Nix (and Haskell), so instead of just continue writing flakes as I did a couple of years ago I looked around and found https://flake.parts/. I have to say I think I really like it!
Just one little problem I ran into that I can’t figure out on my own: how do I build a Docker image that actually works?
My flake.nix
looks like this
{
nixConfig = {
extra-substituters = [ "https://magthe-fabled.cachix.org" ];
extra-trusted-public-keys = [
"magthe-fabled.cachix.org-1:tx/C7RcEutcCxnAiSRgA94h2LYwKFAW6pCvrtzjJo4E="
];
};
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixpkgs-unstable";
systems.url = "github:nix-systems/default";
flake-parts.url = "github:hercules-ci/flake-parts";
haskell-flake.url = "github:srid/haskell-flake";
};
outputs = inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
systems = import inputs.systems;
imports = [ inputs.haskell-flake.flakeModule ];
perSystem = { self', system, lib, config, pkgs, ... }:
let hsPkgs = pkgs.haskell.packages.ghc96;
in {
haskellProjects.default = {
basePackages = hsPkgs;
packages = { };
devShell = { hlsCheck.enable = false; };
autoWire = [ "packages" ];
};
devShells.default = pkgs.mkShell {
name = "tehst custom development shell";
inputsFrom = [ config.haskellProjects.default.outputs.devShell ];
nativeBuildInputs = with pkgs; [
hsPkgs.cabal-fmt
hsPkgs.haskell-language-server
hsPkgs.hlint
];
};
packages.app = self'.packages.tehst;
packages.default = pkgs.dockerTools.buildImage {
name = "tehst";
tag = "latest";
created = "now";
copyToRoot = pkgs.buildEnv {
name = "image-root";
paths = [ self'.packages.tehst ];
pathsToLink = [ "/bin" ];
};
config = {
Cmd = [ "/bin/tehst" ];
ExposedPorts = { "8080/tcp" = { }; };
WorkdingDir = "/";
};
};
};
};
}
An image is built and it has the expected contents, I can run podman import result tehst:latest
to get it into the local store. However, the image can’t be started:
> podman run localhost/tehst:latest
Error: no command or entrypoint provided, and no CMD or ENTRYPOINT from image
and indeed, when looking at the image using podman inspect
there’s no mention of anything that I’ve specified in config
for dockerTools.buildImage
. What’s happening here? (Could the problem be that there’s an argument to perSystem
that’s called config
? Yes, I’m guessing wildly.)
Quite possibly I’m going about this in the wrong way. What am I missing? What should I change to make it work?