Flyway database migration
To prevent application startup failure for larger migrations due to Kubernetes probes it’s essential that databases are migrated outside of Kubernetes via the Continuous Delivery pipeline. This page attempts to show the steps required to perform a safe database migration.
For a more detailed explanation on why this is necessary see: Making a database schema change
Example pull request
Alternatively see below for a step-by-step guide.
Config
Enable database migration for Jenkins:
- Add
enableDbMigration(product)
toJenkinsfile_CNP
file
Add config to build.gradle
:
- Ensure the latest flyway version is set e.g.
id 'org.flywaydb.flyway' version '<VERSION_NUMBER>'
- Add this block:
flyway {
url = System.getenv('FLYWAY_URL')
user = System.getenv('FLYWAY_USER')
password = System.getenv('FLYWAY_PASSWORD')
baselineOnMigrate = true
baselineVersion = '000'
}
task migratePostgresDatabase(type: org.flywaydb.gradle.task.FlywayMigrateTask) {
baselineOnMigrate = true
if (project.hasProperty("dburl")) {
url = "jdbc:postgresql://${dburl}"
}
}
Ensure the RUN_DB_MIGRATION_ON_STARTUP
is configured appropriately:
- Add
RUN_DB_MIGRATION_ON_STARTUP: true
to thevalues.preview.template.yaml
file - This is so that preview will migrate on startup - Add
RUN_DB_MIGRATION_ON_STARTUP: false
to thevalues.yaml
file
Set the migration to run on app startup
- In
application.yaml
set:
dbMigration:
# When true, the app will run DB migration on startup.
# Otherwise, it will just check if all migrations have been applied (and fail to start if not).
runOnStartup: ${RUN_DB_MIGRATION_ON_STARTUP:true}
Java files
Make sure you update the package name to match your application’s in the below examples
- Add a class to configure flyway:
package uk.gov.hmcts.reform.example;
import org.flywaydb.core.Flyway;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationStrategy;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import uk.gov.hmcts.reform.example.data.migration.FlywayNoOpStrategy;
@AutoConfigureAfter({
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class
})
@AutoConfigureBefore(FlywayAutoConfiguration.class)
@Configuration
@ConditionalOnClass(Flyway.class)
@ConditionalOnProperty(prefix = "dbMigration", name = "runOnStartup", havingValue = "false")
public class FlywayConfiguration {
@Bean
public FlywayMigrationStrategy flywayMigrationStrategy() {
return new FlywayNoOpStrategy();
}
}
- And then this class to do the flyway migration:
package uk.gov.hmcts.reform.example.data.migration;
import org.flywaydb.core.Flyway;
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationStrategy;
import uk.gov.hmcts.reform.example.controller.exception.PendingMigrationScriptException;
import java.util.stream.Stream;
public class FlywayNoOpStrategy implements FlywayMigrationStrategy {
@Override
public void migrate(Flyway flyway) {
Stream.of(flyway.info().all())
.filter(info -> !info.getState().isApplied())
.findFirst()
.ifPresent(info -> {
throw new PendingMigrationScriptException(info.getScript());
});
}
}
- Migration exception class:
package uk.gov.hmcts.reform.example.data.exception;
public class PendingMigrationScriptException extends RuntimeException {
public PendingMigrationScriptException(String script) {
super("Found migration not yet applied: " + script);
}
}
This page was last reviewed on 18 August 2024.
It needs to be reviewed again on 18 February 2025
by the page owner platops-build-notices
.
This page was set to be reviewed before 18 February 2025
by the page owner platops-build-notices.
This might mean the content is out of date.