How can I deploy Yesod using Keter?

1.5k Views Asked by At

I'm trying to deploy a Yesod app to an Ubuntu server using Keter. So far this is what I've done:

  1. Install Keter on the server using the provided setup script
    • wget -O - https://raw.github.com/snoyberg/keter/master/setup-keter.sh | bash
  2. Run yesod keter to create a bundle on my dev machine (running OS X Mavericks)
  3. scp the *.keter file into /opt/keter/incoming on the server

At this point, I think I should be able to go to my domain and have the app working, but I'm seeing a "Welcome to nginx" page instead. Additionally, all I have in /opt/keter/log/keter/current.log is:

2014-05-10 18:21:01.48: Unpacking bundle '/opt/keter/etc/../incoming/DoDeployTest.keter'

And I think I should have lines about starting a process and loading an app.

What do I need to do to deploy Yesod with Keter? Is there a good tutorial covering this (so far alot of the ones I'm reading seem somewhat outdated based on not mentioning useful things like yesod keter; hard to say though).

I'm pretty new to Haskell/Yesod/Keter/Sysadmin work so any help is appreciated.

Appendix:

Github repo of the Yesod project (Its vanilla yesod init w/ postgres + configuring the keter.yaml file)

Keter.yaml file:

exec: ../dist/build/DoDeployTest/DoDeployTest
args:
    - production
host: "http://www.yesodonrails.com"
postgres: true
root: ../static
2

There are 2 best solutions below

1
On

Ah, so based on the advice from the blog post introducing Keter, I tried to run the executable inside the *.keter file manually. Doing so yielded the message "cannot execute binary file". I suspect this is because I was compiling on a Mac originally, and deploying to an Ubuntu instance (I had this same problem trying to deploy to Heroku).

Process for discovering this (might be slightly inaccurate):

cp /opt/keter/incoming/DoDeployTest.keter /tmp
cd /tmp
mv DoDeployTest.keter DoDeployTest.tar.gz
gunzip DoDeployTest.tar.gz
tar xvf DoDeployTest.tar
# run executable
/dist/build/appname/appname
1
On

To ensure the maximum level of success possible, I would strongly advise you to compile and run both Keter and your Yesod application on the same platform. The recommendation is also to compile your application on a different machine from the one you're deploying on, since GHC compilation is very resource intensive. It looks like you're already doing this (albeit compiling on OS X and deploying on an Ubuntu server, which is not going to work, as described in response to your own answer).

My recommendation would be to use Docker containers to ensure consistent environments. I have a GitHub project containing a number of Dockerfiles I've been working on to address this and I'll describe roughly what they do here. Note that this GitHub project is still a work in progress and I don't have everything absolutely perfect yet. This is also similar to the answer I gave to this question.

keter-build:

FROM haskell:latest
RUN apt-get update && apt-get install -y \
  git
RUN mkdir /src
RUN cd src && \
  git clone https://github.com/snoyberg/keter && \
  cd keter && \
  git checkout e8b5a3fd5e14dfca466f8acff2a02f0415fceeb0
WORKDIR /src/keter
RUN cabal update
RUN cabal install keter

This configures a container that can be used to build the keter binary at a given revision from the Keter GitHub project.

keter-host:

FROM debian
RUN apt-get update && apt-get install -y \
  ca-certificates \
  libgmp-dev \
  nano \
  postgresql
COPY artifacts/keter /opt/keter/bin/
COPY artifacts/keter-config.yaml /opt/keter/etc/
EXPOSE 80
CMD ["/opt/keter/bin/keter", "/opt/keter/etc/keter-config.yaml"]

This container is a self-contained Keter host. You should ensure that the keter binary built in the keter-build container is available in the artifacts directory so that the COPY artifacts/keter /opt/keter/bin/ instruction copies it into the image.

yesod-env:

FROM haskell:latest
RUN apt-get update && apt-get install -y \
  ca-certificates \
  git \
  nano \
  wget
RUN echo 'deb http://download.fpcomplete.com/debian/jessie stable main' > /etc/apt/sources.list.d/fpco.list
RUN wget -q -O- https://s3.amazonaws.com/download.fpcomplete.com/debian/fpco.key | apt-key add -
RUN apt-get update && apt-get install -y \
  stack

This is a container for building the Yesod app. Note that this Dockerfile is incomplete and haven't got it to clone the app's source code and build it yet. However, this might get you started.

Note that all three containers are ultimately based off the same debian Docker base image, so that binaries produced in each container will have a good chance of being valid in other containers. Some of my work was inspired by Dockerfiles designed by thoughtbot.