我如何从 docker 容器 运行 yesod 初始化?

How do I run yesod init from a docker container?

我想要达到的目标

我想用Haskell和Yesod开发一个个人网站。我之前的网络作品主要在Python。我使用 Docker 以便在完成所有操作后可以轻松地在 Amazon Web Services 上进行部署。我在容器中进行所有开发 - 因此除了 vim 和 git 等实用程序外,没有软件直接安装在我的机器上 - 然后只需部署容器即可。我想为这个网站做同样的事情。

我试过的

我的 Docker 文件当前如下所示:

FROM haskell:latest
MAINTAINER Garry Cairns
ENV REFRESHED_AT 2015-03-19

# create a haskell user to run our programs
# ADD must be after chown see 
RUN ["groupadd", "haskell"]
RUN ["useradd", "haskell", "-s", "/bin/bash", "-m", "-g", "haskell", "-G", "haskell"]
ENV HOME /home/haskell
RUN ["mkdir", "/home/haskell", "-p"]
WORKDIR /home/haskell
RUN ["chown", "-R", "haskell:haskell", "/home/haskell"]
ADD ./ /home/haskell

# install yesod
RUN ["apt-get", "install", "-y", "wget"]
RUN ["wget", "http://www.stackage.org/lts/cabal.config"]
RUN ["cabal", "update"]
RUN ["cabal", "install", "yesod"]

# uncomment the line below to use container as a non-root user
# USER haskell:haskell

install yesod 注释下的说明来自yesod quick start guide。容器构建但是,在 cabal update 步骤中,我看到一条警告说:

Config file path source is default config file.
Config file /home/haskell/.cabal/config not found.
Writing default configuration to /home/haskell/.cabal/config
Downloading the latest package list from hackage.haskell.org
Note: there is a new version of cabal-install available.
To upgrade, run: cabal install cabal-install

这可能与以下错误有关,也可能无关。

我用 sudo docker run -itv /home/garry/projects/personal/api/:/home/haskell garrycairns/haskell /bin/bash 在这个容器上 运行 一个 shell 会话并尝试 yesod init,这告诉我它找不到 yesod 命令. 运行 ghci 也不让我 import Yesod

无论我安装yesod还是yesod-bin,结果都是一样的

我也试过 运行ning 作为 haskell 用户(查看我的 Docker 文件)得到了相同的结果。

预期结果

运行 yesod init 应该按照快速入门指南中的描述构建我的应用程序。

实际结果

yesod 命令在我的容器中不可用。

我在问什么

如何设置一个 Docker 容器,让我 运行 yesod init 以及稍后 yesod devel

您需要将位置 ~/.cabal/bin/ 添加到您的路径以访问 cabal 安装的程序,例如 yesod。

其次,运行 cabal 作为 haskell 用户可能更好,因为它希望非 root 用户 运行 (这可能是阻止您加载的原因) ghci 中的文件)。

最后在主文件夹的子文件夹中开发可能会更好,因为 cabal 沙箱会添加隐藏文件。

您可能还想为数据库等安装系统库

以下文件似乎有效:

FROM haskell:latest
MAINTAINER Garry Cairns
ENV REFRESHED_AT 2015-03-19

# create a haskell user to run our programs
# ADD must be after chown see 
RUN ["groupadd", "haskell"]
RUN ["useradd", "haskell", "-s", "/bin/bash", "-m", "-g", "haskell", "-G", "haskell"]
ENV HOME /home/haskell
RUN ["mkdir", "/home/haskell", "-p"]
WORKDIR /home/haskell
RUN ["chown", "-R", "haskell:haskell", "/home/haskell"]
ADD ./ /home/haskell



# install wget
RUN ["apt-get", "install", "-y", "wget"]

# set up haskell
USER haskell:haskell
# add cabal installed programs to path
ENV PATH /home/haskell/.cabal/bin:$PATH


# enter working directory
RUN ["mkdir", "yesod"]
WORKDIR /home/haskell/yesod
# install yesod binary
RUN ["wget", "http://www.stackage.org/lts/cabal.config"]
RUN ["cabal", "update"]
RUN ["cabal", "install", "alex", "happy", "yesod-bin"]

我最后做了以下事情。

下载 global stackage config file 并将其作为 stackage.

保存在我的项目根目录中

构建以下 Dockerfile,它使用我们刚刚创建的 stackage 文件,直到我说要注释掉其他所有内容。

FROM haskell:7.8

# install database dependencies
RUN ["apt-get", "update"]
RUN ["apt-get", "-y", "install", "libpq-dev"]

# update cabal and install yesod
RUN cabal update
ADD ./stackage /root/.cabal/stackage
RUN cat /root/.cabal/config /root/.cabal/stackage > /root/.cabal/config2
RUN ["mv", "/root/.cabal/config2", "/root/.cabal/config"]
RUN cabal update
RUN ["cabal", "install", "yesod-bin", "-j4"]

# Add your .cabal file before the rest of the code so next step caches
# Comment out here on the first run
ADD ./myproject.cabal /opt/server/myproject.cabal

# Docker will cache this command as a layer, freeing us up to
# modify source code without re-installing dependencies
RUN cd /opt/server && cabal install --only-dependencies -j4

# Add and Install Application Code
ADD ./ /opt/server
RUN cd /opt/server && cabal install

# Add installed cabal executables to PATH
ENV PATH /root/.cabal/bin:$PATH

# Default directory for container
WORKDIR /opt/server

运行 新容器使用您的项目根作为卷,然后 运行 yesod init --bare 在容器内。这也将在主机上的项目根目录中创建它的文件。

取消上面Dockerfile中你注释掉的行,重新构建。你现在有一个工作的 Dockerfile。