Master Your Database Migrations with Flyway: A Comprehensive Guide for All Projects

Devops & Infrastructure, Security, Tips & Tricks, and What Is

Master Your Database Migrations with Flyway: A Comprehensive Guide for All Projects

Application code gets version control, automated tests, and one-click deployments. Database schemas? Often they're still managed with hand-run SQL scripts and whispered tribal knowledge. That gap between code deployment and database deployment is where things break.

Flyway is a database migration tool that brings version control principles to your schema. You write numbered SQL files, Flyway tracks what's been applied, and every environment stays in sync. Combined with DeployHQ's build pipelines, you can automate database migrations as a pre-deployment step — so your schema and code always ship together.

This guide covers how Flyway works, how to use it with JVM and non-JVM projects, and how to integrate it into your deployment workflow.

The Database Migration Problem

When database changes are managed manually, teams run into predictable problems:

  • Schema drift — development, staging, and production databases diverge, causing works on my machine failures
  • Error-prone deployments — running SQL scripts by hand is tedious and one wrong statement can cause downtime
  • No audit trail — no record of who changed what, when, or why
  • Difficult rollbacks — reverting a schema change is far harder than reverting a code commit

Migration tools solve this by treating schema changes as versioned, sequential scripts that are applied automatically.

How Flyway Works

Flyway operates on a straightforward principle: versioned migration scripts.

  1. You write migration files — plain SQL files with version numbers: V1__create_users_table.sql, V2__add_email_column.sql
  2. Flyway tracks state — a flyway_schema_history table in your database records every applied migration, its checksum, and when it ran
  3. Flyway applies the diff — on each run, it compares your migration files against the history table and applies only the pending ones, in order
  4. Checksums catch tampering — if an already-applied script is modified, Flyway detects the mismatch and stops, preventing silent corruption
  5. Every environment stays in sync — the same migrations run in dev, staging, and production, eliminating drift

Flyway for JVM Projects

Flyway originated in the Java ecosystem and integrates deeply with JVM build tools.

Java API

Run migrations programmatically — useful for applying them on application startup:

import org.flywaydb.core.Flyway;

public class DatabaseMigrator {
    public static void main(String[] args) {
        Flyway flyway = Flyway.configure()
            .dataSource("jdbc:postgresql://localhost:5432/mydb", "user", "password")
            .locations("classpath:db/migration")
            .load();
        flyway.migrate();
        System.out.println("Database migration completed successfully!");
    }
}

Maven Plugin

Add Flyway to your build lifecycle:

<build>
    <plugins>
        <plugin>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-maven-plugin</artifactId>
            <version>11.8.0</version>
            <configuration>
                <url>jdbc:postgresql://localhost:5432/mydb</url>
                <user>user</user>
                <password>password</password>
                <locations>
                    <location>classpath:db/migration</location>
                </locations>
            </configuration>
        </plugin>
    </plugins>
</build>

Run with: mvn flyway:migrate

Gradle Plugin

plugins {
    id "org.flywaydb.flyway" version "11.8.0"
}

flyway {
    url = 'jdbc:postgresql://localhost:5432/mydb'
    user = 'user'
    password = 'password'
    locations = ['classpath:db/migration']
}

Run with: gradle flywayMigrate

Spring Boot Integration

Spring Boot 3.x auto-configures Flyway when you add the flyway-core dependency — migrations run automatically on startup from src/main/resources/db/migration.

Note: Spring Boot 4.x changed this — you now need spring-boot-starter-flyway instead of just flyway-core.

Transactional DDL

For databases that support it (PostgreSQL, SQL Server), Flyway wraps each migration in a transaction. If any statement fails, the entire script rolls back — no partial schema changes.

Flyway for Non-JVM Projects

Flyway's command-line interface works with any language or framework. The CLI download bundles a JRE, so you don't need Java installed separately.

1. Configure your connection

Create a flyway.conf file:

flyway.url=jdbc:mysql://localhost:3306/mydb
flyway.user=root
flyway.password=password
flyway.locations=filesystem:sql/migrations

2. Organise your migration scripts

sql/migrations/
  V1__create_products_table.sql
  V2__add_price_column.sql
  V3__create_orders_table.sql

Version numbers can use dots or underscores as separators (V2.1__ and V2_1__ are both valid).

3. Run migrations

flyway -configFiles=flyway.conf migrate

4. Integrate with CI/CD

Add Flyway as a pre-deployment step in your pipeline. Here's a shell script example:

#!/bin/bash

export FLYWAY_URL="jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DB_NAME}"
export FLYWAY_USER="${DB_USER}"
export FLYWAY_PASSWORD="${DB_PASSWORD}"
export FLYWAY_LOCATIONS="filesystem:./db/migrations"

echo "Running Flyway migrations..."
./flyway migrate

if [ $? -eq 0 ]; then
    echo "Flyway migrations completed successfully!"
else
    echo "Flyway migrations failed!"
    exit 1
fi

In DeployHQ, you can run this as a build pipeline command or SSH pre-deployment hook, with database credentials stored securely as environment variables.

Key Features

  • Plain SQL migrations — write standard SQL, no proprietary syntax required
  • Checksum validation — prevents silent modifications to already-applied scripts
  • Baseline support — bring an existing database under Flyway control without replaying history
  • Validation — detect inconsistencies between your scripts and database state with flyway validate
  • Clean command — wipe schemas for dev/test environments. Warning: this drops ALL objects in configured schemas. Never use in production. Set flyway.cleanDisabled=true in production configs
  • Undo migrations — available in the Enterprise edition. The free Community edition requires manual rollback scripts
  • 50+ databases supported — MySQL, PostgreSQL, Oracle, SQL Server, SQLite, MariaDB, CockroachDB, Snowflake, and many more

Best Practices

  1. One change per migration — each script should be a single, atomic schema change. Don't bundle unrelated changes
  2. Descriptive namesV3__add_index_on_users_email.sql is better than V3__update.sql
  3. Test before production — run migrations in staging first. Tools like Testcontainers can spin up isolated databases for automated testing
  4. Design for backward compatibility — avoid destructive changes (dropping columns) if the current app version depends on them. Use a phased approach: deprecate first, remove in a later migration
  5. Commit migrations to Git — store them alongside your application code so schema history tracks with your codebase. Deploy from GitHub or GitLab and DeployHQ picks them up automatically
  6. Automate with CI/CD — run migrations as a pre-deployment step, not manually. DeployHQ's build pipelines handle this natively
  7. Use minimal database privileges — create a dedicated migration user with only the permissions Flyway needs
  8. Always back up before migrating production — Flyway is reliable, but backups are non-negotiable

How Flyway Works with DeployHQ

DeployHQ supports Flyway through its build pipeline and hook system:

  • Build pipelines — run flyway migrate (or Maven/Gradle commands) as a build step before files are deployed
  • Pre-deployment SSH hooks — execute migrations directly on your server before the new code goes live
  • Environment variables — store DB_HOST, DB_USER, DB_PASSWORD securely without hardcoding credentials
  • Deployment history — full visibility into every deployment, including migration outcomes
  • One-click rollback — revert your application deployment if a migration causes issues
  • Deploy from GitHub, GitLab, or Bitbucket — your migration scripts deploy alongside your code from any provider

Flyway vs Alternatives

Flyway isn't the only migration tool. Here's how it compares:

Tool Ecosystem Key Difference
Liquibase Java / cross-platform Supports XML/YAML/JSON changelogs in addition to SQL. More enterprise-oriented
Alembic Python (SQLAlchemy) Auto-generates migrations from model changes. Python-native
Prisma Migrate Node.js / TypeScript Schema-first approach with auto-generated SQL
Atlas Go / cross-platform Declarative schema-as-code with HCL syntax
Django Migrations Python (Django) Built into the framework, auto-detects model changes

Flyway's strength is its simplicity: plain SQL files, no proprietary format, and it works with any language via the CLI.

Licensing

Flyway offers two editions:

  • Community (free, open source) — core migration features, checksum validation, CLI + Maven + Gradle support
  • Enterprise (paid) — adds undo migrations, dry runs, Oracle SQL*Plus support, and priority support from Redgate

The free Community edition covers the majority of use cases.

FAQ

Q: Does Flyway work with MySQL? A: Yes. Flyway supports 50+ databases including MySQL, PostgreSQL, Oracle, SQL Server, SQLite, MariaDB, and CockroachDB. See the full list.

Q: Do I need Java installed to use Flyway? A: Not if you use the CLI — it bundles a JRE. For JVM projects using Maven/Gradle plugins, you'll already have Java in your build environment.

Q: Can I use Flyway with a Node.js or Python project? A: Yes. Use the Flyway CLI to run migrations from any language. Write your migrations in plain SQL and integrate the CLI into your build scripts.

Q: Is Flyway free? A: The Community edition is free and open source. The Enterprise edition adds advanced features like undo migrations. See Redgate's pricing for details.

Q: What happens if I accidentally modify an already-applied migration? A: Flyway detects the checksum mismatch and halts, preventing further migrations. You can use flyway repair to update the stored checksum if the change was intentional.


Database migrations don't have to be a manual, error-prone process. Flyway gives you version-controlled, repeatable schema changes — and when paired with DeployHQ, those migrations run automatically as part of every deployment.

Start your free DeployHQ trial and automate your database migrations alongside your code deployments. See pricing for team plans.


Questions? Reach out at support@deployhq.com or @deployhq.