Déployer une application Haskell/PostgreSQL sur Heroku
Voir aussi : vidéo peertube - vidéo youtube - dépôt git
Heroku est un service de cloud de type PaaS (Platform as a Service), comme Amazon Web Service, Google App Engine, Microsoft Azure, Red Hat OpenShift… Heroku propose une offre gratuite, limitée mais suffisante pour déployer des applications web simples.
Ce tutoriel montre comment écrire, configurer et déployer, sur Heroku, une application web en Haskell avec une base de données PostgreSQL.
Application Haskell/PostgreSQL, dans un dépôt git
- exemple d’application (disponible dans un dépôt gitlab) :
- initialisation de la base de données (
music.sql
) :
SELECT current_database();
SELECT current_user;
CREATE TABLE artists (
id INTEGER PRIMARY KEY,
name TEXT
);INSERT INTO artists VALUES(0, 'Radiohead');
-- ...
CREATE TABLE titles (
id INTEGER PRIMARY KEY,
INTEGER,
artist
name TEXT,FOREIGN KEY(artist) REFERENCES artists(id)
);INSERT INTO titles VALUES(0, 0, 'Paranoid android');
-- ...
- application Haskell (
Main.hs
) :
{-# LANGUAGE OverloadedStrings #-}
import qualified Data.Text as T
import qualified Data.Text.Lazy as L
import System.Environment (getEnv)
import Web.Scotty (get, html, scotty)
import Control.Monad.Trans (liftIO)
import qualified Data.ByteString.Char8 as B8
import qualified Database.PostgreSQL.Simple as P
type DbTitle = (T.Text, T.Text)
formatTitles :: [DbTitle] -> T.Text
= T.intercalate "<br/>\n" . map (\ (a, t) -> T.concat [a, " - ", t])
formatTitles
getMusic :: String -> IO T.Text
= do
getMusic params <- P.connectPostgreSQL $ B8.pack params
conn <- P.query_ conn "SELECT artists.name, titles.name FROM artists \
titles \ INNER JOIN titles ON artists.id = titles.artist" :: IO [DbTitle]
P.close connreturn $ formatTitles titles
main :: IO ()
= do
main <- getEnv "DATABASE_URL"
dbParams <- getEnv "PORT"
portStr let port = read portStr
$ do
scotty port "/" $ do
get <- liftIO $ getMusic dbParams
music $ L.fromStrict $ music html
- configuration cabal (
heroku-musicapp.cabal
) :
: heroku-musicapp
name: 0.1
version: BSD3
license-type: Simple
build-version: >=1.10
cabal
-musicapp
executable heroku-is: Main.hs
main-language: Haskell2010
default-depends: base, bytestring, mtl, postgresql-simple, scotty, text build
- configuration stack (
stack.yaml
) :
resolver: lts-11.15
Installer les clients Heroku et PostgreSQL
- Nixos (depuis 18.09) :
nix-env -iA nixos.heroku
- Nixos (avant 18.09) :
nix-env -iA nixos.nodejs-8_x nixos.nodePackages.node2nix nixos.postgresql100
git clone https://github.com/heroku/cli.git heroku-cli
cd heroku-cli
git checkout 3b5eb335cf35163cf4b3abdc9526a3428eadbc1c
node2nix -8
nix-build -A package
nix-env -i ./result
- autres OS : https://devcenter.heroku.com/articles/heroku-cli
Déployer sur Heroku
- écrire un fichier de configuration de l’application (
Procfile
) :
web: heroku-musicapp
- se connecter à Heroku :
heroku login
- créer et déployer l’application Haskell avec le buildpack Stack :
heroku create --buildpack https://github.com/mfine/heroku-buildpack-stack.git
git push heroku master
- créer et déployer la base de données PostgreSQL :
heroku addons:create heroku-postgresql:hobby-dev
heroku psql -f music.sql
- voir les logs :
heroku logs
- se déconnecter d’Heroku :
heroku logout
Portail web d’Heroku
- aperçu de l’application :
- détails de l’application :
- base de données :
Développement local en utilisant la base distante
Heroku définit les variables d’environnement PORT et DATABASE_URL, que l’on utilise dans l’application développée. Pour exécuter en local, il suffit de définir manuellement ces variables d’environnement. On peut aussi récupérer la configuration d’une base Heroku et l’utiliser pour une application locale :
PORT=3000 DATABASE_URL=`heroku config:get DATABASE_URL` nix-shell --run "cabal run"