Deploying Snap with Docker
In our previous post we built out a scaffold project with Snap 1.0. In this post we’ll go over building a simple Dockerfile to deploy the project.
Make sure you’ve installed docker
There is an effort to make a
docker official haskell image
so we’ll use that. Once it’s merged into
we can simply skip building the
Clone docker-haskell and switch to the docker-library branch. (It doesn’t matter where on the computer we do this)
git clone email@example.com:darinmorrison/docker-haskell.gitcd docker-haskellgit checkout docker-library
Once in the appropriate directory, we can build the image
-t is short for
--tag, which lets us tag an image. We’ll
haskell for the base name and tag it as
. tells docker where to find the dockerfile
cd 7.8docker build -t haskell:7.8 .
We can test that it worked by using
ghci as an interactive pseudo-tty.
docker run -i -t haskell:7.8 ghci
:q to quit
ghci as usual.
We’ll base our project on the docker image we just built.
NOTE: We can push this base image to the docker hub but interestingly enough, we don’t have to (if we’re using “normal” repos; Automated Builds are a different story). We can push the final image without pushing the base image.
Dockerfile goes in the root of the
folder. If you’ve built a haskell project before and are
familiar with cabal sandboxes, this will be similar:
# https://github.com/darinmorrison/docker-haskell/tree/docker-libraryFROM haskell:7.8RUN cabal update# Add Cabal File and deps/ folderADD ./auth-server.cabal /opt/auth-server/auth-server.cabalADD ./deps /opt/auth-server/deps# Create Sandbox and Add Source DepsRUN cd /opt/auth-server &&cabal sandbox init &&cabal sandbox add-source deps/io-streams-haproxy &&cabal sandbox add-source deps/snap &&cabal sandbox add-source deps/snap-core &&cabal sandbox add-source deps/snap-server &&cabal sandbox add-source deps/snap-loader-static &&cabal sandbox add-source deps/heistRUN cd /opt/auth-server && cabal install --only-dependencies# Explicitly add relevant foldersADD ./src /opt/auth-server/srcADD ./snaplets /opt/auth-server/snapletsADD ./static /opt/auth-server/static# Init logging directoriesRUN mkdir /opt/auth-server/log# Build the ProjectRUN cd /opt/auth-server && cabal build# The directory CMD works fromWORKDIR /opt/auth-serverCMD ["./dist/build/auth-server/auth-server"]
With the above dockerfile in the root of
can build with:
cd auth-serverdocker build -t auth-server .
-t auth-servercould be any name, such as
-t myawesomethingbut if you plan to push it to the docker hub do
After building, run it with:
docker run -i -t -p 8000:8000 auth-server
and we should have a running instance of our application on
8000 (or at
boot2docker ip on port
We can push the image we just built to a registry (such as the docker hub) by building it with our username (so it gets filed under our user on the hub):
docker build -t biscarch/auth-serverdocker push biscarch/auth-server
and on some other computer (such as AWS, a Digital Ocean instance or another dev computer) pull and run the image:
docker pull biscarch/auth-serverdocker run -d -p 8000:8000 biscarch/auth-server
after running, we can check that it’s up with
The completed docker image is on the hub as
so you can run a
pull, then a
run anywhere you like:
docker pull biscarch/auth-server:0.0.0.2docker run -i -t -p 8000:8000 biscarch/auth-server:0.0.0.2