Deploying a full stack Scala application on Heroku

Heroku and Scala logos

Project structure

build.sbt
- project
- backend
-- src
- frontend
-- src
-- webpack
- shared
-- src

Compiling the frontend

Create the app

heroku apps:create APP_NAME --region eu
heroku addons:create heroku-postgresql:hobby-dev

The sbt-Heroku plugin

addSbtPlugin("com.heroku" % "sbt-heroku" % "2.1.3")
lazy val `backend` = (project in file("./backend"))
.enablePlugins(PlayScala) // for example
.settings(
herokuAppName in Compile := "APP_NAME",
herokuProcessTypes in Compile := Map(
"web" -> "target/universal/stage/bin/backend -Dhttp.port=$PORT" // command for Heroku to launch the server
//"worker" -> "java -jar target/universal/stage/lib/my-worker.jar"
),
herokuIncludePaths in Compile := Seq(
"backend/app",
"backend/conf/routes",
"backend/conf/application.conf",
"backend/public"
),
// [...]
)
.dependsOn(sharedJVM)
  • the frontend does not build into the backend public directories, and
  • you will see that the task backend/deployHeroku finishes with “success” but nothing actually happened.
stage := {
val webpackValue = (frontend / Compile / fullOptJS / webpack).value
println(s"Webpack value is $webpackValue")
(stage in backend).value
}

Accessing the database

url = ${?JDBC_DATABASE_URL}

Specific to Play

  • in production, you need to define an application secret. You can easily do that by setting an environment variable on your Heroku app, for example via heroku config:set APPLICATION_SECRET=mycoolsecret and then in the configuration file, use play.http.secret.key = ${?APPLICATION_SECRET}
  • your application in Heroku lives in a container, so the origin actually accessing your app is probably unknown. Play will reject incoming connections unless you set play.filters.host.allowed = ["."] .
  • another consequence on having the application living in a container is that you need to know the port on which you traffic will pass. On Heroku, you receive an environment variable PORT which contains that piece of information
  • you most likely want to enable auto evolutions of the database. This is done via play.evolutions.autoApply = true
  • in dev mode, you can create a configuration file with dev values for all the afore-mentioned variables, such as the db url

Wrap up

--

--

--

Mathematician, Scala enthusiast, father of two.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Breaking Down Git and GitHub

AWS CLI: Let’s Play — Part I

Overriding Out Of The Box (OOTB) servlet in AEM

Empathy in Software Development

Integrating Event-Driven Systems with WSO2 Stream Processor and Siddhi

With Voluum, your campaigns an advertising you can control all tracking system

Compile v Transpile

Setup MongoDB Replication

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Antoine Doeraene

Antoine Doeraene

Mathematician, Scala enthusiast, father of two.

More from Medium

The Power of Kafka

Server APIs using Akka HTTP

Apache Kafka: A Basic Intro

Eventbus written in Python based on Kafka