Skip to content

AlistairB/docker-stack-haskell

 
 

Repository files navigation

Haskell + Stack + Docker

A pattern for running a Haskell app with docker for dev and prod.

Stack has docker integration where stack wraps docker in a DSL so developers don't need to 'deal with docker themselves'.

docker:
  enable: true

I dislike hiding docker details behind an app level DSL. I much prefer this pattern where docker + high level script stuff is separate and wraps the stack and haskell level application stuff and each can easily be changed independently.

This is from a servant + persistent boilerplate

https://github.com/parsonsmatt/servant-persistent

It takes about 30 minutes to build the first time, but everything is cached after that.

How To

Run within the dev container

auto/dev-environment

Normal dev workflow

Usually you want to:

auto/dev-environment bash

then:

support/dev/run # or stack test

as needed. This avoids starting the docker container and running db migrations with each app run.

To Run Without Docker

Requires Haskell Stack on your host.

auto/up-dev-dependencies

support/dev/run

auto/down-dev-dependencies

Build the container with just the executable for production (and usually release to a registry)

auto/release

Running in CI

Due to the time + memory it takes to setup stack/ghc and compile all the dependencies it isn't desirable to do this on CI agents.

Instead this is done separately and a base image is created with everything baked in. It is recommended to push a new version of the base container when there are significant stackage version or library changes.

auto/release-ci-base

Testing the prod container locally

It can be useful to test with the cut down prod container.

auto/run-prod-local

Deploying To Prod

Requires a docker registry to deploy to (via auto/release) and some way to deploy a docker container with config.

Others

auto/build
auto/ghci
auto/test

Why?

Why use a custom snapshot?

This allows extra dependencies to be baked into the ci base image. Otherwise they are built locally into .stack-work

Why not use the official fpco stack-build containers?

For some reason the official stack docker images are very large. 8GB vs 1.3GB for official haskell, which include stack. (Although looks like there is a new stack-build-small at 2.67GB)

Also, the stack image is based off of (old) Ubuntu, while official haskell is based on (latest) debian. Debian is a much better fit for a docker container OS and it's simpler if the build and prod OS are the same.

About

A pattern for docker + stack + haskell

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Haskell 70.8%
  • Shell 9.5%
  • JavaScript 8.8%
  • HTML 6.4%
  • Dockerfile 4.5%