DEV Community

Cover image for Flyway Migration: From Legacy Database to CI/CD
Farooq Hussain
Farooq Hussain

Posted on Originally published at Medium AI-assisted

Flyway Migration: From Legacy Database to CI/CD

Most teams think of Flyway only when they need to manage ongoing database schema changes. But what if your project already has a complete, stable schema and youโ€™re only now introducing version control? Or what if you want to incorporate your schema into a CI/CD pipeline for reliable, reproducible deployments?

In this guide, Iโ€™ll walk you through a real-world scenario where we used Flyway to baseline an existing MySQL database and then extended it to support version-controlled schema migrations in CI/CD, without disrupting production.

๐Ÿš€ What is Flyway?

Flyway is a simple but powerful tool for managing database migrations. It applies versioned SQL scripts to your database and tracks them in a special table called flyway_schema_history.

Typical script names:

V1__initial_schema.sql
V2__add_orders_table.sql
V3__rename_column.sql
Enter fullscreen mode Exit fullscreen mode

Flyway ensures these scripts run only once and in the correct order. It also integrates well with CI/CD tools, making it ideal for automated environments.

๐Ÿ“˜ Use Case: Existing Schema with No Migrations (Yet)

In our project, we had:

  • A production MySQL database with dozens of tables
  • No migration history
  • No current need for structural changes
  • A desire to version control the database and enable future migrations via CI/CD

๐Ÿงฑ Step 1: Baselining an Existing Schema

๐Ÿ”น Dump the schema

mysqldump -u root -p --no-data your_database > V1__baseline_schema.sql
Enter fullscreen mode Exit fullscreen mode

Clean the output: remove auto-increments, user references, and environment-specific SQL.

๐Ÿ”น Create directory structure

mkdir -p db/sql
mv V1__baseline_schema.sql db/sql/
Enter fullscreen mode Exit fullscreen mode

๐Ÿ”น Configure flyway.conf

flyway.url=jdbc:mysql://your-db-host:3306/your_database
flyway.user=db_user
flyway.password=secret_password
flyway.locations=filesystem:db/sql
flyway.baselineOnMigrate=true
Enter fullscreen mode Exit fullscreen mode

๐Ÿ”น Run baseline

flyway baseline
Enter fullscreen mode Exit fullscreen mode

This creates the flyway_schema_history table and marks version 1 as the current state without running any script.

๐Ÿงช Step 2: Add a Real Migration

After baselining, we added a real change in a new script

-- db/sql/V2__add_status_to_orders.sql
ALTER TABLE orders ADD COLUMN status VARCHAR(20) DEFAULT 'pending';
Enter fullscreen mode Exit fullscreen mode

Then we ran:

flyway migrate
Enter fullscreen mode Exit fullscreen mode

Result: Flyway applied version 2, recorded it in history, and our database was now safely versioned.

โš™๏ธ Step 3: Integrate Flyway into CI/CD

You can integrate Flyway with GitHub Actions, GitLab CI, Bitbucket Pipelines, or Jenkins.

โœ… Example GitHub Actions Workflow

name: Flyway Migration
on:
  push:
    branches: [ main ]

jobs:
  migrate:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v3
      - name: Set up Java (Flyway needs it)
        uses: actions/setup-java@v3
        with:
          distribution: 'temurin'
          java-version: '17'
      - name: Install Flyway
        run: |
          curl -L https://repo1.maven.org/maven2/org/flywaydb/flyway-commandline/10.8.1/flyway-commandline-10.8.1-linux-x64.tar.gz | tar xvz
          sudo ln -s $PWD/flyway-10.8.1/flyway /usr/local/bin/flyway
      - name: Run Flyway Migrations
        env:
          FLYWAY_URL: jdbc:mysql://your-host:3306/your_database
          FLYWAY_USER: ${{ secrets.DB_USER }}
          FLYWAY_PASSWORD: ${{ secrets.DB_PASSWORD }}
        run: |
          flyway -url=$FLYWAY_URL \
                 -user=$FLYWAY_USER \
                 -password=$FLYWAY_PASSWORD \
                 -locations=filesystem:./db/sql \
                 migrate
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“ฆ Benefits of This Approach

โœ… You gain auditability for all database changes

โœ… Developers can build local environments using the same scripts

โœ… CI/CD ensures consistency across all environments

โœ… Flywayโ€™s validate command catches missing or changed scripts

โœ… Schema management becomes part of your software delivery lifecycle

๐Ÿงฑ Potential Challenges

Problem โ†’ Fix

  • Flyway re-applies the baseline script โ†’ Use baselineOnMigrate=true and never modify a baseline
  • Passwords in config files โ†’ Use secrets and environment variables in CI/CD
  • Manual schema drift โ†’ Disable direct DB access in prod or run flyway validate periodically
  • Need rollback support โ†’ Write manual undo scripts or use point-in-time backups

๐Ÿ” Alternatives (and Why Flyway Wins)

๐Ÿ”น Liquibase
โœ… Pros: Advanced features, rollback support
โŒ Cons: More complex, steeper learning curve

๐Ÿ”น Django ORM / Alembic
โœ… Pros: Built-in for app devs
โŒ Cons: Not cross-language or DB-agnostic

๐Ÿ”น Manual SQL or DB dumps
โœ… Pros: Simple
โŒ Cons: No versioning, no tracking, no automation

Flyway is a great middle-ground: powerful enough for teams, simple enough for solo devs, and perfect for CI/CD.

๐Ÿง  Final Thoughts

Flyway isnโ€™t just for teams writing migrations every day. Itโ€™s also ideal for bringing an existing database under version control, giving your project a foundation for safe schema evolution.

We started with a baseline, added our first real migration, and then built it into our CI/CD pipeline โ€” all in a dayโ€™s work.

If youโ€™re managing an existing DB without schema tracking, nowโ€™s the time to fix that. Start with a baseline. Your future self will thank you.

๐Ÿ“ฃ Letโ€™s Connect!

Have you tried Flyway for baseline-only use cases or integrated it into your CI/CD pipeline? Iโ€™d love to hear your experience in the comments.

If you found this helpful, follow me here on DEV for more DevOps and database engineering content.

Top comments (0)