-1

When I run and app using stack, it said

$ stack exec duckling-example-exe
no port specified, defaulting to port 8000
Listening on http://0.0.0.0:8000

However, I would like to bind the port to $PORT (in order to host on heroku).

How should I do so ? Sorry about newbie question, but I don't know anything about Haskell yet and can't search for any solution so far.

Haha TTpro
  • 5,137
  • 6
  • 45
  • 71

1 Answers1

4

If you cannot do a stack exec -- duckling-example-exe --port $PORT, you have to adapt the source code (a little bit) in exe/ExampleMain.hs.

import System.Environment (lookupEnv)
...

main :: IO ()
main = do
  setupLogs
  tzs <- loadTimeZoneSeries "/usr/share/zoneinfo/"
  p <- lookupEnv "PORT"
  conf <- commandLineConfig $ maybe defaultConfig (`setPort` defaultConfig)
                                                  (p >>= readMaybe)
  httpServe conf $
    ifTop (writeBS "quack!") <|>
    route
      [ ("targets", method GET targetsHandler)
      , ("parse", method POST $ parseHandler tzs)
      ]

The change is not too hard since you can read in the source code how quickHttpServe is implemented, adding the port is a bit of a hassle since setPort :: Int -> Config m a -> Config m a instead of taking a Maybe Int which would have been more convenient here.

Since lookupEnv returns a Maybe String we can use the monadic bind >>= and readMaybe to produce a Maybe Int.

The function now works as follows:

  • if no PORT environment variable is set and no command line param is given default value is chosen
  • if there is a --port 8080 this overrides a PORT=9000.
epsilonhalbe
  • 15,637
  • 5
  • 46
  • 74