2015年12月15日火曜日

yesodのデプロイをnginx + keterでやってみた

keterってどうよ


yesodのproduction環境へのデプロイってどうやってやるのかなと思いつつ調べていたらketerなるものを見つけたのでやってみました。

keterを使ってyesodのデプロイとdaemonizeしてみる


keterはyesodのデプロイとdaemonizeまでやってくれる

keterをインストール


とりあえずインストール
karky7 ~ # emerge -pv dev-haskell/keter

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild  N    ~] dev-haskell/keter-1.4.3.1:0/1.4.3.1::haskell  USE="doc hoogle hscolour profile -system-filepath {-test}" 0 KiB

Total: 1 package (1 new), Size of downloads: 0 KiB

 * IMPORTANT: 42 news items need reading for repository 'gentoo'.
 * Use eselect news read to view new items.

karky7 ~ # 

そして設定
karky7 ~ # cp /etc/keter/keter.yaml.systemd /etc/keter/keter.yaml
karky7 ~ # mkdir -p /web/incoming

keterのIPとポートを決める
# /etc/keter/keter.yaml
root: /web
host: 127.0.0.1
port: 3000
nginx:
  start:
    - systemctl
    - start
    - nginx.service
  reload:
    - systemctl
    - reload
    - nginx.service

yesodプロジェクトを作成


どこでもいいので作る
karky7 ~ # yesod init
Welcome to the Yesod scaffolder.
I'm going to be creating a skeleton Yesod project for you.

What do you want to call your project? We'll use this for the cabal name.

Project name: yapp
Yesod uses Persistent for its (you guessed it) persistence layer.
This tool will build in either SQLite or PostgreSQL or MongoDB support for you.
We recommend starting with SQLite: it has no dependencies.

    s      = sqlite
    p      = postgresql
    pf     = postgresql + Fay (experimental)
    mongo  = mongodb
    mysql  = MySQL
    simple = no database, no auth
    mini   = bare bones, the "Hello World" of multi-file Yesod apps
             (Note: not configured to work with yesod devel)
    url    = Let me specify URL containing a site (advanced)

So, what'll it be? simple
That's it! I'm creating your files now...

---------------------------------------

                     ___
                            {-)   |\
                       [m,].-"-.   /
      [][__][__]         \(/\__/\)/
      [__][__][__][__]~~~~  |  |
      [][__][__][__][__][] /   |
      [__][__][__][__][__]| /| |
      [][__][__][__][__][]| || |  ~~~~
  ejm [__][__][__][__][__]__,__,  \__/


---------------------------------------

The foundation for your web application has been built.


There are a lot of resources to help you use Yesod.
Start with the book: http://www.yesodweb.com/book
Take part in the community: http://yesodweb.com/page/community


It's highly recommended to follow the quick start guide for
installing Yesod: http://www.yesodweb.com/page/quickstart

If your system is already configured correctly, please run:

    cd yapp && stack build && stack exec -- yesod devel
karky7 ~ # 

yappのketer.yamlをイジる
karky7 ~ # cd yapp
karky7 yapp # emacs config/keter.yml

修正する
# After you\'ve edited this file, remove the following line to allow
# `yesod keter` to build your bundle.
# user-edited: false <---- ここコメントアウト

# A Keter app is composed of 1 or more stanzas. The main stanza will define our
# web application. See the Keter documentation for more information on
# available stanzas.
stanzas:

  # Your Yesod application.
  - type: webapp

    # Name of your executable. You are unlikely to need to change this.
    # Note that all file paths are relative to the keter.yml file.
    exec: ../dist/build/yapp/yapp

    # Command line options passed to your application.
    args: []

    hosts:
      # You can specify one or more hostnames for your application to respond
      # to. The primary hostname will be used for generating your application
      # root.
      - www.kamegashira.jp # <--- ここイジった

    # Enable to force Keter to redirect to https
    # Can be added to any stanza
    requires-secure: false

  # Static files.
  - type: static-files
    hosts:
      - kamegashira.jp/static # <--- ここイジった
    root: ../static

    # Uncomment to turn on directory listings.
    # directory-listing: true

  # Redirect plain domain name to www.
  - type: redirect

    hosts:
      - kamegashira.jp # <--- ここイジった
    actions:
      - host: www.kamegashira.jp  # <--- ここイジった
        # secure: false
        # port: 80

    # Uncomment to switch to a non-permanent redirect.
    # status: 303

