Skip to content
flyway-backend-docker logo

Flyway Backend Docker Skill

flyway-backend-docker

Setup backend project with Flyway SQL migrations, tini init system, and MySQL integration testing. Modifies existing Dockerfile from backend-docker skill.

SKILL.md

Full skill instructions

Flyway Backend Docker Skill

This skill configures a backend project to use Flyway for SQL schema management. It modifies an existing Dockerfile (created by the backend-docker skill) to add tini as init system and Flyway migrations that run before the application starts.

Prerequisites

  • backend-docker skill must be applied first - A Dockerfile must already exist
  • Docker installed and running
  • MySQL or compatible database will be used

When to Invoke This Skill

Invoke this skill when ANY of these conditions are true:

  1. User asks for Flyway setup: "add flyway", "setup flyway migrations", "database migrations with flyway"
  2. User needs SQL schema management: "manage database schema", "SQL migrations"
  3. User wants tini + flyway in Docker: "run migrations before app starts"
  4. Backend needs MySQL with migrations: "setup mysql with migrations"

Workflow

Step 1: Verify Dockerfile Exists

# Check for existing Dockerfile (from backend-docker skill)
ls ${BACKEND_PATH}/​Dockerfile

If Dockerfile does not exist, invoke the backend-docker skill first.

Step 2: Create SQL Directory Structure

Create the ./​sql directory with the AGENTS.md file:

mkdir -p ${BACKEND_PATH}/​sql

Create ${BACKEND_PATH}/​sql/​AGENTS.md:

# SQL Migrations Directory

This folder contains Flyway SQL migration files.

## IMPORTANT: Agent Rules

**DO NOT** modify or delete any existing files in this folder.

**ONLY** add new migration files following the Flyway naming convention:
- `V{version}__{description}.sql` for versioned migrations
- `U{version}__{description}.sql` for undo migrations (optional)
- `R__{description}.sql` for repeatable migrations

### Naming Convention Examples

- `V1__create_users_table.sql`
- `V2__add_email_to_users.sql`
- `V3__create_orders_table.sql`
- `R__refresh_views.sql`

### Why This Restriction?

Flyway tracks applied migrations by checksum. Modifying an already-applied migration will cause:
- Migration failures
- Checksum mismatch errors
- Database inconsistency

If you need to change existing schema, create a NEW migration file with the next version number.

Step 3: Create Hello World Migration

Create ${BACKEND_PATH}/​sql/​V1__hello_world.sql:

-- Flyway Hello World Migration
-- This validates that Flyway is correctly configured

