72b1ee1d3d
Backend (Server.hs): - serveStaticOrSpa: serves static files from --static-dir - SPA fallback: extensionless paths serve index.html - MIME type mapping for html/css/js/png/svg/ico/woff2 Frontend: - ES module imports with import map for Mithril CDN - Build script: tsc + copy index.html + static assets CLI: - --static-dir flag (default: frontend/dist) - scripts/run passes through extra args - Dockerfile CMD points at /usr/local/share/sis/static
65 lines
1.6 KiB
Haskell
65 lines
1.6 KiB
Haskell
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
{- | Entry point for the Sis chore tracker server.
|
|
|
|
Starts a Warp HTTP server, serves the JSON API and the SPA frontend.
|
|
-}
|
|
module Main (main) where
|
|
|
|
import Network.Wai.Handler.Warp qualified as Warp
|
|
import Options.Applicative qualified as Opt
|
|
import System.Posix.Signals qualified as Signals
|
|
|
|
import Sis.Server qualified as Sis
|
|
|
|
data Options = Options
|
|
{ optPort :: Int
|
|
, optStaticDir :: FilePath
|
|
}
|
|
|
|
optionsParser :: Opt.Parser Options
|
|
optionsParser =
|
|
Options
|
|
<$> Opt.option
|
|
Opt.auto
|
|
( Opt.long "port"
|
|
<> Opt.short 'p'
|
|
<> Opt.metavar "PORT"
|
|
<> Opt.help "Listen port"
|
|
<> Opt.value 8080
|
|
<> Opt.showDefault
|
|
)
|
|
<*> Opt.strOption
|
|
( Opt.long "static-dir"
|
|
<> Opt.metavar "DIR"
|
|
<> Opt.help "Directory containing the SPA frontend static files"
|
|
<> Opt.value "frontend/dist"
|
|
<> Opt.showDefault
|
|
)
|
|
|
|
main :: IO ()
|
|
main = do
|
|
opts <-
|
|
Opt.execParser $
|
|
Opt.info (optionsParser Opt.<**> Opt.helper) $
|
|
Opt.fullDesc
|
|
<> Opt.progDesc "Sis — shared household chore tracker"
|
|
<> Opt.header "sis-server"
|
|
|
|
-- Install a SIGTERM handler so Docker stop works cleanly.
|
|
_ <-
|
|
Signals.installHandler
|
|
Signals.sigTERM
|
|
(Signals.Catch (putStrLn "[sis] shutting down"))
|
|
Nothing
|
|
|
|
let waiApp = Sis.app (optStaticDir opts)
|
|
|
|
let settings =
|
|
Warp.setPort (optPort opts) $
|
|
Warp.setBeforeMainLoop
|
|
(putStrLn $ "[sis] listening on port " ++ show (optPort opts))
|
|
Warp.defaultSettings
|
|
|
|
Warp.runSettings settings waiApp
|