Skip to content

Instantly share code, notes, and snippets.

@jkachmar
Last active December 24, 2021 15:06
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jkachmar/4828bfe0f585bec93878ea893c3373ee to your computer and use it in GitHub Desktop.
Save jkachmar/4828bfe0f585bec93878ea893c3373ee to your computer and use it in GitHub Desktop.
Small Docker images with Alpine, Haskell, and Stack

All actions should be performed in the root directory of a Haskell project that uses stack. The following lines should be present in the project's stack.yaml file:

docker:
  enable: true

Additionally, the BaseImage and Dockerfile files from this gist should also be present in the project's root directory.

Note that both BaseImage and Dockerfile will have to be changed based on your needs:

  • Any dependencies your project needs in order to build should be installed on the last line of BaseImage
  • All instances of example should instead refer to your project name in the Dockerfile

To create the Alpine-based build container: docker build -f BaseImage -t <image_name> .

  • where <image_name> is what you want your build image to be tagged as
  • e.g. docker build -f BaseImage -t alpine-ghc/base .

To build the binary: stack --docker-image=<image_name> install

  • where <image_name> is what you tagged your build image as
  • e.g. stack --docker-image=alpine-ghc/base install

To build the deployment image: docker build -t <example> .

  • where <example> is what you want your production image to be tagged as
  • e.g. docker build -t my-project .

To run the container locally: docker run -i -t <example>

  • where <example> is what you tagged your production image as
  • e.g. docker run -i -t my-project
# Use Alpine Linux as base image
FROM alpine:latest
# Add mitchty's keys
ADD https://raw.githubusercontent.com/mitchty/alpine-ghc/master/mitch.tishmack%40gmail.com-55881c97.rsa.pub \
/etc/apk/keys/mitch.tishmack@gmail.com-55881c97.rsa.pub
# Add mitchty's GHC 'repo'
RUN echo "https://s3-us-west-2.amazonaws.com/alpine-ghc/8.0" >> /etc/apk/repositories
RUN echo "http://dl-6.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories \
&& echo "@edge http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories
# Update packages and install dependencies
RUN apk update && apk add \
alpine-sdk \
git \
ca-certificates \
ghc \
gmp-dev \
zlib-dev \
shadow@edge # Required for stack's 'usermod' and 'groupmod' invocations
# Grab a recent binary of Stack
ADD https://s3.amazonaws.com/static-stack/stack-1.1.2-x86_64 /usr/local/bin/stack
RUN chmod 755 /usr/local/bin/stack
# Install dependencies necessary for stack to build the project binary
# e.g. RUN apk add postgresql-dev
# Use Alpine Linux as base image
FROM alpine:latest
# Install libpq and gmp dependencies (dynamic libraries required by the project)
RUN apk update && apk add libpq gmp
# Copy the prebuilt binary from stack-work into the container
# (substitute your project name for 'example')
COPY .stack-work/docker/_home/.local/bin/example /usr/local/bin/example
# Run the binary on container start
# (substitute your project name for 'example')
CMD ["example"]
@chrisdone
Copy link

FROM alpine:latest

I think this should be a specific alpine version, for reproducibility. It's always possible that your Dockerfile will no longer work with a new release.

@chrisdone
Copy link

In fact this dockerfile (baseimage) doesn't seem to work anymore:

Step 5/7 : RUN apk update && apk add     alpine-sdk          git                 ca-certificates     ghc                 gmp-dev             zlib-dev            shadow@edge # Required for stack's 'usermod' and 'groupmod' invocations
 ---> Running in e96225bfd2db
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
fetch https://s3-us-west-2.amazonaws.com/alpine-ghc/8.0/x86_64/APKINDEX.tar.gz
fetch http://dl-6.alpinelinux.org/alpine/edge/community/x86_64/APKINDEX.tar.gz
ERROR: http://dl-6.alpinelinux.org/alpine/edge/community: IO ERROR
WARNING: Ignoring APKINDEX.0a96cc2d.tar.gz: No such file or directory
fetch http://dl-cdn.alpinelinux.org/alpine/edge/community/x86_64/APKINDEX.tar.gz
WARNING: This apk-tools is OLD! Some packages might not function properly.
v3.7.0-159-g08fa87dac2 [http://dl-cdn.alpinelinux.org/alpine/v3.7/main]
v3.7.0-160-g82f356f8c4 [http://dl-cdn.alpinelinux.org/alpine/v3.7/community]
v3.7.0-4722-g05748c9fad [http://dl-cdn.alpinelinux.org/alpine/edge/community]
1 errors; 12853 distinct packages available
The command '/bin/sh -c apk update && apk add     alpine-sdk          git                 ca-certificates     ghc                 gmp-dev             zlib-dev            shadow@edge # Required for stack's 'usermod' and 'groupmod' invocations' returned a non-zero code: 1
exit status 1
make: *** [all] Error 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment