Deploying Scaleable JVM Apps on 
Heroku 
Joe Kutner 
JVM Languages Owner at Heroku 
@codefinger
Java 
Scala 
Groovy 
Clojure 
JRuby
Traditional WAR file deployment… 
.war
Why WAR?
What does modern Java deployment 
look like?
Modern Java deployment is… 
Containerless
Modern containerless deployment…
Let’s see it in action…
java -jar myapp.jar
java -jar jetty-runner.jar /my/app/
$ heroku deploy:war myapp.war
The Twelve Factor App
The Twelve Factor App is… 
• a manifesto 
• a methodology 
• a collection of experiences
Its goals are… 
• scalability 
• maintainability 
• portability
Its does this through… 
declarative setup 
…explicit dependencies 
…external configuration 
! 
clean contracts 
…between your app and its platform 
…reduced coupling 
! 
minimum divergence 
…between each deployment 
…between dev and prod environments
• Port binding 
• Concurrency 
• Disposability 
• Dev/prod parity 
• Logs 
• Admin processes 
Twelve Factors 
12factor.net 
• Codebase 
• Dependencies 
• Config 
• Backing services 
• Build, release, run 
• Processes
I. Codebase 
One codebase, many deploys 
Test 
Staging 
Production
I. Codebase 
One codebase, many deploys 
Test 
Staging 
Production 
$ git push heroku-test master 
$ git push heroku-stg master 
$ git push heroku-prod master
II. Dependencies 
Explicitly declared
II. Dependencies 
Explicitly declared 
<dependency> 
<groupId>postgresql</groupId> 
<artifactId>postgresql</artifactId> 
</dependency>
II. Dependencies 
Explicitly declared 
! 
libraryDependencies ++= Seq( 
"postgresql" % "postgresql" % "9.0-801.jdbc4" 
)
II. Dependencies 
Explicitly declared 
<dependency> 
<groupId>org.eclipse.jetty</groupId> 
<artifactId>jetty-servlet</artifactId> 
</dependency>
II. Dependencies 
Explicitly declared 
libraryDependencies ++= Seq( 
"com.twitter" % "finagle-http" % "6.18.0", 
)
III. Configuration 
Store config in the environment, not the app
III. Configuration 
Store config in the environment, not the app 
! 
<dbUrl>jdbc://postgres...</dbUrl>
III. Configuration 
Store config in the environment, not the app 
URI dbUri = new URI(System.getenv(“DATABASE_URL"));!
III. Configuration 
Store config in the environment, not the app 
$ heroku config:set JAVA_OPTS=“-Xmx512m”
IV. Backing Services 
Treat backing services as attachable resources
IV. Backing Services 
Treat backing services as attachable resources
IV. Backing Services 
Treat backing services as attachable resources 
$ heroku addons:add papertrail
V. Build, release, run 
• A build step vendors dependencies, prepares assets, etc. 
• A release step creates a package from build and config. 
• A runtime step executes, without special knowledge.
V. Build, release, run 
$ mvn package
V. Build, release, run 
$ git push heroku master
V. Build, release, run 
$ sbt stage deployHeroku
VI. Processes 
Stateless
VI. Processes 
Stateless 
Don’t write to the local filesystem.
VII. Port binding 
• Export services via port binding 
• Self-contained, not relying on runtime injection by a web server 
java -Dserver.port=$PORT -jar …
VIII. Concurrency 
• Scale out 
• Scale up
VIII. Concurrency 
• Scale out 
• Scale up 
$ heroku ps:scale web=3
VIII. Concurrency 
web.2 
web.1 
worker.3 
worker.1 clock.1 
Workload Diversity 
Number of Processes 
worker.2
IX. Disposability 
Fast startup and graceful shutdown 
• Spring Boot and Play do this for you… 
• as opposed to big App Servers that take several minutes to boot
X. Dev/prod parity 
Keep dev, staging, prod and everything in between as similar as possible
X. Dev/prod parity 
Keep dev, staging, prod and everything in between as similar as possible 
dev! 
sqlite! 
postgres 
stage! 
mysql! 
postgres 
prod! 
postgres! 
postgres 
=! 
≠! 
= 
=! 
≠! 
=
XI. Logs 
Treat logs as event streams
XI. Logs 
Treat logs as event streams 
DB Web Worker 
Event Stream 
2014-09-10T22:38:43.427311+00:00 heroku[worker]: ... 
2014-09-10T22:38:49.629790+00:00 heroku[web.1]: Starting process... 
2014-09-10T22:39:22.056033+00:00 heroku[router]: at=info method=... 
2014-09-10T22:38:43.427311+00:00 heroku[postgres]: ... 
2014-09-10T22:38:43.427311+00:00 heroku[api]: Release v34 created... 
2014-09-10T22:38:49.629790+00:00 heroku[web.1]: Starting process ... 
2014-09-10T22:39:22.056033+00:00 heroku[router]: GET mysite.com/ ...
XII. Admin Processes 
Admin and management tasks should be one-off processes
XII. Admin Processes 
Admin and management tasks should be one-off processes 
web1 
web2 
web3 
admin
• Port binding 
• Concurrency 
• Disposability 
• Dev/prod parity 
• Logs 
• Admin processes 
Twelve Factors 
• Codebase 
• Dependencies 
• Config 
• Backing services 
• Build, release, run 
• Processes
Further reading… 
! 
Heroku DevCenter: devcenter.heroku.com 
! 
Spring Boot Example: https://github.com/kissaten/spring-boot-executable 
! 
Link to slideshare 
! 
Twitter: @codefinger
Thank You! 
Joe Kutner 
JVM Languages Owner at Heroku 
@codefinger

Creating Scalable JVM/Java Apps on Heroku

  • 1.
    Deploying Scaleable JVMApps on Heroku Joe Kutner JVM Languages Owner at Heroku @codefinger
  • 2.
    Java Scala Groovy Clojure JRuby
  • 3.
    Traditional WAR filedeployment… .war
  • 4.
  • 5.
    What does modernJava deployment look like?
  • 6.
    Modern Java deploymentis… Containerless
  • 7.
  • 9.
    Let’s see itin action…
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
    The Twelve FactorApp is… • a manifesto • a methodology • a collection of experiences
  • 15.
    Its goals are… • scalability • maintainability • portability
  • 16.
    Its does thisthrough… declarative setup …explicit dependencies …external configuration ! clean contracts …between your app and its platform …reduced coupling ! minimum divergence …between each deployment …between dev and prod environments
  • 17.
    • Port binding • Concurrency • Disposability • Dev/prod parity • Logs • Admin processes Twelve Factors 12factor.net • Codebase • Dependencies • Config • Backing services • Build, release, run • Processes
  • 18.
    I. Codebase Onecodebase, many deploys Test Staging Production
  • 19.
    I. Codebase Onecodebase, many deploys Test Staging Production $ git push heroku-test master $ git push heroku-stg master $ git push heroku-prod master
  • 20.
  • 21.
    II. Dependencies Explicitlydeclared <dependency> <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> </dependency>
  • 22.
    II. Dependencies Explicitlydeclared ! libraryDependencies ++= Seq( "postgresql" % "postgresql" % "9.0-801.jdbc4" )
  • 23.
    II. Dependencies Explicitlydeclared <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-servlet</artifactId> </dependency>
  • 24.
    II. Dependencies Explicitlydeclared libraryDependencies ++= Seq( "com.twitter" % "finagle-http" % "6.18.0", )
  • 25.
    III. Configuration Storeconfig in the environment, not the app
  • 26.
    III. Configuration Storeconfig in the environment, not the app ! <dbUrl>jdbc://postgres...</dbUrl>
  • 27.
    III. Configuration Storeconfig in the environment, not the app URI dbUri = new URI(System.getenv(“DATABASE_URL"));!
  • 28.
    III. Configuration Storeconfig in the environment, not the app $ heroku config:set JAVA_OPTS=“-Xmx512m”
  • 29.
    IV. Backing Services Treat backing services as attachable resources
  • 30.
    IV. Backing Services Treat backing services as attachable resources
  • 31.
    IV. Backing Services Treat backing services as attachable resources $ heroku addons:add papertrail
  • 32.
    V. Build, release,run • A build step vendors dependencies, prepares assets, etc. • A release step creates a package from build and config. • A runtime step executes, without special knowledge.
  • 33.
    V. Build, release,run $ mvn package
  • 34.
    V. Build, release,run $ git push heroku master
  • 35.
    V. Build, release,run $ sbt stage deployHeroku
  • 36.
  • 37.
    VI. Processes Stateless Don’t write to the local filesystem.
  • 38.
    VII. Port binding • Export services via port binding • Self-contained, not relying on runtime injection by a web server java -Dserver.port=$PORT -jar …
  • 39.
    VIII. Concurrency •Scale out • Scale up
  • 40.
    VIII. Concurrency •Scale out • Scale up $ heroku ps:scale web=3
  • 41.
    VIII. Concurrency web.2 web.1 worker.3 worker.1 clock.1 Workload Diversity Number of Processes worker.2
  • 42.
    IX. Disposability Faststartup and graceful shutdown • Spring Boot and Play do this for you… • as opposed to big App Servers that take several minutes to boot
  • 43.
    X. Dev/prod parity Keep dev, staging, prod and everything in between as similar as possible
  • 44.
    X. Dev/prod parity Keep dev, staging, prod and everything in between as similar as possible dev! sqlite! postgres stage! mysql! postgres prod! postgres! postgres =! ≠! = =! ≠! =
  • 45.
    XI. Logs Treatlogs as event streams
  • 46.
    XI. Logs Treatlogs as event streams DB Web Worker Event Stream 2014-09-10T22:38:43.427311+00:00 heroku[worker]: ... 2014-09-10T22:38:49.629790+00:00 heroku[web.1]: Starting process... 2014-09-10T22:39:22.056033+00:00 heroku[router]: at=info method=... 2014-09-10T22:38:43.427311+00:00 heroku[postgres]: ... 2014-09-10T22:38:43.427311+00:00 heroku[api]: Release v34 created... 2014-09-10T22:38:49.629790+00:00 heroku[web.1]: Starting process ... 2014-09-10T22:39:22.056033+00:00 heroku[router]: GET mysite.com/ ...
  • 47.
    XII. Admin Processes Admin and management tasks should be one-off processes
  • 48.
    XII. Admin Processes Admin and management tasks should be one-off processes web1 web2 web3 admin
  • 49.
    • Port binding • Concurrency • Disposability • Dev/prod parity • Logs • Admin processes Twelve Factors • Codebase • Dependencies • Config • Backing services • Build, release, run • Processes
  • 50.
    Further reading… ! Heroku DevCenter: devcenter.heroku.com ! Spring Boot Example: https://github.com/kissaten/spring-boot-executable ! Link to slideshare ! Twitter: @codefinger
  • 51.
    Thank You! JoeKutner JVM Languages Owner at Heroku @codefinger