top of page

Welcome
to NumpyNinja Blogs

NumpyNinja: Blogs. Demystifying Tech,

One Blog at a Time.
Millions of views. 

CI/CD Made Easy: Automate the Deployment of a Dockerized Spring Boot App to Heroku with GitHub Actions

May 3, 2025
4 min read

In this post, we'll set up a CI/CD pipeline using GitHub Actions to automatically build and deploy our Dockerized Spring Boot app to Heroku whenever we push changes to a branch.


GitHub Actions Overview :

GitHub Actions is a powerful CI/CD tool built directly into GitHub. It allows developers to automate workflows such as building, testing, and deploying code every time a change is pushed to a repository. Workflows are defined using simple YAML files stored in the .github/workflows directory.

Key features include:

  • Event-driven automation – Trigger workflows on push, pull_request, or schedule-based events.

  • Customizable workflows – Define steps for building, testing, and deploying applications.

  • Integration with Docker and cloud platforms – Seamlessly build and deploy containerized applications.

  • Built-in runner support – Run jobs on GitHub-hosted virtual machines or self-hosted runners.

In the context of this blog, we’ll use GitHub Actions to:

  1. Automatically build our Spring Boot app into a Docker image.

  2. Push the image to Heroku’s Container Registry.

  3. Release the app to Heroku without manual intervention.


Prerequisites:


  • Dockerized Spring Boot app ( You can refer to my other blog to learn how to dockerize a Spring Boot app.. https://www.numpyninjaacademy.com/post/dockerize-a-spring-boot-app-using-docker-compose-a-step-by-step-guide )

  • Heroku account and CLI installed

  • GitHub repository for your app

  • Heroku app created and linked to a GitHub repo

  • Heroku Configuration:

    • Set the stack to Container to use custom Docker images.

  • GitHub Secrets configured:

    • GitHub repository ->Settings -> Secrets and variables → Actions

    • HEROKU_API_KEY: Obtain via heroku auth: token.

    • HEROKU_APP_NAME: Your Heroku app's name.

    • Why is HEROKU_API_KEY needed?

      • This is your authentication token for the Heroku CLI and Docker registry. It allows GitHub Actions to:

        • Log in to Heroku's container registry.

        • Release the Docker image.

        • Check Heroku logs or dyno status.

    Without this key, GitHub Actions can't authenticate with Heroku and will be denied access.


With all of these set up are ready, we can go ahead with creating a Workflow file for GitHub actions.

As a first step, you should create your GitHub Actions workflow file in .github/workflows/deploy.yml inside your project repository. Your project folder structure might look like this:


your-project/

├── .github/

│ └── workflows/

│ └── deploy.yml <-- Your workflow file. You can name anything meaningful. But the extension should be .yml.



name: Deploying Dockerized app to Heroku
on:
push:
 branches:
 - main # Trigger on changes to the main branch
jobs:
deploy:
 runs-on: ubuntu-latest
 steps:
 # Step 1: Check out the repository code
 - name: Checkout Repository
 uses: actions/checkout@v3

 # Step 2: Install Heroku CLI
 - name: Install Heroku CLI

 run: curl https://cli-assets.heroku.com/install.sh | sh
 # Step 3: Set up JDK
 - name: Set up JDK 17
 uses: actions/setup-java@v3
 with:
 java-version: '17'
 distribution: 'temurin'

 # Step 4: Build the application with Maven
 - name: Build with Maven
 run: mvn clean package

 # Step 5: Verify the JAR File
 - name: Verify JAR File
 run: ls -la target/
 continue-on-error: false # Fail if the JAR file is not found

 # Step 6: Log in to Heroku Container Registry
 - name: Log in to Heroku Container Registry
 run: |
 echo $ {{ secrets.HEROKU_API_KEY }} | docker login --username=_ --password-stdin registry.heroku.com

 # Step 7: Build and Push Docker Image
 - name: Build and Push Docker Image
 run: |
 herokuContainer=registry.heroku.com/$ {{ secrets.HEROKU_APP_NAME }}/web
 docker build -t $herokuContainer .
 docker push $herokuContainer

 # Step 8: Release the New Docker Image to the Heroku App
 - name: Release Image on Heroku
 env:
 HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}
 run: heroku container:release web -a $ {{ secrets.HEROKU_APP_NAME }}

Now, let's dig deep into the file and understand what each steps do.

  • On:

    Push:

    Branches:

    - main

    It triggers the workflow only when you push to the main branch.


  • Jobs:

    Deploy:

    runs-on: ubuntu-latest

    This tells GitHub Actions to run the deploy job on a virtual machine (VM) that uses the latest Ubuntu Linux image.

  • Steps :

  • - name: Checkout Repository

    uses: actions/checkout@v3

    This step checks out (downloads) your GitHub repository code into the runner's file system so the rest of the GitHub Actions workflow can access

    your code (like Dockerfile, pom.xml, src/, etc.).

  • - name: Install Heroku CLI

    run: curl https://cli-assets.heroku.com/install.sh | sh

    Installs the Heroku CLI tool so Heroku commands (heroku container:release, heroku ps, etc.) can be used.

  • - name: Set up JDK 17

    uses: actions/setup-java@v3

    With:

    java-version: '17'

    distribution: 'temurin'

    Sets up Java 17 (Temurin) in the GitHub Actions environment — needed to compile your Spring Boot app.

  • - name: Build with Maven

    run: mvn clean package

    Builds our Spring Boot app and generates a .jar file inside the target/ directory.

  • - name: Verify JAR File

    run: ls -la target/

    continue-on-error: false

    Lists the contents of the target/ folder to verify the JAR was successfully created, and the workflow will fail if the JAR is missing.

  • - name: Log in to Heroku Container Registry

    run: |

    echo ${{ secrets.HEROKU_API_KEY }} | docker login --username=_ --password-stdin registry.heroku.com

    Logs into Heroku's Docker container registry using your Heroku API key stored in GitHub Secrets.

  • - name: Build and Push Docker Image

    run: |

    herokuContainer=registry.heroku.com/${{ secrets.HEROKU_APP_NAME }}/web

    docker build -t $herokuContainer .

    docker push $herokuContainer

    docker build: builds our Docker image using the Dockerfile in our repo.

    docker push: pushes the image to Heroku’s registry under the /web process.

  • - name: Release Image on Heroku

    Env:

    HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}

    run: heroku container:release web -a ${{ secrets.HEROKU_APP_NAME }}

    Releases the pushed image to your Heroku app under the web process (which listens for HTTP requests).

Finally, we need to trigger the Workflow:

Push to the Main branch:

git add .
git commit -m "Dockerize and deploy"
git push origin main

GitHub Actions will:

  • Build your Docker image

  • Push it to Heroku’s Container Registry

  • Release the app automatically

Conclusion

Now your app is fully automated: every push to your main branch triggers a CI/CD pipeline, building and deploying your Dockerized Spring Boot application to Heroku with zero manual steps.





 
 

+1 (302) 200-8320

NumPy_Ninja_Logo (1).png

Numpy Ninja Inc. 8 The Grn Ste A Dover, DE 19901

© Copyright 2025 by Numpy Ninja Inc.

  • Twitter
  • LinkedIn
bottom of page