Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
In several different articles now, weâve explored how to build web apps using Haskell. See for instance, our Haskell Web Series and our API integrations series. But all this is meaningless in the end if we donât have a way to deploy our code so that other people on the internet can find it! In this next series, weâll explore how we can use common services to deploy Haskell code. Itâll involve a few more steps than code in more well-supported languages!
If youâve never programmed in Haskell at all, youâve got a few things to learn before you start deploying code! Download our Beginners Checklist for tips on how to start learning! But maybe youâve done some Haskell already, and need some more ideas for libraries to use. In that case, take a look at our Production Checklist for guidance!
Deploying Code on Heroku
In this article, weâre going to focus on using the Heroku service to deploy our code. Heroku allows us to do this with ease. We can get a quick prototype out for free, making it ideal for Hackathons. Like most platforms though, Heroku is easiest to use with more common languages. Heroku can automatically detect Javascript or Python apps and take the proper steps. Since Haskell isnât used as much, weâll need one extra specification to get Heroku support. Luckily, most of the hard work is already done for us.
Buildpacks
Heroku uses the concept of a âbuildpackâ to determine how to turn your project into runnable code. Youâll deploy your app by pushing your code to a remote repository. Then the buildpack will tell Heroku how to construct the executables you need. If you specify a Node.js project, Heroku will find your package.json file and download everything from NPM. If itâs Python, Heroku will install pip and do the same thing.
Heroku does not have any default buildpacks for Haskell projects. However, there is a buildpack on Github we can use (star this repository!). It will tell our Heroku container to download Stack, and then use Stack to build all our executables. So letâs see how we can build a rudimentary Haskell project using this process.
Creating Our Application
Weâll need to start by making a free account on Heroku. Then weâll download the Heroku CLI so we can connect from the terminal. Use the heroku login command and enter your credentials.
Now we want to create our application. In your terminal, cd into the directory that has your Haskell Stack project. Make sure itâs also a Github repository already. Itâs fine if the repository is only local for now. Run this command to create your application (replace haskell-test-app with your desired app name):
heroku create haskell-test-app \ -b https://github.com/mfine/heroku-buildpack-stack
The -b argument specifies our buildpack. We'll pull it from the specified Github repository. If this works, you should be able to go to your Heroku dashboard and see an entry for your new application. Youâll have a Heroku domain for your project that you can see on project settings.
Now we need to make a Procfile. This tells Heroku the specific binary we need to run to start our web server. Make sure you have an executable in your .cabal file that starts up the server. Then in the Procfile, youâll specify that executable under the web name:
web: run-server
Note though that you canât use a hard-coded port! Heroku will choose a port for you. You can get it by retrieving the PORT environment variable. Hereâs what your code might look like:
runServer :: IO ()runServer = do port <- read <$> getEnv âPORTâ Run port (serve myAPI myServer)
Now youâll need to âscaleâ the application to make sure it has at least a single machine to run on. From your repository, run the command:
heroku ps:scale web=1
Finally, we need to push our application to the Heroku container. To do this, make sure Heroku added the remote heroku Github repository. You can do this with the following command:
git remote -v
It should show you two remotes named heroku, one for fetch, and one for push. If those donât exist, you can add them like so:
heroku git:remote -a haskell-test-app
Then you can finish up by running this command:
git push heroku master
You should see terminal output indicating that Heroku recognizes your application. If you wait long enough, youâll start to see the Stack build process. If you have any environment variables for your project, set them from the app dashboard. You can also set variables with the following command:
heroku config:set VAR_NAME=var_value
Once our app finishes building, you can visit the URL Heroku gives you. It should look like https://your-app.herokuapp.com. Youâve now deployed your Haskell code to the cloud!
Weaknesses
There are a few weaknesses to this system. The main one is that our entire build process takes place on the cloud. This might seem like an advantage, and it has its perks. Haskell applications can take a LONG time to compile though. This is especially true if the project is large and involves Template Haskell. Services like Heroku often have timeouts on their build process. So if compilation takes too long, the build will fail. Luckily, the containers will cache previous results. This means Stack wonât have to keep re-downloading all the libraries. So even if our first build times out, the second might succeed.
Conclusion
This concludes part 1 of our Haskell Deployment series. Weâll see the same themes quite a bit throughout this series. Itâs definitely possible to deploy our Haskell code using common services. But we often have to do a little bit more work to do so. Next week, weâll see how we can automate our deployment process by incorporating Circle CI.
Want some more tips on developing web applications with Haskell? Download our Production Checklist to learn about some other libraries you can use! For a more detailed explanation of one approach, read our Haskell Web Skills series.
For All the World to See: Deploying Haskell with Heroku was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.