Heroku sbt Plugin
This plugin is used to deploy Scala and Play applications directly to Heroku without pushing to a Git repository. This is can be useful when deploying from a CI server.
Using the Plugin
Add the following to your
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, which creates a
Alternatively, you can deploy a fat JAR using sbt-assembly.
Next, add something like this to your
build.sbt if you do not have a Heroku Git repo in your
herokuAppName in Compile := "your-heroku-app-name"
Now, if you have the Heroku CLI installed, run:
$ sbt stage deployHeroku
If you do not have the CLI installed, then run:
$ HEROKU_API_KEY="xxx-xxx-xxxx" sbt stage deployHeroku
And replace "xxx-xxx-xxxx" with the value of your Heroku API token.
It is required that you use sbt 0.13.5 or greater.
You must use Java 1.7 or higher locally.
This plugin has not been tested with Play 2.0 or 2.1.
Configuring the Plugin
You may set the desired JDK version like so:
herokuJdkVersion in Compile := "11"
For a list of supported JDK versions, refer to the Heroku Java Support DevCenter article.
You can (but probably should not) set configuration variables like so:
herokuConfigVars in Compile := Map( "MY_VAR" -> "some value", "JAVA_OPTS" -> "-XX:+UseCompressedOops" )
If you adhere to the principles of the 12 Factor app,
Configuration should be strictly seperated from code. Thus, you do not want to tie your
configuration to your codebase. There are a few exceptions to this, such as
JAVA_OPTS may be universal. But please use
Any variable defined in
herokuConfigVars will override defaults. However, if you remove
a variable from this list, it will not automatically be removed from your Heroku app
(even on the next deploy).
You may set process types (similar to a
herokuProcessTypes in Compile := Map( "web" -> "target/universal/stage/bin/my-app -Dhttp.port=$PORT", "worker" -> "java -jar target/universal/stage/lib/my-worker.jar" )
You can include additional directories in the slug (they must be relative to the project root):
You can run the plugin against all sub-projects (in addition to the root project) by setting the following option:
herokuSkipSubProjects in Compile := false
This defaults to
true (and currently it only runs against all sub-projects or none).
You can disable the upload progress in the console by setting the
heroku.log.format system property to
false, like this:
$ sbt -Dheroku.log.format=false deployHeroku
src/sbt-test directory for examples.
Deploying a Fat JAR
If you are packaging your application with sbt-assembly or any other plugin that
produces a "fat JAR", you can deploy that file by adding the following configuration to your
herokuFatJar in Compile := Some((assemblyOutputPath in assembly).value)
If not using sbt-assembly, you may replace
(assemblyOutputPath in assembly).value with the relative path to your JAR file.
Then you can deploy by running:
$ sbt assembly deployHeroku
The sbt-heroku plugin will skip the sbt-native-packager bits and deploy your JAR directly to Heroku.
Running a Remote Console
sbt-native-packager version 0.7.6 or greater, sbt-heroku will create a
console process type for you. This command can be run like so:
$ heroku run console -a <appname> Running `console` attached to terminal... up, run.5154 Picked up JAVA_TOOL_OPTIONS: -Xmx384m -Djava.rmi.server.useCodebaseOnly=true Failed to created JLineReader: java.lang.NoClassDefFoundError: scala/tools/jline/console/completer/Completer Falling back to SimpleReader. Welcome to Scala version 2.10.4 (OpenJDK 64-Bit Server VM, Java 1.8.0_20). Type in expressions to have them evaluated. Type :help for more information. scala>
For older versions of Play 2.x it might be necessary to upgrade
You can do this by adding the following line of code to your
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.7.6")
Additionally, the is a bug in Scala 2.11.6 that causes this console task to fail. Upgrading to Scala 2.11.7 fixes the issue.
Deploying to Multiple Environments
To deploy to multiple Heroku app environments, you can use either system properties, environment variables, or any other native sbt/Java configuration method. For example, you might define your
appName as a Map and choose a value with
the system property as a key.
herokuAppName in Compile := Map( "test" -> "your-heroku-app-test", "stg" -> "your-heroku-app-stage", "prod" -> "your-heroku-app-prod" ).getOrElse(sys.props("appEnv"), "your-heroku-app-dev")
Then run the sbt command like so:
$ sbt -DappEnv=test stage deployHeroku
Deploying from Git Branches
Another option when using multiple environments is to deploy from a Git branch that corresponds to the environment. This is particularly useful if you are using git-flow or a similar process.
First, add the sbt-git plugin ot your
project/plugins.sbt like this:
resolvers += "jgit-repo" at "http://download.eclipse.org/jgit/maven" addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.6.4")
Then in your
build.sbt you can configure the sbt-heroku plugin to deploy to the environment that corresponds to the current Git branch like this:
import com.typesafe.sbt.SbtGit._ // ... herokuAppName in Compile := Map( "testing" -> "myapp-testing", "staging" -> "myapp-staging", "production" -> "myapp" ).getOrElse(git.gitCurrentBranch.value, "myapp-dev") showCurrentGitBranch
In order to run the test suite, you must have the Heroku CLI installed. Then run:
$ sbt scripted
To run an individual test, use a command like this:
$ sbt "scripted settings/config_vars"
The heavy lifting for this plugin is done by the
heroku-deploy library. The source code for that project can be found
in the heroku-maven-plugin repository. If you
need to update that library, do this:
$ git clone https://github.com/heroku/heroku-maven-plugin $ cd heroku-maven-plugin/heroku-deploy # make your changes $ mvn clean install
Then update the
heroku-deploy dependency version in the sbt-heroku
build.sbt to whatever
version is specified in the heroku-deploy
pom.xml. The next time you run the
scripted tests it will pick up the
snapshot version from your local Maven repository.