Deploying / Hosting Spring Boot applications on Heroku

Heroku is a cloud platform as a service (PaaS) that you can use to deploy, manage, and scale your applications. It supports several programming languages and has a very simple and convenient deployment model.

In this article, you’ll learn how to deploy Spring Boot applications on Heroku with step by step instructions.

There are several ways of deploying spring boot apps to Heroku. I’ll take you through all of them one by one. I’ll also show you the pros and cons of using one method over the other.

Creating a Simple Spring Boot app for deployment

Before learning about deployment, Let’s first create a simple Spring Boot app that we’ll deploy on Heroku.

You can also clone the sample app directly from Github, and move to the next section.

  1. Bootstrapping the app

    The easiest way to bootstrap a new spring boot app is using Spring Boot CLI. Just enter the following command in your terminal to generate the project using Spring Boot CLI -

    $ spring init -n=heroku-demo -d=web heroku-demo
    Using service at https://start.spring.io
    Project extracted to '/Users/rajeevkumarsingh/heroku-demo'

    The command will generate the application with all the necessary configurations in a directory named heroku-demo.

    You can also use the Spring Initializr web app to generate the application if you don’t want to install Spring Boot CLI:

    • Open http://start.spring.io.
    • Enter heroku-demo in the artifact field.
    • Add Web in the dependencies section.
    • Click Generate Project to generate and download the project.

    This will downloaded a zip archive of the project with all the directories and configurations.

  2. Building a Demo endpoint

    Let’s add a controller endpoint to the application so that it responds with a message whenever we access the root (/) endpoint.

    Create a file named IndexController.java inside src/main/java/com/example/herokudemo/, and add the following code to it -

    package com.example.herokudemo;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class IndexController {
        @GetMapping("/")
        public String index() {
            return "Hello there! I'm running.";
        }
    }
  3. Running the app

    You can run the app using the following command -

    $ mvn spring-boot:run

    The app will start on port 8080 by default. You can access it by going to http://localhost:8080. You should see the message Hello there! I'm running..

Deploying a Spring Boot app on Heroku using Git and Heroku CLI

All right! Now that we have a sample app, let’s learn how to deploy it to Heroku. In this section we’ll deploy the app using Git and Heroku CLI.

You need to have a Heroku account. If you don’t have one, you can create it from Heroku’s Signup Page. Once you’re registered with Heroku, follow the steps below to deploy the Spring Boot app.

  1. Download and install Heroku CLI

    Heroku CLI is a command line application that lets you create, deploy and manage Heroku apps from the command line. You can download Heroku CLI from Heroku Dev Center. You’ll also find the instructions for installing Heroku CLI on your platform on that page.

  2. Login using your email and password

    Enter the following command to login to Heroku using Heroku CLI

    heroku login

    You will be prompted to enter your Heroku account’s email and password. Enter all the details -

    Enter your Heroku credentials:
    Email: youremail@example.com
    Password: **************
    Logged in as youremail@example.com

    That’s it! You’re logged in to Heroku. We can now proceed with the deployment.

  3. Set up Git and create a Heroku app

    Execute the following commands from the root directory of the project to create a local Git repository for the project -

    git init
    git add .
    git commit -m "initial commit"

    Now, create a new heroku app using heroku create command like so -

    $ heroku create
    Creating app... done, ⬢ apple-custard-73702
    https://apple-custard-73702.herokuapp.com/ | https://git.heroku.com/apple-custard-73702.git

    The above command creates a new heroku app and also makes a remote repository for the app at Heroku.

    Heroku chooses a random unique name for the app by default. If you want to specify a custom name then you can pass the app name in the heroku create command like this -

    heroku create <YOUR_UNIQUE_APP_NAME>

    You can also rename an existing app using heroku apps:rename command -

    heroku apps:rename --app <OLD_NAME> <NEW_NAME>

    Let’s use the above command to rename our app -

    $ heroku apps:rename --app apple-custard-73702 callicoder-heroku-demo
    Renaming apple-custard-73702 to callicoder-heroku-demo... done
    https://callicoder-heroku-demo.herokuapp.com/ | https://git.heroku.com/callicoder-heroku-demo.git
    Git remote heroku updated
     ▸    Don't forget to update git remotes for all other local checkouts of the app.
  4. Deploy the app to Heroku

    Finally, you can deploy the app by simply pushing the code to the remote repository named heroku which was created by the heroku create command.

    git push heroku master

    Heroku automatically detects that the project is a Maven/Java app and triggers the build accordingly.

    The deployment will take some time. You should see the build logs on console. Once the application is deployed, you can open it using the following command -

    heroku open

    The app should open in the system’s default browser and you should see the message Hello there! I'm running..

    You can see the logs of the application anytime by running the following command -

    heroku logs --tail

This is the easiest method of deploying spring boot apps to Heroku. But its not the ideal option if -

  • Your project doesn’t use Git.
  • Your project is closed source and you don’t want to push the source code to Heroku.
  • Your project uses some dependencies that are internal to your company. In this case the source code won’t compile at Heroku because it won’t be able to download the internal dependencies.

Deploying a Spring Boot app on Heroku using Heroku CLI Deploy Plugin

