I’ve seen a fair number of support tickets where customers are using Liquibase with Spring Boot on Heroku, and a few months back, I helped some folks get it working, here’s the secret…

By default, it applies the schema changes on boot, which for updates, can take some time, and cause your app not to boot, this manifests as an R10 error.

A while back, my colleagues released a new “release-phase” mechanism, which allows you to specify a process which should run before your main deployments, this is an ideal point to run your database migrations.

Doing this with a Spring Boot application and Liquibase is fairly easy…

First off, you’ll need to disable Liquibase in your Spring application.properties.

spring.liquibase.enabled=false

Ensure your package is using the Maven Wrapper, Maven is not available by default in the Dynos.

Add the Liquibase plugin to your pom.xml, there’s plenty of information here.

    <build>
        <plugins>
            ...
            <plugin>
                <groupId>org.liquibase</groupId>
                <artifactId>liquibase-maven-plugin</artifactId>
                <version>3.6.2</version>
            </plugin>
        </plugins>
    </build>

Finally, you need to add a new release process to your Procfile.

release: ./mvnw -Dliquibase.changeLogFile=src/main/resources/db/changelog/db.changelog-master.yaml -Dliquibase.url=$JDBC_DATABASE_URL -Dliquibase.promptOnNonLocalDatabase=false liquibase:update

The Liquibase Maven plugin doesn’t have any knowledge of Spring, so it will not take any of the spring.liquibase properties you may have already defined.

For more information on configuring the Maven Liquibase plugin see the instructions.

If you don’t have a Procfile, you’re probably relying on the default process being executed by the Java Buildpack, the easiest way to get a Procfile is to copy the command-line for your web process and use that as the web process, something like this.

web: java -Dserver.port=$PORT $JAVA_OPTS -jar target/my-web-service-0.0.1-SNAPSHOT.jar