In this article, we’ll walk through using Gradle to deploy a Spring Boot application on Heroku.
The content of this article is a compilation of the sections of various Heroku articles that are relevant to our task of deploying a Spring Boot application using Gradle.
Requirements
This article assumes you have the following installed:
- Java 8 or later
- Gradle
- MAMP
- Heroku Account
- Heroku CLI
- Cheese-mvc-persistent App
Heroku Account & CLI
To begin, create a free Heroku account.
Then download and install the Heroku CLI.
You can verify that the installation worked by executing heroku --version
command from your terminal:
$ heroku --version
heroku/7.35.0 darwin-x64 node-v12.13.0
Once installed, cd
into the root directory of your project and you can use the heroku login
command from the terminal to log in using the email address and password you used when creating your Heroku account:
$ heroku login
heroku: Press any key to open up the browser to login or q to exit
› Warning: If browser does not open, visit
› https://cli-auth.heroku.com/auth/browser/***
heroku: Waiting for login...
Logging in... done
Logged in as me@example.com
Preparing Your Project
We will deploy your cheese-mvc-persistent
project created for the LC101 Java Track.
List all of the branches in your repository (the asterisk denotes the current branch) and check that your current branch is master.
$ git branch
* master
Java Artifacts
This section is for information purpose only since you are using Gradle build tool so you can choose not to run the steps listed here. Instead, you will run the steps listed under the next section Preparing Gradle Apps For Heroku
.
Typically, when we’re working on our projects, we’re building and running them locally. We have tools like Gradle and our IntelliJ that help us. These tools make compiling and running our application simple. We won’t have those tools in production, however, so we’ll need to package up our code into an executable JAR file.
A JAR file is a Java archive, which is essentially a ZIP file containing a bunch of compiled Java classes. We could use the javac command to take our source files and build an executable JAR file. However, when the JAR is executed, it also needs to be able to find all the dependencies (for instance, Spring) at runtime in order to use them. We’ll need to build our JAR file using Gradle so that these dependencies are packaged up alongside the compiled Java code that we wrote.
Spring Boot adds a plugin to Gradle that allows us to package up our source code alongside any dependencies, creating a fat JAR that contains compiled versions of our code and all of its dependencies. This JAR file can then be deployed to our server, and run anywhere that has the JVM installed. Try building a fat JAR yourself by running
$ ./gradlew assemble
Or on Windows:
$ gradlew.bat assemble
This created a fat JAR which we can run from the command line with the command:
$ java -jar build/libs/cheese-mvc-persistent-0.0.1-SNAPSHOT.jar
Preparing Gradle Apps For Heroku
This section contains an extract of the article Deploying Gradle Apps on Heroku, only covering the steps we will need to deploy our application. For a full overview, please read the article.
Heroku Java support for Gradle will be applied to applications that contain a build.gradle
file, settings.gradle
file, or a gradlew file
.
You are using gradlew
, then you must also add the gradle/wrapper/gradle-wrapper.jar
and gradle/wrapper/gradle-wrapper.properties
files to your Git repository. Also, they must not be ignored in your .gitignore
file. If you do not add these files, you will receive an error such as:
-----> executing ./gradlew stage
Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMain
Verify that your build file is set up correctly
The Gradle buildpack will run different build tasks depending on the frameworks it detects in your app. For Spring Boot, it will run ./gradlew build -x test
. If no known web frameworks are detected, it will run ./gradlew
stage.
To customize your build, you can create a stage task in your build.gradle
file. If this task is present, Heroku will run it in favor of any framework defaults. Your stage task will look something like this for Spring Boot:
task stage(dependsOn: ['build', 'clean'])
build.mustRunAfter clean
You want to avoid running tests during the Heroku build, you can use the following code in your build.gradle
to disable the test task during the execution of the stage task:
gradle.taskGraph.whenReady {
taskGraph ->
if (taskGraph.hasTask(stage)) {
test.enabled = false
}
}
Default web process type
The Gradle buildpack will automatically detect the use of the Spring Boot and Ratpack web frameworks. For Spring Boot, it will create a web process type with the following command:
java -Dserver.port=$PORT $JAVA_OPTS -jar build/libs/demo-0.0.1-SNAPSHOT.jar
We will customize the default web command with a Procfile
.
Add a new text file (shell script) Procfile
using Intellij.
The Procfile
A Procfile is a text file in the root directory of your application that defines process types and explicitly declares what command should be executed to start your app.
Your Procfile will look something like this for Spring Boot:
web: java -Dserver.port=$PORT $JAVA_OPTS -jar build/libs/cheese-mvc-persistent-0.0.1-SNAPSHOT.jar
Both of these examples declare a single process type, web, and the command needed to run it. The name “web” is important. It declares that this process type will be attached to the HTTP routing stack of Heroku, and receive web traffic when deployed.
How to keep build artifacts out of git
If you already have a .gitignore
file, check that the .gitignore
file contains the information below.
Prevent build artifacts from going into revision control by creating a .gitignore
file. Here’s a typical .gitignore
file:
build
.gradle
.idea
out
*.iml
*.ipr
*.iws
.DS_Store
Build your app and run it locally
To build your app locally do this:
$ ./gradlew stage
$ heroku local web
Or on Windows:
$ gradlew.bat stage
$ heroku local web
Your app should now be running on http://localhost:5000/
.
Our application is now ready to be run on a remote machine. Our next step is to prepare Heroku to host our application.
Deploy your application to Heroku
This section contains an extract of the article Deploy the app, only covering the steps we will need to deploy our application. For a full overview, please read the article.
After you commit your changes to git, you can deploy your app to Heroku.
$ heroku login
heroku: Press any key to open up the browser to login or q to exit
› Warning: If browser does not open, visit
› https://cli-auth.heroku.com/auth/browser/***
heroku: Waiting for login...
Logging in... done
Logged in as me@example.com
Create an app on Heroku, which prepares Heroku to receive your source code:
$ heroku create cheese-mvc-persistent-heroku
Creating cheese-mvc-persistent... done, stack is heroku-18
http://cheese-mvc-persistent-heroku.herokuapp.com/ | git@heroku.com:cheese-mvc-persistent.git
Git remote heroku added
When you create an app, a Git remote (named heroku) is also created and associated with your local Git repository.
By default, Heroku generates a random name for your app. You can pass a parameter to specify your own app name, like in our case cheese-mvc-persistent
or another name which is not already assigned to another Heroku application.
Now you can deploy. Almost every Heroku deployment follows this same pattern. First, use the git add command to stage your modified files for commit:
git add .
Next, commit the changes to the repository:
git commit -m "Add a Procfile."
Now deploy:
$ git push heroku master
...
-----> Gradle app detected
...
-----> Launching... done
http://cheese-mvc-persistent.herokuapp.com deployed to Heroku
Finally, check that your updated code is successfully deployed:
heroku open
Connecting To A Database - ClearDB MySQL
This section contains an extract of the article ClearDB MySQL, only covering the steps we will need to setup a MySQL database for our application. For a full overview, please read the article.
If you had a project without any service dependencies (like a database), the above steps would be all you need to deploy your application. In our case, we want to also deploy a database. Heroku has a free Add-ons ClearDB MySQL
to setup a MySQL database in our cloud environment. You will need to provide a credit card number and a phone number to verify your Heroku account.
ClearDB is a powerful, high-speed database-as-a-service in the cloud for your MySQL powered applications.
Provisioning the shared MySQL add-on
The ClearDB add-on can be installed and up and running in your app in no time! Run the following command to add ClearDB to your application:
$ heroku addons:create cleardb:ignite
-----> Adding cleardb to cheese-mvc-persistent... done, v18 (free)
Retrieve your database URL by issuing the following command:
$ heroku config | grep CLEARDB_DATABASE_URL
CLEARDB_DATABASE_URL => mysql://adffdadf2341:adf4234@us-cdbr-east.cleardb.com/heroku_db?reconnect=true
Copy the value of the CLEARDB_DATABASE_URL config variable.
$ heroku config:set DATABASE_URL='mysql://adffdadf2341:adf4234@us-cdbr-east.cleardb.com/heroku_db?reconnect=true'
Adding config vars:
DATABASE_URL => mysql2://adffd...b?reconnect=true
Restarting app... done, v61.
That’s it!
Open App In Browser
The application and database is now deployed. You can visit the app’s URL by running this command:
$ heroku open
You can find a sample of the app here: https://cheese-mvc-heroku.herokuapp.com/
View Logs
You can view the logs for the application by running this command heroku logs --tail
:
$ heroku logs --tail
2019-02-06T02:20:58.271708+00:00 app[web.1]: Picked up JAVA_TOOL_OPTIONS: -Xmx300m -Xss512k -XX:CICompilerCount=2 -Dfile.encoding=UTF-8
2019-02-06T02:20:54.000000+00:00 app[api]: Build succeeded
2019-02-06T02:21:04.504651+00:00 app[web.1]: 2019-02-06 02:21:04.503 INFO 4 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 57733 (http)
2019-02-06T02:21:04.609263+00:00 app[web.1]: 2019-02-06 02:21:04.608 INFO 4 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-02-06T02:21:04.609630+00:00 app[web.1]: 2019-02-06 02:21:04.609 INFO 4 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.14]
2019-02-06T02:21:04.660219+00:00 app[web.1]: 2019-02-06 02:21:04.659 INFO 4 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/app/.jdk/jre/lib/amd64/server::/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
2019-02-06T02:21:04.869403+00:00 app[web.1]: 2019-02-06 02:21:04.869 INFO 4 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-02-06T02:21:04.869559+00:00 app[web.1]: 2019-02-06 02:21:04.869 INFO 4 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3453 ms
2019-02-06T02:21:05.613519+00:00 app[web.1]: 2019-02-06 02:21:05.613 INFO 4 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-02-06T02:21:06.229996+00:00 heroku[web.1]: State changed from starting to up
Reload your application in the browser, and you’ll see another log message generated for that request. Press Control+C
to stop streaming the logs.
How do I delete/destroy an app on Heroku?
You can use the heroku apps:destroy
command from the command line, or you can visit the “Settings” tab of the app in your Heroku Dashboard and click the “Delete app” button at the bottom of the page.
$ heroku apps:destroy
▸ WARNING: This will delete ⬢ cheese-mvc-persistent-heroku including all add-ons.
▸ To proceed, type cheese-mvc-persistent-heroku or re-run this command with --confirm cheese-mvc-persistent-heroku
> cheese-mvc-persistent-heroku
Destroying ⬢ cheese-mvc-persistent-heroku (including all add-ons)... done
Go to command line and enter heroku apps
to verify the APP is gone.
$ heroku apps
Sources
- Deploying Java Applications — Liftoff documentation
- Deploying Gradle Apps on Heroku | Heroku Dev Center
- ClearDB MySQL | Heroku Dev Center
- Deploying Spring Boot Applications to Heroku | Heroku Dev Center
- Getting Started on Heroku with Java | Heroku Dev Center