Haskell on Heroku
Haskell on Heroku is a fast buildpack for deploying Haskell web apps on Heroku.
Features
-
Fast: Deploy a new app in 45 seconds, on average. Push a change in 30 seconds, on average.
-
Efficient: No unnecessary recompiling or relinking. Minimal caching. Minimal slugs, at 3MB for an average “Hello, world!”
-
Flexible: Use any Haskell web framework. Use any GHC version. Use GHCi as usual.
Quick start
With Heroku Toolbelt and Git installed, try:
-
Clone an example Snap app:
git clone https://github.com/mietek/haskell-on-heroku-examples.git mv haskell-on-heroku-examples/hello-snap . cd hello-snap
-
Commit the app to a new Git repo:
git init git add . git commit -m "Initial commit"
-
Create a new Heroku app:
heroku create -b https://github.com/mietek/haskell-on-heroku.git
-
Deploy the app on Heroku:
time git push heroku master heroku ps:scale web=1 heroku open
To write the example app from scratch, check the Hello Snap documentation.
For a more advanced example, showing how to use snaplets and Heroku Postgres, try Hello Snap with Postgres.
Questions
Can I use another web framework?
Yes. All Haskell web frameworks should work with Haskell on Heroku. Prepared packages are available for the Happstack, Scotty, Snap, Spock, and Yesod Haskell web frameworks. For examples, try:
- Hello Happstack Lite
- Hello Scotty
- Hello Snap
- Hello Snap with Postgres
- Hello Spock
- Hello Yesod
- Hello Yesod Platform
Does this have the latest GHC?
Yes. Prepared packages are available for GHC 7.8.2. Most other GHC versions should also work with Haskell on Heroku.
Can I use GHCi with this?
Yes. Once an app is deployed, use a one-off dyno to run GHCi within the app sandbox:
heroku run bash
restore
cabal repl
What do I need to know about Heroku?
Apps deployed on Heroku must listen for incoming connections on the provided PORT
. All log output is expected on standard output or standard error. Apps using Heroku Postgres should connect to the database using the DATABASE_URL
provided by Heroku. Finally, apps should be aware of the implications of HTTP routing on Heroku.
For more information about deploying web apps on Heroku, browse the Heroku Dev Center, or read the Heroku Hacker’s Guide.
To learn about modern web app architecture, read the Twelve-Factor App.
Procfile
?
Can I skip the Yes. Haskell on Heroku will generate a default Procfile
, taking the executable name from the Cabal package description file.
.profile.d
script?
Can I include a Yes. Haskell on Heroku will also generate its own .profile.d
script, named haskell-on-heroku.sh
.
I don’t trust this. Where do these packages come from?
Trusting any precompiled software requires careful thought. Haskell on Heroku packages are prepared by Least Fixed, hosted on Amazon S3, and updated daily, as a service for the Haskell community.
You can also prepare and host your own Haskell on Heroku packages, retaining complete control over your code.
How exactly do I prepare my own packages?
To prepare your own packages on Heroku, create a new Heroku app, configure your Amazon S3 details, and attempt to deploy the app. Without prepared packages in place, Haskell on Heroku will deploy an app-less slug, containing only itself. Next, use a one-off PX dyno to prepare the packages:
heroku run --size=PX prepare
Finally, deploy the app again, by either commiting a change and pushing, or rebuilding:
heroku plugins:install https://github.com/heroku/heroku-repo.git
heroku repo:rebuild
It is also possible to prepare packages off Heroku, using any 64-bit machine running Ubuntu 10.04 LTS.
How do I configure this?
To set configuration variables, use heroku config:set
.
Variable | Default | Description |
---|---|---|
HALCYON_AWS_ACCESS_KEY_ID |
— | Use this Amazon S3 key to access private prepared packages |
HALCYON_AWS_SECRET_ACCESS_KEY |
— | Use this Amazon S3 key to access private prepared packages |
HALCYON_S3_BUCKET |
— | Use this Amazon S3 bucket to keep prepared packages |
HALCYON_S3_ACL |
private |
Use this Amazon S3 ACL to control access to prepared packages |
HALCYON_PURGE_CACHE |
0 |
When 1 , delete all prepared packages from cache before compiling |
HALCYON_FORCE_FAIL_INSTALL |
0 |
When 1 , deploy an app-less slug without installing anything |
HALCYON_SILENT |
0 |
When 1 , hide all expected external command output |
HALCYON_FORCE_GHC_VERSION |
— | Use this GHC version instead of inferring it |
HALCYON_NO_CUT_GHC |
0 |
When 1 , use GHC prepared without deleting extraneous files |
HALCYON_FORCE_CABAL_VERSION |
— | Use this Cabal version instead of inferring the version |
HALCYON_FORCE_CABAL_UPDATE |
0 |
When 1 , update Cabal instead of using a recently updated prepared package |
I still have questions. Can I ask you a question?
Yes. Least Fixed offers commercial support for Haskell on Heroku. Say hello@leastfixed.com
Thanks
Thanks to Joe Nelson and Neuman Vong for their work on Haskell buildpacks, and to Tweag I/O and Purely Agile for advice and assistance.
Meta
Written by Miëtek Bak. Say hello@mietek.io
Available under the MIT License.