Skip to main content

Building Static Executables With Stack

In the past, I have spent quite a bit of time trying to build fully static executables for Haskell projects. Tired of wrestling Nix, I eventually found that I was able to easily build fully static executables for projects without special dependencies using Docker images provided by the Stack team. The recent Stackage releases include an LTS release that uses GHC 9.0.2, but a corresponding Docker image was not released in the repository that I have been using. I inquired in an issue and am learning about the intended purposes of the various Docker images. Things are working now, but I need to consider what to do in the future.

The Stack team has provided the fpco/stack-build image repository for many years, and stack --docker functionality uses this repository by default. When I was developing lsupg last summer, however, the repository had stopped updating. Based on a comment that I am no longer able to find, I got the impression that the commercialhaskell/stackage image repository was a replacement. I even created an issue about updating Stack to use the new image repository.

An lts19 image has not been pushed to the commercialhaskell/stackage image repository. I learned that this repository was only intended to build Stackage itself, and the GitHub package registry is now used instead of Docker Hub. I see that lts18, lts19, and nightly tags are currently available. I was unsure if Stack supports using images from other registries, but I tried configuring docker.repo to ghcr.io/commercialhaskell/stackage/build:nightly and it works without issue.

I also learned that the fpco/stack-build image repository is being updated again! The lts-18* images do not include the libraries necessary for building static executables, but the new lts-19 image does! I am not sure if future images will include such libraries or not.

If I should not rely on any of these Stack images, I can migrate my projects to ghc-musl, which can also be used with Stack.

Note that my goal is to make it easy to build fully static executables using multiple versions of GHC. I updated the lsupg project this morning so that it supports building fully static executables using the following versions of GHC:

GHC 9.0.2 is my current default because it is used by the most recent LTS release. This default is configured by a symbolic link from stack.yaml to stack-9.0.2.yaml. Please note that this change is in the develop branch and has not yet been merged into the main branch.