Unlike the previous method, this heroku deployment method doesn’t require you to setup a Git repository for your project and push the source code to Heroku.

You can build and package the app locally and deploy the packaged jar file to Heroku. This is done using Heorku CLI Deploy Plugin. It allows you to deploy a pre-built jar or war file to Heroku.

Follow the steps below to deploy a Spring Boot app on Heroku using Heroku CLI Deploy plugin:

  1. Install Heroku Deploy CLI Plugin

    Enter the following command in your terminal to install the heroku-cli-deploy plugin:

    heroku plugins:install heroku-cli-deploy
  2. Package your Spring Boot application

    Next, you’ll need to package the application in the form of a jar file. You can do that using mvn package command -

    mvn clean package

    This command will create a packaged jar file of the application in the target folder of the project.

  3. Create a Heroku app

    Now let’s create a Heroku app using heroku create command -

    heroku create <APP-NAME> --no-remote

    Notice the use of --no-remote option. This tells heroku to not setup any git remote repository.

  4. Deploy the jar file on Heroku

    Finally, you can deploy the jar file using the following command -

    heroku deploy:jar target/heroku-demo-0.0.1-SNAPSHOT.jar --app <APP-NAME>

    The above command should have deployed the app successfully. But there is a caveat here. Let’s check the logs of the application to understand that-

    heroku logs --tail --app <APP-NAME>

    If you check the logs using the above command, you’ll notice an error like this -

    Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 90 seconds of launch

    Heroku requires our application to listen on the port passed through $PORT environment variable. But the spring boot application listens on port 8080 by default.

    Fixing the Port binding error

    There are two ways of fixing the port binding error:

    • You can specify the port that the application should listen to in a property named server.port in the src/main/java/resources/application.properties file -

      server.port=${PORT:8080}

      The above property will evaluate to the PORT environment variable if it is available, otherwise it will fall back to the default port 8080.

    • Alternatively, you can use a Procfile to customize the command that is used to run the application. The customized command would include the server.port configuration that will be used by Spring Boot to bind the app.

      Create the Procfile in the root directory of the project with the following configuration -

      # Procfile
      web: java $JAVA_OPTS -jar target/heroku-demo-0.0.1-SNAPSHOT.jar -Dserver.port=$PORT $JAR_OPTS

    After doing one of the above two, You can deploy the app using the same heroku deploy:jar command -

    heroku deploy:jar target/heroku-demo-0.0.1-SNAPSHOT.jar --app <APP-NAME>

    This time the application should start successfully. You can verify that by opening the app in the browser using heroku open command.

Deploying a Spring Boot app on Heroku using Heroku Maven Plugin

The Heroku Maven plugin allows you to deploy any maven application without having to install Heroku CLI. It integrates the deployment into your build system, and works out of the box with any CI / CD server like Jenkins or Travis CI.

Moreover, it keeps all the configurations in a single place (the pom.xml file), and therefore eliminates the need of a Procfile.

Follow the steps below to deploy your spring boot application using Heroku Maven Plugin.

  1. Adding and Configuring Heroku Maven Plugin

    Add the heroku-maven-plugin to the plugins section of your pom.xml file -

    <build>
    	<plugins>
    
    		<!-- Heroku Maven Plugin Configuration -->
    		<plugin>
    		      <groupId>com.heroku.sdk</groupId>
    		      <artifactId>heroku-maven-plugin</artifactId>
    		      <version>2.0.3</version>
    		      <configuration>
    		          <appName>callicoder-heroku-maven-demo</appName>
    		          <includeTarget>false</includeTarget>
    		          <includes>
    		              <include>${project.build.directory}/${project.build.finalName}.jar</include>
    		          </includes>
    		          <jdkVersion>${java.version}</jdkVersion>
    		          <processTypes>
    		              <web>java $JAVA_OPTS -jar ${project.build.directory}/${project.build.finalName}.jar</web>
    		          </processTypes>
    		      </configuration>
    		  </plugin>
    		  
    	</plugins>
    </build>

    Change the <appName> configuration to an app name of your choice.

  2. Creating the app

    You can create an app either using Heroku CLI or from the Heroku dashboard. To create the app using Heroku CLI, type the following command in your terminal -

    heroku create callicoder-heroku-maven-demo

    Don’t forget to change the name callicoder-heroku-maven-demo to the app name that you’ve set in the pom.xml file.

If you don't want to install Heroku CLI, then create the app from the [dashboard](https://dashboard.heroku.com/).
  1. Deploying the app using Heroku maven plugin

    If you have Heroku CLI installed, then use the following maven command to deploy the application -

    mvn clean heroku:deploy

    If you don’t have Heroku CLI installed, then you need to set the HEROKU_API_KEY environment variable before running heroku:deploy -

    HEROKU_API_KEY="YOUR HEROKU API KEY" mvn clean heroku:deploy

    You can find the API key from Heroku dashboard.

Resources

The demo project that we built and deployed to heroku in this post is available on Github.

You can also check out the following official Heroku resources to learn more about deployment of spring boot apps to Heroku.

Thanks for reading. In the next article, you’ll learn how to deploy spring boot applications on AWS using Elastic beanstalk. Also, Don’t forget to subscribe to my newsletter to get notified whenever I publish new articles on the blog.