如何在生产环境中运行Snap Haskell Web应用程序?

28

我在我的生产Ubuntu服务器(在EC2上)安装了Snap/Haskell,并检出了我的项目 - 但我该如何运行它?

我的意思是,在本地,我通过命令行运行它:

project-name -p 8000

Snap是否自带Web服务器(看起来是这样的),如果是,我该如何配置它以作为某种守护进程运行?
有什么技巧吗?
编辑2:
wiki上,他们说:
snap-server是一个支持snap-core定义的接口的HTTP服务器库。
而这里,关于“您的Haskell Web代码的部署/后端选项”的Haskell维基百科则表示Snap:
包括自己的服务器。请参见Web / Frameworks 但是怎么做?我该如何运行它自己的服务器?如果我只是对编程感兴趣,为什么必须了解该死的部署...
编辑:相关问题:部署使用Snap框架的Haskell代码

当您运行project-name -p 8000时,您的应用程序是否没有像您请求的一样在端口8000上运行? - Sarah
1
如果您无法将它作为守护进程运行,请使用类似于 screen 的方式运行它。例如 screen -S snapd -d -m -L project-name -p 8000,然后您可以通过 screen -r snapd -X quit 停止该进程。 - Daniel Leschkowski
@Sarah 是的,但是在生产环境中,当我退出登录时,它会终止我的会话和其中的所有进程。 - Andriy Drozdyuk
@DanielLeschkowski 我可能可以将其作为守护进程运行,只是我不知道如何... - Andriy Drozdyuk
3个回答

25

好的,经过一些挖掘询问后,这就是我得出的结论。

大致思路

将Snap应用程序编译为二进制文件,然后借助upstart作为服务运行。

步骤

  1. Compile your webapp. For the sake of this example, we'll assume the webapp is at /home/john/webapps/mysite:

    $ cd /home/john/webapps/mysite
    $ cabal install
    ...
    Preprocessing executable 'mysite` for 'mysite-0.1'...
    Installing executable(s) in /home/john/.cabal/bin
    

    As we can see the, the binary is placed in /home/john/.cabal/bin. You may move it to any place you like, but we'll leave it there.

  2. Create a log in your application folder, otherwise snap will complain:

    $ mkdir /home/john/webapps/mysite/log
    
  3. Now we will create a service that will run our webapp. To do so we will use Ubuntu's service facility called upstart.

    a) We name our service simply by creating a conf file with the desired name in the /etc/init/ directory. Let's call it mysite:

    $ sudo vi /etc/init/mysite.conf
    

    b) Now let's add the description of what our service is:

    start on startup
    chdir /home/john/webapps/mysite
    exec /home/john/.cabal/bin/mysite -p 80
    

    First, we say that the service should run on startup (or on bootup) of the system.

    Second, since snap needs it's snaplets and other static resources (like the log directory we created earlier) - we tell the service to run inside our project's directory.

    Lastly, we specify the binary that actually will run as a service: /home/john/.cabal/bin/mysite. We pass the -p 80 parameter to the snap webserver to make it run on port 80. (Note: you have to disable all apache and nginx servers, so that they don't take up that port any more)

  4. Done. You can check if it is running and start it manually if you need to:

    initctl list | grep mysite
    initctl start mysite
    

17

是的,snap-server是自己的服务器,这意味着编译您的Haskell/Snap应用程序将生成一个可执行文件,您可以在命令行上运行该文件来托管您的网站。就是这样,没有像Apache或Nginx这样的外部服务器可供使用。如果需要,您可以设置反向代理,但这取决于您。

这是我在大多数重要部署中所做的:

  • 在同一Linux盒子上编译或兼容的机器上编译 - 我几乎总是使用cabal-dev进行沙箱处理
  • 命令行参数: cabal-dev/bin/myapp -p 8010 -e prod +RTS -A4M -qg1
  • 我在非特权、非默认端口(如上面的8010)上运行以便我可以使用负载均衡器将请求转发到它。这也允许我在一个Linux盒子上运行多个Snap应用程序(如果需要)。
  • 然后我使用一个简单的进程监视应用程序来确保它保持运行。您可以使用:
  • 设置监控之后,您只需在想要重新启动应用程序时发送一个HUP信号,监视应用程序会将其重新启动。
  • 我非常喜欢Fabric的部署自动化。您可以使用fabric处理远程同步、重启等问题。

希望这有所帮助。


谢谢,这很棒。但是我如何“启动”我的应用程序?此外,有没有替代cabal-dev的方法,该死的东西在Windows上不起作用? - Andriy Drozdyuk
1
你可以通过运行myapp.exe来启动程序,这个文件是在Cabal编译后创建的。如果你不想使用Cabal-dev,也可以直接使用Cabal本身,这样也能得到相同的结果,但无法进行沙箱隔离。 - ozataman
你们使用什么类型的负载均衡器? - Andriy Drozdyuk

5

由于它是Ubuntu,您几乎总是最好使用upstart来管理它。

man 5 init

除其他外,它还允许您为服务设置依赖关系层次结构。"snapapp依赖于mongodb,因此在mongodb运行之前不要启动snapapp" - 就是这样。

是的,snap是一个Web服务器,但我们几乎总是在它们前面放置nginx,而snap应用程序仅在本地主机上监听,并且使用proxy_path指向服务器或一组服务器。

有趣的是,我们在$work的新开发中几乎完全转向了Common Lisp,设置完全相同。


谢谢你告诉我关于upstart的事情。它看起来很棒,使用起来也很简单!那么,如何将nginx放在snap webapp之前呢?我的snap webapp是什么样子的?我还需要运行snap webserver吗,还是只需要nginx?对不起,问题可能有点愚蠢... - Andriy Drozdyuk
1
作为一个显而易见的附注:我会在Nginx后运行Snap,以便服务静态内容并代理指向动态内容的URL。 - 9000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接