仅在没有 stack.yaml 的情况下构建 LTS 依赖项

时间:2021-05-25 17:26:26

标签: haskell haskell-stack

我想实现一个包含三个阶段的多阶段 Dockerfile:

  1. 拉取 fpco/stack-build:lts-17.12 并构建所有 LTS 依赖项
  2. 复制 stack.yamlpackage.yml 并构建所有 extra-deps
  3. 复制 . 并构建实际项目

到目前为止,我设法将 2 和 3 分开,但 1 和 2 仍然一起执行,这意味着每次 stack.yamlpackage.yaml 更改时,都需要重新编译整个 LTS。每次大约需要 20 分钟,而在本地开发(没有 Docker)中,当我修改 stack.yamlpackage.yaml 时,只会编译“新东西”,而且通常很快。

在单独的 Docker 阶段执行此“仅 LTS”首次编译将允许 Docker 缓存结果并避免一直重新编译所有内容。

当我在没有 YAML 文件的情况下尝试 stack build --dependencies-only 时,Stack 抱怨此文件夹不是 Stack 项目目录。

是否可以只预编译 LTS 而没有 yaml 文件,然后根据 stack.yaml 编译项目?

1 个答案:

答案 0 :(得分:2)

事实证明,我的问题,正如措辞一样,没有意义。

Stack 不会“编译整个 LTS”。它只编译项目依赖项需要的模块。因此,如果没有 stack.yamlpackage.yaml(或 project.cabal),它什么也做不了。

一种解决方法是使用一个 long-term 子文件夹,其中包含一个 stack.yaml 和一个 package.yaml 文件,其中列出了很少更改的依赖项(例如 aeson、{{1} }, text...).

bytestring

然后在 Dockerfile 的第一阶段:

project-dir/
    long-term/
        stack.yaml
        package.yaml
    stack.yaml
    package.yaml

只要不触及这两个长期文件,Docker 就会很乐意重用缓存的结果。

现在,对“实际”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 stack.yaml 进行一行更改不需要重新编译整个世界。

--

松散的灵感来自:https://gist.github.com/and-pete/e8fd63d51121c61d25461bcc2b3fe743

相关问题