Hi there,
Is it feasible to share the .cabal/store
betweena host machine an a docker container? Tha use case is that I have a project in my host machine, but I want to build it within a docker container without the need of downloading and building a huge amount of dependencies.
I create a docker image with ghc
and cabal
, then run the container with two mount volumes: one for the source code and one pointing to the cabal’s store
docker run -v $(pwd):/usr/local/project -v ${HOME}/.cabal/store/:/usr/local/.cabal/store:ro -it my-imge
I mount the store’s volume as read-only (:ro
) since I would expect that there is no need to do any other thing in the cabal store other than reading from it, but I might be wrong.
Within the docker’s running container I build the project using a freeze file and with dry-run just to see if It will download something.
# container's console
> cabal update
> cabal --store-dir=/usr/local/.cabal/store build all --dry-run --builddir=dist-newstyle-docke --project-file=cabal.docker-build.project
Resolving dependencies...
Build profile: -w ghc-9.4.8 -O1
In order, the following would be built (use -v for more details):
- zip-2.0.0 (lib) (requires download & build)
- my-project-componets (lib:my-project) (first run)
- my-project (exe:my-project) (first run)
Surprisingly, one hackage dependency needs to be downloaded. The surprise comes from the fact that the project is already built outside the containers with the same freeze file, so I’d expect all dependencies to be on the store.
So, if something needs to be downloaded, for sure the store can’t be read-only, hence I spin up the container again mounting the store as normal, an then building the project. Now the build of the the zip
library fails
# after docker run -v ${HOME}/.cabal/store/:/usr/local/.cabal/store ...
> cabal --store-dir=/usr/local/.cabal/store build all --builddir=dist-newstyle-docker --project-file=cabal.advance-options.project
Starting zip-2.0.0 (lib)
Building zip-2.0.0 (lib)
Failed to build zip-2.0.0.
Build log (
/root/.cache/cabal/logs/ghc-9.4.8/zip-2.0.0-cc40d6442b9486f7cc8d5bf1e8eadd52dcafcd3ea12b53054cb809dd08a19618.log
):
Configuring library for zip-2.0.0..
Preprocessing library for zip-2.0.0..
Building library for zip-2.0.0..
[1 of 5] Compiling Codec.Archive.Zip.CP437 ( Codec/Archive/Zip/CP437.hs, dist/build/Codec/Archive/Zip/CP437.o, dist/build/Codec/Archive/Zip/CP437.dyn_o )
[2 of 5] Compiling Codec.Archive.Zip.Type ( Codec/Archive/Zip/Type.hs, dist/build/Codec/Archive/Zip/Type.o, dist/build/Codec/Archive/Zip/Type.dyn_o )
Codec/Archive/Zip/Type.hs:38:1: error:
Could not find module ‘Data.CaseInsensitive’
There are files missing in the ‘case-insensitive-1.2.1.0’ package,
try running 'ghc-pkg check'.
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
38 | import Data.CaseInsensitive (CI)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.
.
more errors related to missing modules in zip's dependencies.
At this point I wonder if it is possible to share the cabal’s store between host and containerfor faster builds or we are doomed to re-build everything.
BTW: I’ve tried to copy the binary directly but It fails to execute (I think some template haskell is involved)