[英]Build LTS dependencies only with no stack.yaml
I would like to implement a multistage Dockerfile with three stages:我想实现一个具有三个阶段的多级 Dockerfile:
fpco/stack-build:lts-17.12
and build all LTS dependenciesfpco/stack-build:lts-17.12
并构建所有 LTS 依赖项stack.yaml
and package.yml
and build all extra-depsstack.yaml
和package.yml
并构建所有额外的deps.
.
and build the actual projectSo far I managed to separate 2 and 3, but 1 and 2 are still executed together, which means that every single time either stack.yaml
or package.yaml
change, the entire LTS needs to be recompiled.到目前为止,我设法将 2 和 3 分开,但 1 和 2 仍然一起执行,这意味着每次
stack.yaml
或package.yaml
都需要重新编译。 This takes roughly 20 minutes every time, whereas in local dev (without Docker), when I modify stack.yaml
or package.yaml
, only the "new stuff" gets compiled and it's usually very quick.每次大约需要 20 分钟,而在本地开发人员(没有 Docker)中,当我修改
stack.yaml
或package.yaml
时,通常只会很快得到“新的东西”。
Doing this "LTS-only" first compilation in a separate Docker stage would allow Docker to cache the results and avoid recompiling everything all the time.在单独的 Docker 阶段执行此“仅 LTS”首次编译将允许 Docker 缓存结果并避免一直重新编译所有内容。
When I try to stack build --dependencies-only
with no YAML files, Stack complains that this folder is not a Stack project directory.当我尝试在没有 YAML 文件的情况下
stack build --dependencies-only
时,Stack 抱怨此文件夹不是 Stack 项目目录。
Is it possible to pre-compile only the LTS with no yaml
file and, thereafter, compile the project based on stack.yaml
?是否可以只预编译没有
yaml
文件的 LTS,然后基于stack.yaml
编译项目?
It turns out that my question, as it is phrased, doesn't make sense.事实证明,我的问题,正如它所说的那样,没有意义。
Stack doesn't "compile the entire LTS". Stack 不会“编译整个 LTS”。 It compiles only the modules that the project's dependencies need.
它只编译项目依赖项需要的模块。 Therefore, it can't do anything without a
stack.yaml
and a package.yaml
(or project.cabal
).因此,如果没有
stack.yaml
和package.yaml
(或project.cabal
),它什么也做不了。
A workaround is to use a long-term
subfolder with a stack.yaml
and a package.yaml
files listing the dependencies that will change very rarely (say aeson
, text
, bytestring
...).一种解决方法是使用带有堆栈
long-term
子文件夹stack.yaml
和package.yaml
文件列出了依赖关系的text
,说很少会改变bytestring
aeson
)
project-dir/
long-term/
stack.yaml
package.yaml
stack.yaml
package.yaml
Then in the first stage of the Dockerfile:然后在Dockerfile的第一阶段:
FROM fpco/stack-build:lts-17.12 as dependencies
# ...
COPY ./long-term/stack.yaml ./long-term/package.yaml ./
RUN stack build --test --no-run-tests --dependencies-only
COPY ./stack.yaml ./package.yaml ./stack.yaml.lock ./
RUN stack build --test --no-run-tests --dependencies-only
As long as these two long-term files aren't touched, Docker will happily reuse the cached results.只要不碰这两个长期文件,Docker 就会愉快地重用缓存的结果。
And now, making a one-line change into the "actual" stack.yaml
or package.yaml
doesn't need to recompile the whole world.现在,对“实际”堆栈进行一行更改
stack.yaml
或package.yaml
不需要重新编译整个世界。
-- --
Loose inspiration taken from: https://gist.github.com/and-pete/e8fd63d51121c61d25461bcc2b3fe743灵感来源于: https://gist.github.com/and-pete/e8fd63d51121c61d25461bcc2b3fe743
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.