Heroku Scala Support
Last updated December 03, 2024
This document describes the general behavior of Heroku as it relates to the recognition and execution of Scala applications. For a more detailed explanation of how to deploy an application, see Getting Started with Scala on Heroku.
Activation
Heroku recognizes Scala applications when files matching any of the following patterns are found:
/*.sbt
/project/*.scala
/project/build.properties
/.sbt/*.scala
When a deployed application is recognized as a Scala application, Heroku responds with -----> Scala app detected
.
$ git push heroku master
-----> Scala app detected
You can deploy Scala applications that use Maven as well, but they’re treated as Java applications, so Heroku Java Support applies.
Environment
The following environment variables are set:
PATH
:.sbt_home/bin:/usr/local/bin:/usr/bin:/bin
PORT
: The web process binds to this HTTP portDATABASE_URL
: URL of the Heroku Postgres database connection
Resizing dynos automatically changes Java memory settings. You can manually adjust the JAVA_OPTS
config var to override these defaults.
When a Java process is started on your dyno, the following Java options are automatically picked up:
-
-Dfile.encoding=UTF-8
These options are configured as part of the environment variable JAVA_TOOL_OPTIONS
. It’s intended to augment a command line in environments where the command line can’t be accessed or modified. If you must override these settings, you can either define your preferred options in the Procfile
command, which takes precedence, or you can set your own JAVA_TOOL_OPTIONS
config var.
Adjusting Environment for a Dyno Size
When you select a new dyno type some JVM flags are automatically added to JAVA_TOOL_OPTIONS
.
Cedar
Cedar-generation dynos have JAVA_TOOL_OPTIONS
set to the following per dyno size:
Plan | JAVA_TOOL_OPTIONS |
---|---|
Eco | -Xmx300m -Xss512k -XX:CICompilerCount=2 |
Basic | -Xmx300m -Xss512k -XX:CICompilerCount=2 |
Standard-1X | -Xmx300m -Xss512k -XX:CICompilerCount=2 |
Standard-2X | -Xmx671m -XX:CICompilerCount=2 |
Private/Shield-S | -Xmx671m -XX:CICompilerCount=2 |
Performance/Private/Shield-M | -Xmx2g |
Performance/Private/Shield-L | -Xmx12g |
Performance/Private/Shield-L-RAM | -XX:MaxRAMPercentage=80.0 |
Performance/Private/Shield-XL | -XX:MaxRAMPercentage=80.0 |
Performance/Private/Shield-2XL | -XX:MaxRAMPercentage=80.0 |
Fir
All Fir-generation dynos have JAVA_TOOL_OPTIONS
set to -XX:MaxRAMPercentage=80.0
.
Monitoring Resource Usage
You can use additional JVM flags to monitor resource usage in a dyno. The following flags are recommended for monitoring resource usage:
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+UseConcMarkSweepGC
See the troubleshooting article for more information about tuning a JVM process.
Build Behavior
Applications must include a /project/build.properties
file with the sbt.version
property specifying a version of SBT between 0.11.0 and 1.x. SBT release candidates, betas, and other pre-release versions are allowed.
The Heroku Scala buildpack runs sbt compile stage
to build the application. Applications must include a stage
task, which performs any tasks needed to prepare an application to be run in-place. For example, Typesafe’s sbt-native-packager
adds a stage
task to SBT that generates start scripts for an application. To use the plugin, create a /project/plugins.sbt
file containing:
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.7.6")
Or you can write a custom stage
task by putting something like this in your build.sbt
:
val stage = taskKey[Unit]("Stage task")
val Stage = config("stage")
stage := {
(packageWar in Compile).value
(update in Stage).value.allFiles.foreach { f =>
if (f.getName.matches("webapp-runner-[0-9\\.]+.jar")) {
println("copying " + f.getName)
IO.copyFile(f, baseDirectory.value / "target" / "webapp-runner.jar")
}
}
}
You can test your task by running sbt compile stage
locally.
Clean Builds
In some cases, builds must clean artifacts before compiling. If a clean build is necessary, configure builds to perform clean
by setting SBT_CLEAN=true
:
$ heroku config:set SBT_CLEAN=true
Setting config vars and restarting example-app... done, v17
SBT_CLEAN: true
All subsequent deploys use the clean
task. To remove the clean
task, unset SBT_CLEAN
:
$ heroku config:unset SBT_CLEAN
Unsetting SBT_CLEAN and restarting example-app... done, v18
Runtime Behavior
By default, Scala applications are launched with a start script generated by the sbt-native-packager
:
web: target/universal/stage/bin/appname
If an application isn’t using sbt-native-packager
or must be launched in a different way, you can include a custom Procfile
in the root of the project specifying a different entry for the web
process.
The Play framework automatically generates a start script for you, so no additional plugins are needed.
Supported JDK Versions
Refer to the Java support article.
Specifying a Java Version
Refer to the Java support article.
Postgres Auto-Provisioning
This section is only applicable to accounts created before May 15, 2023 or if you asked Heroku Support to enable auto-provisioning for your account.
A Heroku Postgres database automatically provisions on the first deploy of your Scala applications. This auto-provisioning populates the DATABASE_URL
environment variable.
If you don’t want the Postgres add-on, remove it by running:
$ heroku addons:destroy DATABASE --app example-app