Sign inSign up

bthdev/db-migration-runner

By bthdev

•Updated over 1 year ago

A CLI tool for database schema migrations supporting SQL Server, PostgreSQL, and SQLite.

Image
0

1.2K

bthdev/db-migration-runner repository overview

⁠Database Migration Runner (bthdev/db-migration-runner)

This Docker image provides a flexible and robust runner for applying database migrations using the FluentMigrator library. It supports migrations written in both C# (compiled into assemblies) and raw SQL scripts, executing them in the correct order based on their timestamps.

⁠Features

  • Multiple Database Support: Works seamlessly with SQL Server, PostgreSQL, and SQLite.
  • Interleaved Migrations: Discovers both C# migrations (from .dll assemblies) and .sql scripts within the specified migration directory.
  • Timestamp-Based Ordering: All discovered migrations (C# and SQL) are combined and executed strictly in the order defined by their timestamps (the first 12 digits of the C# class name or SQL filename, e.g., YYYYMMDDHHMM).
  • Transactional Execution: Each migration step (C# class or SQL script) is executed within its own transaction to ensure atomicity.
  • Automatic Version Tracking: Uses FluentMigrator's standard version table (VersionInfo by default) to track applied migrations and prevent re-running them.
  • Error Handling: If any migration fails, the process stops immediately, the transaction for that specific migration is rolled back, and a detailed error is logged. Subsequent migrations will not be attempted.
  • Configurable: Database type and connection string are provided via environment variables.
  • Logging: Outputs detailed logs to the console and also writes critical errors to a logs/migration-error.log file within the container (can be mounted to host).

⁠How to Use

Place your migration files (.dll assemblies containing C# migrations and/or .sql scripts) in a single directory. Ensure filenames/class names follow the timestamp convention (YYYYMMDDHHMM_YourDescription).

⁠Running with Docker

Mount your migrations directory and optionally a logs directory into the container. Provide the database type and connection string as environment variables.

Environment Variables:

  • DATABASE_TYPE: The target database (SqlServer, PostgreSql, or SQLite). Case-insensitive.
  • CONNECTION_STRING: The connection string for your database. Important: Ensure the database user has necessary permissions (schema changes, data manipulation).
  • MIGRATIONS_PATH (Optional): Path inside the container where migrations are located. Defaults to /app/migrations.

Example (Windows - PowerShell):

# Create directories if they don't exist
mkdir C:\path\to\your\migrations
mkdir C:\path\to\your\logs

# Run the migration
docker run --rm `
  -v C:\path\to\your\migrations:/app/migrations `
  -v C:\path\to\your\logs:/app/logs `
  -e DATABASE_TYPE="<DatabaseType>" `
  -e CONNECTION_STRING="<Your_Connection_String>" `
  bthdev/db-migration-runner:latest

Example (Linux/macOS - Bash):

# Create directories if they don't exist
mkdir -p /path/to/your/migrations
mkdir -p /path/to/your/logs

# Run the migration
docker run --rm \
  -v /path/to/your/migrations:/app/migrations \
  -v /path/to/your/logs:/app/logs \
  -e DATABASE_TYPE="<DatabaseType>" \
  -e CONNECTION_STRING="<Your_Connection_String>" \
  bthdev/db-migration-runner:latest

Replace <DatabaseType> (e.g., PostgreSql) and <Your_Connection_String> with your actual values.

⁠Running with Kubernetes

You can run the migration as a Kubernetes Job. This is ideal for applying migrations as part of a deployment process.

1. Create a Secret for the Connection String:

kubectl create secret generic db-connection-secret --from-literal=connectionString='<Your_Connection_String>'

2. Create a migration-job.yaml file:

apiVersion: batch/v1
kind: Job
metadata:
  name: db-migration-job-<unique-suffix> # Add a unique suffix/timestamp if needed
spec:
  template:
    spec:
      containers:
      - name: migrator
        image: bthdev/db-migration-runner:latest
        env:
        - name: DATABASE_TYPE
          value: "<DatabaseType>" # e.g., PostgreSql
        - name: CONNECTION_STRING
          valueFrom:
            secretKeyRef:
              name: db-connection-secret
              key: connectionString
        # Mount migrations via a ConfigMap or PersistentVolumeClaim
        volumeMounts:
        - name: migration-files
          mountPath: /app/migrations
        # Optionally mount a volume for logs
        # - name: migration-logs
        #   mountPath: /app/logs
      # Define the volume for migrations (adjust source as needed)
      volumes:
      - name: migration-files
        configMap:
          name: my-migration-scripts # Or use a persistentVolumeClaim, etc.
      # Optionally define a volume for logs
      # - name: migration-logs
      #   persistentVolumeClaim:
      #     claimName: my-logs-pvc
      restartPolicy: Never # Important for Jobs
  backoffLimit: 1 # Number of retries on failure

3. Customize and Apply:

  • Replace <DatabaseType> in the YAML.
  • Replace <unique-suffix> with something meaningful or omit if managing jobs externally.
  • Crucially: Configure the volumes and volumeMounts section to correctly provide your migration .dll and .sql files to the /app/migrations path. This typically involves creating a ConfigMap from your SQL files and potentially building a custom image or using an init container to place DLLs if they aren't already in the main image or another volume.
  • Apply the job: kubectl apply -f migration-job.yaml

4. Monitor the Job:

  • Check status: kubectl get job db-migration-job-<unique-suffix>
  • View logs: kubectl logs job/db-migration-job-<unique-suffix>

For issues or contributions, please refer to the Source Repository⁠.

Tag summary

Content type

Image

Digest

sha256:62141c6b7…

Size

84 MB

Last updated

over 1 year ago

docker pull bthdev/db-migration-runner