# Free deployment to Heroku. # # !! Warning: You must use a 64 bit machine to compile !! # # This could mean using a virtual machine. Give your VM as much memory as you can to speed up linking. # # Basic Yesod setup: # # * Move this file out of the deploy directory and into your root directory # # mv deploy/Procfile ./ # # * Create an empty package.json # echo '{ "name": "~project~", "version": "0.0.1", "dependencies": {} }' >> package.json # # Postgresql Yesod setup: # # * add code to read the DATABASE_URL environment variable. # # import System.Environment # main = do # # parse env variable # durl <- getEnv "DATABASE_URL" # # pass settings to withConnectionPool instead of directly using loadConnStr # defaultMain (fromArgsExtra loadExtra) withYesodHeroku # # * add a dependency on the "heroku" package in your cabal file # # * add code in Application.hs to turn the url into connection parameters. The below works for Postgresql. # # #ifdef !DEVELOPMENT # import qualified Web.Heroku # #endif # # # canonicalizeKey :: (Text, val) -> (Text, val) # canonicalizeKey ("dbname", val) = ("database", val) # canonicalizeKey pair = pair # # toMapping :: [(key, val)] -> DO.Object key val # toMapping = DO.Mapping . map (\(key, val) -> (key, DO.Scalar val)) # # combineMappings :: DO.Object key val -> DO.Object key val -> DO.Object key val # combineMappings (DO.Mapping m1) (DO.Mapping m2) = DO.Mapping $ m1 ++ m2 # combineMappings _ _ = error "Data.Object is not a Mapping." # # loadHerokuConfig :: DO.TextObject -> IO Settings.PersistConfig # loadHerokuConfig ymlenv = do # #if DEVELOPMENT # let urlMap = DO.Mapping [] # #else # urlMap <- Web.Heroku.dbConnParams >>= return . toMapping . map canonicalizeKey # #endif # either error return $ Database.Persist.Base.loadConfig (combineMappings urlMap ymlenv) # # # withYesodHeroku :: AppConfig DefaultEnv () -> Logger -> (Application -> IO ()) -> IO () # withYesodHeroku conf logger f = do # s <- staticSite # dbconf <- withYamlEnvironment "config/postgresql.yml" (appEnv conf) loadHerokuConfig # Database.Persist.Base.withPool (dbconf :: Settings.PersistConfig) $ \p -> do # Database.Persist.Base.runPool dbconf (runMigration migrateAll) p # let h = YesodHeroku conf logger s p # defaultRunner (f . logWare) h # where # #ifdef DEVELOPMENT # logWare = logStdoutDev # #else # logWare = logStdout # #endif # Heroku setup: # Find the Heroku guide. Roughly: # # * sign up for a heroku account and register your ssh key # * create a new application on the *cedar* stack # # * make your Yesod project the git repository for that application # * create a deploy branch # # git checkout -b deploy # # Repeat these steps to deploy: # * add your web executable binary (referenced below) to the git repository # # git checkout deploy # git add ./dist/build/~project~/~project~ # git commit -m deploy # # * push to Heroku # # git push heroku deploy:master # Heroku configuration that runs your app web: ./dist/build/~project~/~project~ production -p $PORT