CREATE TABLE IF NOT EXISTS flyway_hello_world (
    id INT AUTO_INCREMENT PRIMARY KEY,
    message VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO flyway_hello_world (message) VALUES ('Hello from Flyway!');

Step 4: Create Entrypoint Script

Create ${BACKEND_PATH}/​docker-entrypoint.sh:

#!/​bin/​sh
set -e

echo "=== Running Flyway migrations ==="

# Wait for database to be ready
until nc -z -v -w30 ${DB_HOST:-db} ${DB_PORT:-3306}
do
  echo "Waiting for database connection at ${DB_HOST:-db}:${DB_PORT:-3306}..."
  sleep 2
done

echo "Database is up - running migrations"

# Run Flyway migrations
flyway -url="jdbc:mysql://${DB_HOST:-db}:${DB_PORT:-3306}/​${DB_NAME:-app}?allowPublicKeyRetrieval=true&useSSL=false" \
       -user=${DB_USER:-root} \
       -password=${DB_PASSWORD:-root} \
       -locations=filesystem:/​app/​sql \
       -connectRetries=5 \
       migrate

echo "=== Flyway migrations complete ==="
echo "=== Starting application ==="

# Execute the main command (passed as arguments)
exec "$@"

Step 5: Modify Existing Dockerfile

Read the existing Dockerfile and apply these modifications:

5a: Add Flyway Dependencies

For Debian/​Ubuntu-based images (python:*-slim, etc.), add after existing apt-get install:

# Install tini, flyway dependencies, and netcat for health checks
RUN apt-get update && apt-get install -y --no-install-recommends \
    tini \
    curl \
    netcat-openbsd \
    default-jre-headless \
    && rm -rf /​var/​lib/​apt/​lists/​*

For Alpine-based images (node:-alpine, golang:-alpine, etc.), add:

# Install tini and dependencies for flyway
RUN apk add --no-cache tini openjdk17-jre-headless curl bash netcat-openbsd
5b: Add Flyway Installation

Add after the dependency installation:

# Install Flyway
ENV FLYWAY_VERSION=10.22.0
RUN mkdir -p /​tmp/​flyway && \
    curl -fSL --retry 3 --retry-delay 5 \
        "https://repo1.maven.org/​maven2/​org/​flywaydb/​flyway-commandline/​${FLYWAY_VERSION}/​flyway-commandline-${FLYWAY_VERSION}-linux-x64.tar.gz" \
        -o /​tmp/​flyway/​flyway.tar.gz && \
    tar -xzf /​tmp/​flyway/​flyway.tar.gz -C /​opt && \
    ln -s /​opt/​flyway-${FLYWAY_VERSION}/​flyway /​usr/​local/​bin/​flyway && \
    rm -rf /​tmp/​flyway

Note: For Alpine images, use linux-alpine-x64.tar.gz instead of linux-x64.tar.gz.

5c: Add SQL and Entrypoint Copies

Add before COPY . .:

# Copy SQL migrations
COPY sql/ /​app/​sql/

# Copy entrypoint
COPY docker-entrypoint.sh /​docker-entrypoint.sh
RUN chmod +x /​docker-entrypoint.sh
5d: Modify ENTRYPOINT and CMD

Replace the existing CMD with ENTRYPOINT + CMD pattern:

For Debian-based images:

ENTRYPOINT ["/​usr/​bin/​tini", "--", "/​docker-entrypoint.sh"]
CMD ["<original-cmd>"]

For Alpine-based images:

ENTRYPOINT ["/​sbin/​tini", "--", "/​docker-entrypoint.sh"]
CMD ["<original-cmd>"]

Where <original-cmd> is the original CMD from the Dockerfile (e.g., python -m uvicorn app.main:app --host 0.0.0.0 --port 8000).

Step 6: Create docker-compose.yml for Testing

Create ${BACKEND_PATH}/​docker-compose.yml:

services:
  db:
    image: mysql:8.0
    container_name: flyway-test-db
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: app
      MYSQL_USER: appuser
      MYSQL_PASSWORD: apppassword
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/​var/​lib/​mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-proot"]
      interval: 5s
      timeout: 5s
      retries: 10
      start_period: 30s

  app:
    build: .
    container_name: flyway-test-app
    environment:
      DB_HOST: db
      DB_PORT: 3306
      DB_NAME: app
      DB_USER: root
      DB_PASSWORD: root
    ports:
      - "8080:8080"
    depends_on:
      db:
        condition: service_healthy

volumes:
  mysql_data:

Step 7: Create Integration Test Script

Create ${BACKEND_PATH}/​test-flyway-integration.sh:

#!/​bin/​bash
set -e

echo "=== Flyway Integration Test ==="

# Cleanup any existing containers
docker compose down -v 2>/​dev/​null || true

# Start MySQL
echo "Starting MySQL container..."
docker compose up -d db

# Wait for MySQL to be healthy
echo "Waiting for MySQL to be ready..."
timeout=90
while [ $timeout -gt 0 ]; do
    if docker compose exec -T db mysqladmin ping -h localhost -u root -proot 2>/​dev/​null; then
        echo "MySQL is ready!"
        break
    fi
    echo "Waiting... ($timeout seconds remaining)"
    sleep 2
    timeout=$((timeout - 2))
done

if [ $timeout -le 0 ]; then
    echo "ERROR: MySQL failed to start within timeout"
    docker compose logs db
    docker compose down -v
    exit 1
fi

# Build and start app (which runs Flyway migrations)
echo "Building and starting app container..."
docker compose up -d --build app

# Wait for app to start and run migrations
echo "Waiting for app to start..."
sleep 15

# Check if app is running
if ! docker compose ps app | grep -q "Up"; then
    echo "ERROR: App container failed to start"
    docker compose logs app
    docker compose down -v
    exit 1
fi

# Verify Flyway migration was applied
echo "Verifying Flyway migration..."
RESULT=$(docker compose exec -T db mysql -u root -proot -D app -e "SELECT message FROM flyway_hello_world LIMIT 1;" 2>/​dev/​null)

if echo "$RESULT" | grep -q "Hello from Flyway!"; then
    echo "SUCCESS: Flyway migration applied correctly!"
    echo "Found message: Hello from Flyway!"
else
    echo "ERROR: Flyway migration verification failed"
    echo "Query result: $RESULT"
    docker compose logs app
    docker compose down -v
    exit 1
fi

# Cleanup
echo "Cleaning up..."
docker compose down -v

echo "=== Integration Test PASSED ==="

Step 8: Validate Setup

Run the integration test:

cd ${BACKEND_PATH}
chmod +x test-flyway-integration.sh docker-entrypoint.sh
./​test-flyway-integration.sh

Expected output:

  • MySQL container starts successfully
  • App container builds and starts
  • Flyway migrations run without errors
  • flyway_hello_world table contains "Hello from Flyway!"

Environment Variables

VariableDefaultDescription
DB_HOSTdbDatabase hostname
DB_PORT3306Database port
DB_NAMEappDatabase name
DB_USERrootDatabase user
DB_PASSWORDrootDatabase password

Adding New Migrations

To add a new migration:

# Create new migration file
touch sql/​V2__create_users_table.sql

IMPORTANT: Never modify existing migration files. Always create new versioned migrations.

Error Handling

Flyway Migration Fails

  1. Check database connectivity: Verify DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD
  2. Check SQL syntax: Review migration files for errors
  3. Check Flyway logs: docker compose logs app

Tini Not Found

  1. Verify tini is installed in Dockerfile
  2. Check path: Alpine uses /​sbin/​tini, Debian uses /​usr/​bin/​tini

Database Connection Timeout

  1. Increase wait time in docker-entrypoint.sh
  2. Check MySQL healthcheck in docker-compose.yml

Do NOT Invoke When

  • Project doesn't need SQL schema management
  • Project uses a different migration tool (Liquibase, Alembic, etc.)
  • Project doesn't use a relational database
  • Dockerfile doesn't exist (invoke backend-docker first)

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View