Skip to content
Switch branches/tags

Latest commit

This change includes the dash character (`-`) in the default `BASE_TAG`
argument, and all uses of this argument are updated accordingly.  With
the default configuration, there are no changes.

This is necessary in order to support tags that are not prefixed with
the version number.  For example, somebody may use the project to build
images internally using a custom image name and tag as follows,
resulting in an image tagged as `acme/ghc-musl:ghc922`.

    $ earthly --allow-privileged --build-arg BASE_TAG=acme/ghc-musl: +ghc922

Git stats


Failed to load latest commit information.
Latest commit message
Commit time


This repository provides Docker images with GHC compiled with musl; therefore can be used to create fully static Haskell binaries without glibc dependency on any platform which can run Docker (x86_64). Powered by ghcup.

Images come with ghc and cabal executables alongside with commonly used libraries and build tools. They can also be used with the stack build tool using its Docker integration.

Here are the latest images currently published in Docker Hub:

  • utdemir/ghc-musl:v24-ghc922
  • utdemir/ghc-musl:v24-ghc902
  • utdemir/ghc-musl:v24-ghc8107
  • utdemir/ghc-musl:v24-ghc884



Mount the project directory to the container, and use cabal-install with --enable-executable-static flag inside the container:

$ cd myproject/
$ docker run -itv $PWD:/mnt utdemir/ghc-musl:v24-ghc922
sh$ cd /mnt
sh$ cabal new-update
sh$ cabal new-build --enable-executable-static

You can also set executable-static option on your cabal.project file.


Use below arguments, or set the relevant options on your stack.yaml:

stack build \
  --ghc-options ' -static -optl-static -optl-pthread -fPIC' \
  --docker --docker-image "utdemir/ghc-musl:v24-ghc922" \

Make sure to pick an image with the GHC version compatible with the Stackage resolver you are using.

Follow commercialhaskell/stack#3420 for more details on static compilation using the Stack build tool.

Example session with GHC

Below shell session shows how to start a pre-compiled docker container and compile a simple Hello.hs as a static executable:

$ docker run -itv $PWD:/mnt utdemir/ghc-musl:v24-ghc922
bash-4.4# cd /mnt/
bash-4.4# cat Hello.hs
main = putStrLn "Hello"
bash-4.4# ghc --make -optl-static -optl-pthread Hello.hs
[1 of 1] Compiling Main             ( Hello.hs, Hello.o )
Linking Hello ...
bash-4.4# ls -al Hello
-rwxr-xr-x 1 root root 1185056 Aug 11 16:55 Hello
bash-4.4# file Hello
Hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped
bash-4.4# ldd ./Hello
ldd: ./Hello: Not a valid dynamic program

The result can be executed on different Linux systems:

$ docker run -itv $PWD:/mnt alpine
# /mnt/Hello
$ docker run -itv $PWD:/mnt centos
[root@94eb29dcdfe6 /]# /mnt/Hello


Feel free to open an issue or send a PR to add a library or support a newer compiler version.

The build process is orchestrated using Earthly. Once it is installed (or obtained via "nix-shell -p earthly"), you can use below command to build and test all images, and generate an updated

earthly --allow-privileged --artifact +all/

Note: --allow-privileged is only necessary because we use Docker-in-Docker project to test if the generated images work with stack's Docker support. Feel free to comment out BUILD +test-stack line to test without passing --allow-privileged.