Deploying Scala and Play Applications with the Heroku sbt Plugin
Last updated April 29, 2020
Table of Contents
In addition to Git deployment, Heroku supports building and releasing apps via an API. The Heroku sbt plugin uses this API to provide direct deployment of prepackaged standalone web applications to Heroku.
This may be a preferred approach for applications that take a long time to compile, or that need to be deployed from a Continuous Integration server such as Travis CI or Jenkins.
In this article, you’ll learn how to include the Heroku sbt Plugin in your project, configure it, and deploy your application to Heroku.
Adding the plugin
To include the plugin in your project, add the following to your project/plugins.sbt
file:
addSbtPlugin("com.heroku" % "sbt-heroku" % "2.1.4")
If you’re not using Play, then you’ll also need to add the sbt-native-packager plugin. You can do this by adding the following to your project/plugins.sbt
:
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.5.2")
Then run sbt update
to ensure the new dependencies are downloaded.
Next, we must configure the name of the Heroku application the plugin will deploy to. But first, create a new app. Install the Heroku CLI and run the create
command with the -n
flag, which will prevent it from adding a Git remote.
$ heroku create -n
Creating obscure-sierra-7788... done, stack is heroku-18
http://obscure-sierra-7788.herokuapp.com/ | git@heroku.com:obscure-sierra-7788.git
Now add something like this to your build.sbt
, but replace “obscure-sierra-7788” with the name of the application you created.
herokuAppName in Compile := "obscure-sierra-7788"
You’re ready to deploy.
Deploying with the plugin
To create the slug and deploy it to Heroku, run the following command:
$ sbt stage deployHeroku
...
[info] -----> Packaging application...
[info] - app: obscure-sierra-7788
[info] - including: target/universal/stage/
[info] -----> Creating build...
[info] - file: target/heroku/build.tgz
[info] - size: 47MB
[info] -----> Uploading slug... (100%)
[info] - success
[info] -----> Deploying...
[info] remote:
[info] remote: -----> sbt-heroku app detected
[info] remote: -----> Installing JDK 11... done
[info] remote: -----> Discovering process types
[info] remote: Procfile declares types -> console, web
[info] remote:
[info] remote: -----> Compressing...
[info] remote: Done: 106.5M
[info] remote: -----> Launching...
[info] remote: Released v3
[info] remote: https://obscure-sierra-7788.herokuapp.com/ deployed to Heroku
[info] remote:
[info] -----> Done
[success] Total time: 113 s (01:53), completed Jan 17, 2020 11:39:21 AM
Visit your application with this command:
$ heroku open -a obscure-sierra-7788
Or view the logs with this command:
$ heroku logs -a obscure-sierra-7788
The Heroku CLI will allow you to access the application, and run commands just like an application deployed with git push
.
Advanced configuration
The sbt plugin allows for several advanced configuration settings. All of these settings are defined in the build.sbt
file. For example, you may set the desired JDK version like so:
herokuJdkVersion in Compile := "11"
For a list of supported JDK versions, see Heroku Java Support.
You can set configuration variables as a Map
:
herokuConfigVars in Compile := Map(
"MY_VAR" -> "some value",
"JAVA_OPTS" -> "-Xmx384m -Xss512k -XX:+UseCompressedOops"
)
Be aware that any variable defined in herokuConfigVars
will override defaults, or previously defined config vars.
You may set process types (similar to a Procfile
) with herokuProcessTypes
:
herokuProcessTypes in Compile := Map(
"web" -> "target/universal/stage/bin/my-app -Dhttp.port=$PORT",
"worker" -> "java -jar target/universal/stage/lib/my-worker.jar"
)
And finally, you can include additional directories in the slug like this (note that they must be relative to the project root):
herokuIncludePaths in Compile := Seq(
"app", "conf/routes", "public/javascripts"
)
By default, the plugin will package the essential directories under your project’s target
directory, so including additional directories should not be necessary in most cases.
Deploying to multiple applications
Most real applications will be required to deploy to multiple Heroku apps (such as dev, test, and prod). Normally this is done with multiple Git remotes. But with the plugin you can use either system properties, environment variables, or any other native sbt/Java configuration method. For example, you might define your herokuAppName
with a Map and choose a value with a system property like this:
herokuAppName in Compile := Map(
"test" -> "your-heroku-app-test",
"stage" -> "your-heroku-app-stage",
"prod" -> "your-heroku-app-prod"
).getOrElse(sys.props("appEnv"), "your-heroku-app-dev")
Then run an sbt command similar to this:
$ sbt -DappEnv=test stage deployHeroku
Requirements
The plugin has a few restrictions that must be considered.
It is required that your project use sbt 0.13.5 or greater.
You must use Java 1.7 or higher locally.
The plugin does not support Play 2.0 or 2.1.
For more information on the plugin and Scala in general, see Heroku’s Scala support. For more information on sbt, see the sbt documentation.