CAPYSQUASH

---

CAPYSQUASH documentation page.

---

Title: Docker Validation. Description: How CAPYSQUASH uses Docker to validate schema equivalence.

DOCKER VALIDATION

CAPYSQUASH uses Docker containers with PostgreSQL to validate that squashed migrations produce the same schema as your originals.

šŸ’” Docker validation is used by CAPYSQUASH Platform, capysquash-cli, and available in pgsquash-engine library.

WHY DOCKER VALIDATION?

THE PROBLEM

How do you verify that consolidated migrations produce the same database schema?

Static analysis has limitations:

SQL is complex with many edge cases PostgreSQL has dialect-specific behaviors Extensions can change semantics Sequence orders matter Implicit conversions exist

The solution: Actually run both migration sets and compare the results.

THREE VALIDATION APPROACHES

CAPYSQUASH offers three Docker-based validation strategies:

TWO_CONTAINERS Most accurate but slower

ā˜‘ Separate Docker containers ā˜‘ Complete isolation ā˜‘ Extension conflicts avoided ā˜‘ Best for production ~2-3 min for 100 migrations

TWO_DATABASES Best balance (default)

ā˜‘ One container, two databases ā˜‘ Shared extensions ā˜‘ Faster startup ā˜‘ Good for most cases ~90-120s for 100 migrations

  • SCHEMA_DIFF

  • Fastest for development

  • ā˜‘ Single database

  • ā˜‘ Schema dump comparison

  • ā˜‘ Quick iteration

  • ā˜‘ Development workflows

  • ~30-45s for 100 migrations

HOW IT WORKS

Step-by-Step Process

1

  • START DOCKER CONTAINERS

  • Spin up PostgreSQL containers (or single container with multiple databases)

Docker run -d postgres:17.

Wait for ready state

2

  • DETECT & INSTALL EXTENSIONS

  • Scan migrations for required PostgreSQL extensions

  • -- Auto-detected CREATE EXTENSION IF NOT EXISTS vector; CREATE EXTENSION IF NOT EXISTS pg_stat_statements; CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

3

  • APPLY ORIGINAL MIGRATIONS

  • Run all original migration files in order

  • psql < 001_init.sql Psql < 002_users.sql. Psql < 003_posts.sql.

... continue for all files

4

  • CAPTURE ORIGINAL SCHEMA

  • Use pg_dump to capture complete schema state

  • pg_dump --schema-only \ --no-owner \ --no-privileges \

  • original_db > original_schema.sql

5

  • APPLY SQUASHED MIGRATIONS

  • Run consolidated migration files in fresh database

  • psql < 001_schema_foundation.sql Psql < 002_constraints_relationships.sql. Psql < 003_indexes_performance.sql.

... continue for squashed files

6

  • CAPTURE SQUASHED SCHEMA

  • Use pg_dump again on squashed database

  • pg_dump --schema-only \ --no-owner \ --no-privileges \

  • squashed_db > squashed_schema.sql

7

  • COMPARE SCHEMAS

  • Byte-for-byte diff of schema dumps

  • diff original_schema.sql squashed_schema.sql

Exit code 0 = identical

Exit code 1 = differences found

  • 8

  • CLEANUP CONTAINERS

  • Stop and remove Docker containers

Docker stop container_id. Docker rm container_id

EXTENSION DETECTION

Pgsquash automatically detects and installs PostgreSQL extensions:

AUTO-DETECTED EXTENSIONS

COMMON EXTENSIONS

vector (pgvector) uuid-ossp pg_stat_statements pg_trgm postgis hstore

  • SUPABASE EXTENSIONS

  • pg_graphql

  • pg_jsonschema

  • pgjwt

  • pg_net

  • vault

  • Extensions are detected by scanning CREATE EXTENSION statements and automatically installed before running migrations.

VALIDATION OUTPUT

Success Case

  • šŸ” Running Docker validation with TWO_DATABASES approach...

  • ā˜‘ Docker containers started

  • ā˜‘ Extensions detected: vector, uuid-ossp

  • ā˜‘ Extensions installed successfully

  • ā˜‘ Original migrations applied (287 files)

  • ā˜‘ Original schema captured

  • ā˜‘ Squashed migrations applied (12 files)

  • ā˜‘ Squashed schema captured

  • ā˜‘ Schema comparison: IDENTICAL

  • ā˜‘ Validation successful: Schemas are equivalent

  • Duration: 45.2s

  • Approach: TWO_DATABASES

Failure Case

  • šŸ” Running Docker validation...

  • ā˜‘ Docker containers started

  • ā˜‘ Extensions installed

  • ā˜‘ Original migrations applied

  • ā˜‘ Original schema captured

  • ā˜‘ Squashed migrations applied

  • ā˜‘ Squashed schema captured

  • āœ— Schema comparison: DIFFERENCES FOUND

  • ā˜’ Validation failed: Schemas are different

  • Differences:

  • TABLE users:

  • MISSING COLUMN: legacy_id (type: TEXT)

  • EXTRA COLUMN: user_uuid (type: UUID)

  • INDEX idx_legacy_id:

  • MISSING in squashed schema

  • Recommendation: Review consolidation rules and retry

VALIDATION CONFIG

Configure validation in pgsquash.config.json:

{
  "validation": {
    "docker_approach": "TWO_DATABASES",
    "enable_extension_detection": true,
    "auto_install_extensions": true,
    "enable_sql_fixes": true,
    "custom_extensions": {
      "vector": "pgvector/pgvector:latest"
    }
  }
}

WHEN VALIDATION RUNS

VALIDATION TRIGGERS

Manual validation command: pgsquash validate original/ squashed/

  • SAFE workflow: Automatically runs with TWO_CONTAINERS

  • FAST workflow: Automatically runs with SCHEMA_DIFF

  • CI/CD pipelines: Can be integrated into automated workflows

DOCKER REQUIREMENTS

āš ļø REQUIREMENTS

ā˜‘ Docker Desktop (macOS/Windows) or Docker Engine (Linux) must be installed ā˜‘ Docker daemon must be running ā˜‘ Network access to pull PostgreSQL images ā˜‘ Sufficient disk space for Docker images (~500MB) ā˜‘ Available ports for PostgreSQL (default: 5432)

  • CHECK DOCKER STATUS:

Docker ps.

Should show running containers or empty list

PERFORMANCE TIPS

šŸš€ SPEED UP VALIDATION

Use SCHEMA_DIFF for dev Keep Docker images cached Use local Docker volumes Limit migration file count

  • šŸŽÆ IMPROVE ACCURACY

  • Use TWO_CONTAINERS for prod

  • Enable extension detection

  • Match PostgreSQL version

  • Include all extensions

TROUBLESHOOTING

ERROR: Cannot connect to Docker

Solution: Start Docker Desktop or Docker daemon

ERROR: Extension not found Solution: Add extension to custom_extensions config

  • ERROR: Schema differences found

  • Solution: Review consolidation rules, adjust safety level, or fix migrations


# macOS - Start Docker

open -a Docker

# Linux - Start Docker daemon

sudo systemctl start docker

# Check Docker status

docker ps
// Add custom extensions
"custom_extensions": {
  "my_extension": "postgres:17"
}

NEXT STEPS

How is this guide?

On this page