I built a containerized Azure Function App that internlly runs a haskell program packaged with Nix.
I followed Create your first containerized functions on Azure Container Apps to make a scaffold. Runtime could be anything than can run sub process, which is everything. So I choose dotnet.
And at the end of the generated Dockerfile, I added some nix layers.
# Basic runtime to install nix
RUN apt install -y xz-utils curl
RUN bash -c "sh <(curl -L https://nixos.org/nix/install) --daemon --yes"
# Update PATH to include nix tools
ENV PATH="/home/.nix-profile/bin:/nix/var/nix/profiles/default/bin:${PATH}"
Then I copied my haskell project.
ADD haskell-project /opt/haskell-project
Create haskell package using cabal2nix
. I call nix-collect-garbage
to reduce the size of docker layer.
RUN nix-shell -p cabal2nix --run 'cabal2nix --no-check /opt/haskell-project > /opt/haskell-project/foo.nix' && nix-collect-garbage
The default.nix
would look like this. It calls the haskell package and wrap it with justStaticExecutables to leave only runtime dependencies.
let
p = (import <nixpkgs> {}).pkgs;
in
p.haskell.lib.compose.justStaticExecutables (p.haskellPackages.callPackage ./foo.nix {})
Build the nix package
RUN nix-build
In the Function implementation, run the hasell executable as a subprocess
using System.Diagnostics;
using (Process hs = new Process())
{
hs.StartInfo.UseShellExecute = true;
hs.StartInfo.FileName = "/opt/haskell-project/result/bin/exe";
hs.Start();
await hs.WaitForExitAsync();
if (hs.ExitCode != 0)
{
throw new Exception($"haskell subprocess failed {hs.ExitCode}");
}
}
Top comments (0)