# Use the following to automatically copy your bundle upon creation via `yesod
# keter`. Uses `scp` internally, so you can set it to a remote destination
# copy-to: user@host:/opt/keter/incoming/

# You can pass arguments to `scp` used above. This example limits bandwidth to
# 1024 Kbit/s and uses port 2222 instead of the default 22
# copy-to-args:
#   - \"-l 1024\"
#   - \"-P 2222\"

# If you would like to have Keter automatically create a PostgreSQL database
# and set appropriate environment variables for it to be discovered, uncomment
# the following line.
# plugins:
#   postgres: true

がっちゃんこする


karky7 yapp # yesod keter
cleaning...
Warning: The package list for 'hackage.haskell.org' does not exist. Run 'cabal
update' to download it.
Resolving dependencies...
Configuring yapp-0.0.0...
Building yapp-0.0.0...
Preprocessing library yapp-0.0.0...
[1 of 8] Compiling Settings         ( Settings.hs, dist/build/Settings.o )
[2 of 8] Compiling Settings.StaticFiles ( Settings/StaticFiles.hs, dist/build/Settings/StaticFiles.o )
[3 of 8] Compiling Import.NoFoundation ( Import/NoFoundation.hs, dist/build/Import/NoFoundation.o )
[4 of 8] Compiling Foundation       ( Foundation.hs, dist/build/Foundation.o )
[5 of 8] Compiling Import           ( Import.hs, dist/build/Import.o )
[6 of 8] Compiling Handler.Common   ( Handler/Common.hs, dist/build/Handler/Common.o )
[7 of 8] Compiling Handler.Home     ( Handler/Home.hs, dist/build/Handler/Home.o )
[8 of 8] Compiling Application      ( Application.hs, dist/build/Application.o )
In-place registering yapp-0.0.0...
Preprocessing executable 'yapp' for yapp-0.0.0...
[1 of 1] Compiling Main             ( app/main.hs, dist/build/yapp/yapp-tmp/Main.o )
Linking dist/build/yapp/yapp ...
karky7 yapp # 
karky7 yapp # cp yapp.keter /web/incoming/
/etc/hostsファイルにホストを追加
127.0.0.1        www.kamegashira.jp

keter起動


うまくいけば、起動するはず
karky7 ~ # systemctl start keter
karky7 ~ # ps -ef | grep keter
root     10381     1  0 22:00 ?        00:00:00 /usr/bin/keter /etc/keter/keter.yaml
root     10400 10381  0 22:00 ?        00:00:00 /usr/bin/keter /etc/keter/keter.yaml
karky7 ~ # 
karky7 ~ # netstat -l
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 *:43124                 *:*                     LISTEN     
tcp        0      0 *:ssh                   *:*                     LISTEN     
tcp        0      0 localhost:3000          *:*                     LISTEN 
...

nginxを設定、起動する


serverセクションを追加する、「proxy_set_header Host $host;」が重要、これないとうまく動かない
    server {
        listen 80;
        server_name kamegashira.jp;
        location / {
            proxy_pass http://127.0.0.1:3000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Fowarded-For $proxy_add_x_forwarded_for;
        }
        access_log /var/log/nginx/localhost.access_log main;
        error_log /var/log/nginx/localhost.error_log info;
    }
そしてnginx起動
karky7 ~ # systemctl start nginx
ブラウザで「http://www.kamegashira.jp/」にアクセスしてみる
簡単にデプロイができる、大量なスクリプトをweb領域に展開するよりは全然かんたん、1つのファイルだけ持ってけばいい。理想のデプロイじゃないですか。

是非みなさんhaskellでyesodなクリスマスを彼女と過ごしてください!