简体   繁体   English

仅在没有堆栈的情况下构建 LTS 依赖项。yaml

[英]Build LTS dependencies only with no stack.yaml

I would like to implement a multistage Dockerfile with three stages:我想实现一个具有三个阶段的多级 Dockerfile:

  1. pull fpco/stack-build:lts-17.12 and build all LTS dependencies拉取fpco/stack-build:lts-17.12并构建所有 LTS 依赖项
  2. copy stack.yaml and package.yml and build all extra-deps复制stack.yamlpackage.yml并构建所有额外的deps
  3. copy .复制. and build the actual project并构建实际项目

So 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.yamlpackage.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.yamlpackage.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.yamlpackage.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.yamlpackage.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.yamlpackage.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM