<div dir="ltr"><div dir="ltr"><div dir="ltr">We're dealing with this same hassle at Slant. For starters, instead of your hello-world build, you can use:<div><br></div><div><font face="monospace, monospace">stack build --dependencies-only</font></div><div><br></div><div>We've gone a few steps farther to make Kubernetes deployment easier. We have a base container for web services with this Dockerfile:</div><div><br></div><div><div><font face="monospace, monospace">FROM haskell:8.2.1 as buildenv</font></div><div><font face="monospace, monospace">WORKDIR /app</font></div><div><font face="monospace, monospace">RUN apt-get update && apt-get -y install make xz-utils libpq-dev</font></div><div><font face="monospace, monospace">RUN stack upgrade --binary-version 1.6.1</font></div><div><font face="monospace, monospace">RUN stack update && stack setup --resolver lts-11.22</font></div><div><font face="monospace, monospace">RUN stack build Cabal --resolver lts-11.22</font></div><div><font face="monospace, monospace">RUN stack build haskell-src-exts --resolver lts-11.22</font></div><div><font face="monospace, monospace">RUN stack build lens --resolver lts-11.22</font></div><div><font face="monospace, monospace">RUN stack build aeson --resolver lts-11.22</font></div><div><font face="monospace, monospace">RUN stack build http-conduit --resolver lts-11.22</font></div><div><font face="monospace, monospace">RUN stack build servant-server --resolver lts-11.22</font></div></div><div><br></div><div>We'll occasionally make a new version of this with a bumped LTS version. When we started there was no official 8.4-base docker image, but since we're using stack it doesn't really matter. The explicit install of stack-1.6.1 is due to an error that occurs when trying to pull indexes with 1.7.1 on the kubernetes build server; there's probably a cleaner solution but we're not using any 1.7.1 features yet. Optimally the order here should be "least likely to change goes first" but we haven't done any real analysis on that.</div><div><br></div><div>From here, individual services have a Dockerfile roughly like so:</div><div><br></div><div><div><font face="monospace, monospace">FROM debian:jessie as runtimeenv</font></div><div><font face="monospace, monospace">RUN apt-get update && apt-get install -y libgmp-dev && rm -rf /var/lib/apt/lists/*</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">FROM <private>/haskell-webserver:lts-11.22 as dependencies</font></div><div><font face="monospace, monospace"># pre-build any additional slow local dependencies</font></div><div><font face="monospace, monospace">COPY stack.yaml .</font></div><div><font face="monospace, monospace">COPY package.yaml .</font></div><div><font face="monospace, monospace">COPY submodules ./submodules</font></div><div><font face="monospace, monospace">RUN rm -rf ~/.stack/indices/</font></div><div><font face="monospace, monospace">RUN stack build --dependencies-only</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">FROM dependencies as build</font></div><div><font face="monospace, monospace">COPY . .</font></div><div><font face="monospace, monospace">RUN stack build --ghc-options="-O2" # additional options as desired</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">FROM runtimeenv</font></div><div><font face="monospace, monospace">WORKDIR /app</font></div><div><font face="monospace, monospace">COPY --from=build /app/.stack-work/install/x86_64-linux/lts-11.22/8.2.2/bin/app-name-exe .</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">CMD ./app-name-exe</font></div></div><div><br></div><div>This gives us a reasonable build speed and nice lean deploy container.</div><div><br></div></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Sep 4, 2018 at 4:22 AM Daniel Rolls via Haskell-Cafe <<a href="mailto:haskell-cafe@haskell.org">haskell-cafe@haskell.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I am building Haskell web services using docker. I do this utilising the stack tool within the official Haskell Docker image. Doing this has a number of advantages<div><br></div><div>- It's predictable - I can control bringing in new versions of stack and ghc.</div><div>- It's easy to share - no stack or Haskell installation is required to build the image</div><div>- These services can interact with other services in a controlled environment using Docker compose.</div><div><br></div><div>One downside is that I doing this naively means waiting for a modules to download every time docker build is run since the stack build command will start from scratch each time. I worked around this by adding two build steps. The first runs a hello world example with the stack.yml and package.yml from my project. The second build builds the intended code. This trick separated the downloading of dependent libraries from building the code and means day to day code changes are quick to build since the first stack build is cached as a docker image layer. Still though, making a small change to a stack yml file means a long wait re-downloading all dependent libraries.</div><div><br></div><div>Firstly, is there a better way of doing this? I know stack supports building within docker but when I worked this way I still found projects depended on the system stack and would commonly fail due to stack bugs.</div><div><br></div><div>Secondly, my two "stack build" calls where the first builds a hello world program feels a bit hacky. is there a better way to achieve this?</div><div><br></div><div>Thanks,</div><div>Dan</div><div><br></div><div class="m_-5074905442109961828gmail-yj6qo"></div><br class="m_-5074905442109961828gmail-Apple-interchange-newline"></div>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</blockquote></div>