commercialhaskell / commercialhaskell/stack

Document DIY Docker builds

Open
#3,129 4 comments 0 reactions 0 assignees View on GitHub
component: docker component: docs (online)
Dominant language
Haskell
Stars
4.1k
Forks
850
Avg merge
10h 37m
Merged PRs (30d)
4

Description

My use case is I want to build my Haskell projects with Stack inside a Docker container without having Stack installed. This is so my colleagues can just run `make` on a project without having to install dependencies beyond Docker.

Essentially, I want to do what `stack --docker build` does, but I want to do it by hand.

Requirements:
* a build image that has stack installed and set up
* a way of caching artefacts on the host system between builds
* local, non-Docker `stack` to continue to work

You can see how I've cobbled this together at the moment:
* [project Makefile](https://github.com/weaveworks-experiments/compare-revisions/blob/master/Makefile)
* [build image definition](https://github.com/weaveworks/build-tools/pull/88/files)

The essential ingredients are:
* run `docker` very carefully:

```
docker run --rm -ti \
-e STACK_IN_CONTAINER=1 \
-e STACK_ROOT=$(HOME) \
-e HOME=$(shell pwd)/.stack-work/docker/_home \
-v $(HOME):$(HOME) \
-v $(HOME)/.stack:$(HOME)/.stack \
-v $(shell pwd):$(shell pwd) \
-v $(shell pwd)/.stack-work/docker/_home:$(shell pwd)/.stack-work/docker/_home \
quay.io/weaveworks/build-haskell:latest $@
```
* run `stack` very carefully:

```
stack --internal-re-exec-version=1.3.2 \
--internal-docker-entrypoint "DockerEntrypoint {deUser = Nothing}" \
--docker \
--local-bin-path $(BINARY_DIR) \
--copy-bins \
build
```

`BINARY_DIR` is a Makefile constant which is used in another place in order to gather together the images.

I don't really understand what's going on here. In particular, I don't really know:
* what goes in each of these directories
* where the build artefacts (esp. for dependencies) are cached
* where the package index is stored
* why the whole of `$HOME` needs to be mounted
* what the effect of `STACK_IN_CONTAINER` is
* why the `--internal-docker-entrypoint` and `--internal-re-exec-version` flags are needed

And probably more things also.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.