yesodweb / yesod-scaffold

The Yesod scaffolding, with branches for different versions.
MIT License
76 stars 39 forks source link

Add deployment help, e.g. with a multi-stage docker file #208

Closed malteneuss closed 1 year ago

malteneuss commented 2 years ago

Since everyone would probably like to host/deploy his/her Yesod project, how about adding some info on how to deploy Yesod, e.g. how to build a docker image out of it to make it easy to deploy. That's not trivial with non-haskell dependencies, especially on NixOS,which is popular with Haskellers. We could add some documentation to the Yesod homepage or (my preference) add a multi-stage docker Dockerfile that takes care of building and packing an image. Something along the lines of https://chekkan.com/haskell-yesod-web-app-in-docker/ :

FROM fpco/stack-build:lts-16.0 as dependencies
RUN mkdir /opt/build
WORKDIR /opt/build

# GHC dynamically links its compilation targets to lib gmp
RUN apt-get update \
  && apt-get download libgmp10
RUN mv libgmp*.deb libgmp.deb

# Docker build should not use cached layer if any of these is modified
COPY stack.yaml package.yaml stack.yaml.lock /opt/build/
RUN stack build --system-ghc --dependencies-only

# ------------------------------------------------------------------------
FROM fpco/stack-build:lts-16.0 as build

# Copy compiled dependencies from previous stage
COPY --from=dependencies /root/.stack /root/.stack
COPY . /opt/build/

WORKDIR /opt/build

RUN stack build --system-ghc

RUN mv "$(stack path --local-install-root --system-ghc)/bin" /opt/build/bin

# -----------------------------------------------------------------------
# Base image for stack build so compiled artifact from previous
# stage should run
FROM ubuntu:18.04 as app
RUN mkdir -p /opt/app
WORKDIR /opt/app

# Install lib gmp
COPY --from=dependencies /opt/build/libgmp.deb /tmp
RUN dpkg -i /tmp/libgmp.deb && rm /tmp/libgmp.deb

COPY --from=build /opt/build/bin .
COPY --from=build /opt/build/static ./static
COPY --from=build /opt/build/config ./config
ENV YESOD_PORT 8080
EXPOSE 8080
CMD ["/opt/app/my-project"]

Of course it would need to generate variations for the different databases. I would be willing to help with that.

malteneuss commented 1 year ago

There's now a very convenient Nix "Haskell-flake" setup that makes it quite easy to package a Haskell project (although only cabal is supported) as a Nix package, which then can be used with "Nix dockerTools" much more conveniently.