3

I am in the process of creating a Dockerfile that can build a haskell program. The Dockerfile uses ubuntu focal as a base image, installs ghcup, and then builds a haskell program. There are multiple reasons why I am doing this; it can support a low-configuration CI environment, and it can help new developers who are trying to build a complicated project.

In order to speed up build times, I am using docker v20 with buildkit. I have a sequence of events like this (it's quite a long file, but this excerpt is the relevant part):

# installs haskell
WORKDIR $HOME
RUN git clone https://github.com/haskell/ghcup-hs.git
WORKDIR ghcup-hs
RUN BOOTSTRAP_HASKELL_NONINTERACTIVE=NO ./bootstrap-haskell
#RUN source ~/.ghcup/env  # Uh-oh: can't do this.
# We recreate the contents of ~/.ghcup/env
ENV PATH=$HOME/.cabal/bin:$HOME/.ghcup/bin:$PATH

# builds application
COPY application $HOME/application
WORKDIR $HOME/application
RUN mkdir -p logs
RUN --mount=type=cache,target=$HOME/.cabal \
    --mount=type=cache,target=$HOME/.ghcup \
    --mount=type=cache,target=$HOME/application/dist-newstyle \
    cabal build |& tee logs/configure.log

But when I change some non-code files (README.md for example) in application, and build my docker image ...

DOCKER_BUILDKIT=1 docker build -t application/application:1.0 .

... it takes quite a bit of time and the output from cabal build includes a lot of Downloading [blah] followed by Building/Installing/Completed messages from cabal install.

However when I go into my container and type cabal build, it is much faster (it is already built):

host$ docker run -it application/application:1.0
container$ cabal build  # this is fast

I would expect it to be just as fast in the prior case as well. Since I have not really changed the code files, and the dependencies are all downloaded, and since I am using RUN --mount.

Are there files somewhere that my --mount=type=cache entries are not covering? Is there a package registry file somewhere that I need to include in its own --mount=type=cache line? As far as I can tell, my builds ought to be nearly instant instead of taking several minutes to complete.

Erasmus
  • 596
  • 5
  • 8
  • There's also `~/.ghc/${arch}-${ghcver}/` which hosts the user-global *package database* of GHC. Basically, Cabal installs packages under `~/.cabal` but also links them from `~/.ghc` so that e.g. `ghci` knows about them. Not entirely sure it's the issue you had, but could be related. – ulidtko Apr 05 '22 at 13:23

0 Answers0