Toan Ng

Continuous Deployment with and GitHub Actions

Example project showing how to run Spring Boot apps on

You can find the code at Github


To deploy a backend service for demo or personal purposes, a platform is essential. However, the popular platform Heroku is becoming increasingly costly.

This may require individuals or businesses to explore alternative options that are more affordable.


So why not start using by checking out their hands-on guide at

Build example Spring Boot app with Dockerfile

As stated in allows you to deploy any kind of app as long as it is packaged in a Docker image. That also means you can just deploy a Docker image and as it happens we have one ready to go in flyio/hellofly:latest.

That means you can use the proposed command flyctl launch --image flyio/hellofly:latest - but this would only launch a pre-build app based on the image flyio/hellofly

But as we want to use our own Spring Boot project at we need to create a Docker image first.

Spring Boot project is created by using with the following dependencies: spring-initializer

In the root of our project we can create a Dockerfile like this:

# Base image
FROM openjdk:17-jdk-slim

# Keep consistent with pom.xml

RUN mkdir /app

ADD ./target/flyio.jar /app/


# Expose port

ENTRYPOINT ["java", "-Duser.timezone=Asia/Saigon", "-jar", "flyio.jar"]

Note: By default, when running mvn package, the Spring Boot Maven Plugin generates a fat jar named ${name}-${version}.jar, with ${name} and ${version} values taken from the pom.xml file. However, it is possible to configure the pom.xml file to generate a jar file with a different name that corresponds to the application name.

For more information on this topic, please refer to this link:

Install flyctl

On a Mac install flyctl via brew:

brew install flyctl

Signup or login to or

fly auth signup

Configure flyctl

In the terminal we can run fly launch to start the interactive configuration process.

You can set app name, region, etc. and then flyctl will generate a fly.toml file for you. This file is used to configure your app and is used by the flyctl CLI.


Setup GitHub Actions

We want to build our Spring Boot app and push the Docker image to GitHub Container Registry. For that we need to create a GitHub Actions workflow in .github/workflows/deployment.yaml that will be triggered on every push to the main branch.

name: Java CI/CD with Maven and

        branches: [ master, main ]


        runs-on: ubuntu-latest
            -   name: Checkout the repo
                uses: actions/checkout@v3

            -   name: Set up JDK 17
                uses: actions/setup-java@v3
                    java-version: '17'
                    distribution: 'adopt'
                    cache: maven

            -   name: Build with Maven
                run: mvn clean package

            -   name: Deploy our Spring Boot app to
                uses: superfly/flyctl-actions/setup-flyctl@master
            -   run: flyctl deploy --remote-only
                    FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

As you can see we need to set the FLY_API_TOKEN secret in the GitHub repository settings. To get the token we need to run flyctl auth token and copy the token.


Deploy Spring Boot app to

Now we can push our changes to the main branch and watch the GitHub Actions workflow running. After a few minutes our Spring Boot app should be deployed to


Access our Spring Boot app on

Finally, our app should now be accessible to the public:


Now that’s pretty cool!