我想实现一个包含三个阶段的多阶段 Dockerfile:
fpco/stack-build:lts-17.12
并构建所有 LTS 依赖项stack.yaml
和 package.yml
并构建所有 extra-deps.
并构建实际项目到目前为止,我设法将 2 和 3 分开,但 1 和 2 仍然一起执行,这意味着每次 stack.yaml
或 package.yaml
更改时,都需要重新编译整个 LTS。每次大约需要 20 分钟,而在本地开发(没有 Docker)中,当我修改 stack.yaml
或 package.yaml
时,只会编译“新东西”,而且通常很快。
在单独的 Docker 阶段执行此“仅 LTS”首次编译将允许 Docker 缓存结果并避免一直重新编译所有内容。
当我在没有 YAML 文件的情况下尝试 stack build --dependencies-only
时,Stack 抱怨此文件夹不是 Stack 项目目录。
是否可以只预编译 LTS 而没有 yaml
文件,然后根据 stack.yaml
编译项目?
答案 0 :(得分:2)
事实证明,我的问题,正如措辞一样,没有意义。
Stack 不会“编译整个 LTS”。它只编译项目依赖项需要的模块。因此,如果没有 stack.yaml
和 package.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