LoginSignup
3
2

More than 3 years have passed since last update.

NimでHeroku

Last updated at Posted at 2019-06-22

はじめに

ちょっと前にFlaskで作ったアプリをHerokuにデプロイしました。
そういえばNimにもjesterあったなー、と思いだしたので簡単なwebアプリを作ってHerokuにデプロイしてみます。
どっちかというとHerokuでNimですね。

環境

  • nim 0.20.0
  • Heroku Freeプラン

Herokuの準備

こちらのbuildpackを使ってHerokuにnimの環境を作ります。

heroku create --stack cedar --buildpack https://github.com/vic/heroku-buildpack-nim.git

新しいアプリができました
2.png

Config VarsにKey=NIM_BRANCH, Value=develを設定します。
理由がよくわかってませんがこれがないとnimのビルドができませんでした。(そのうち調べます)
3.png

アプリの準備

jesterのチュートリアルを参考にアプリを作ります。他にnimble, procfileも必要です。

main.nim
import jester, posix, json, logging, os, strutils, asyncdispatch
import htmlgen as h

onSignal(SIGABRT):
  echo "<2>Received SIGABRT"
  quit(1)

let
  fl   = newFileLogger("logs.log",
                       fmtStr = "$datetime $levelname ")
addHandler(fl)

proc log_debug(args: varargs[string, `$`]) =
  debug args
  fl.file.flushFile()

proc log_info(args: varargs[string, `$`]) =
  info args
  fl.file.flushFile()

var settings = newSettings()
if existsEnv("PORT"):
  settings.port = Port(parseInt(getEnv("PORT")))

routes:
  get "/":
    resp h.h1("Hello myservice!!!")

when isMainModule:
  log_info "starting"
  runForever()
main.nimble
# Package
bin           = @["main"]
# Dependencies
requires "nim >= 0.20.0, jester"
Procfile
web: ./main

いざデプロイ

必要なものがそろったのでデプロイします。

git add .
git commit -m "first commit"
git push heroku master

しばらくしてからアプリを起動すると...
4.png

成功です!!!

おわりに

とりあえず動かしてみた、のレベルなのでwebアプリとは呼べませんね...
ただ、デプロイまでにあたった壁を自力で解決できたので、ちょっとスキルアップした気がします。(ログみたり、ソース追ったり)
次はDBと連携させたいです。

はまったポイント

ポートの指定エラー

デプロイしても起動せず...

Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch

Herokuが設定するポートをアプリで使うように設定する必要がありました。この記述が抜けてました。

var settings = newSettings()
if existsEnv("PORT"):
  settings.port = Port(parseInt(getEnv("PORT")))

タイポでエラー

ポートを設定したのに起動しない...

Error: unhandled exception: index 20 not in 0 .. 19 [IndexError]

これはHerokuではなく自分のタイポが原因でした。newFileLoggerの引数にfmtStrを設定してますが、こう書くべきところを

let fl = newFileLogger("log.txt", fmtStr = "$datetime $levelname ")

こう書いており、$levelnameの後ろにスペース入れ忘れてました。

let fl = newFileLogger("log.txt", fmtStr = "$datetime $levelname")

logging.nimのsubstituteLogでFileLoggerのfmtStrからログの種類を判定します。
fmtStrを1文字ずつresultに追加し['a'..'z', 'A'..'Z', '0'..'9', '_']以外の文字になったら追加をやめ、いままで追加した文字から種類を判定します。
スペースを入れ忘れたせいで20文字のfmtStrなのに21文字目をresultに追加しようとしてIndexErrorが発生しました。てへぺろ

参考

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2