DBDiff

Docker Configuration for DBDiff

This Docker setup provides multiple PHP and MySQL version combinations for testing DBDiff across different environments.

Configuration

The Docker setup is configurable via environment variables. Copy .env.example to .env and customize:

cp .env.example .env
# Edit .env to customize ports, database credentials, timeouts, etc.

Environment Variables

Key configuration options:

Podman Support

Podman is a daemonless, rootless, Docker-compatible container engine. All docker-compose commands work identically with podman-compose. Podman is a great alternative if you do not have Docker Desktop installed or prefer not to run a background daemon.

Installing Podman

Ubuntu / Debian:

sudo apt-get install -y podman podman-compose

macOS (via Homebrew):

brew install podman podman-compose
podman machine init && podman machine start

Windows (via winget):

winget install RedHat.Podman
winget install RedHat.Podman-Desktop  # optional GUI

Podman Desktop is a cross-platform GUI available at https://podman-desktop.io/ — it provides a Docker Desktop-like interface and can run the same compose files without any changes.

Using podman-compose instead of docker-compose

Simply substitute docker-compose for podman-compose in any command in this guide:

# Start PostgreSQL and run Postgres e2e tests
podman-compose up -d db-postgres16
podman-compose run --rm \
  -e DB_HOST_POSTGRES=db-postgres16 \
  cli-php83-postgres16 \
  bash -c "scripts/run-tests.sh --postgres db-postgres16"

# Stop everything
podman-compose down

The start.sh and stop.sh scripts also support Podman automatically if docker-compose is not found:

# Prefer podman-compose when docker-compose is unavailable
COMPOSE_CMD=podman-compose ./start.sh 8.3 8.0

Rootless networking note

Podman runs containers as your own user by default. If port binding below 1024 fails, either:

Available Configurations

PHP Versions

MySQL Versions

PostgreSQL Versions

Services

CLI Services (for running DBDiff)

Database Services

PHPMyAdmin Services

Usage Examples

Start specific database and PHPMyAdmin

# Start MySQL 8.0 with PHPMyAdmin
docker-compose up -d db-mysql80 phpmyadmin-mysql80

# Start MySQL 8.4 with PHPMyAdmin
docker-compose up -d db-mysql84 phpmyadmin-mysql84

# Start MySQL 9.3 with PHPMyAdmin
docker-compose up -d db-mysql93 phpmyadmin-mysql93

Run DBDiff with specific PHP/MySQL combination

# PHP 8.3 with MySQL 8.0
docker-compose run --rm cli-php83-mysql80 server1.php server2.php database1 database2

# PHP 8.4 with MySQL 8.4
docker-compose run --rm cli-php84-mysql84 server1.php server2.php database1 database2

# PHP 8.4 with MySQL 9.3
docker-compose run --rm cli-php84-mysql93 server1.php server2.php database1 database2

Run DBDiff with PostgreSQL

# Start the PostgreSQL service
docker-compose up -d db-postgres16

# Run a Postgres diff with PHP 8.3
docker-compose run --rm cli-php83-postgres16 \
  bash -c "./dbdiff --driver=pgsql \
  --server1=dbdiff:dbdiff@db-postgres16:5432 \
  server1.mydb_staging:server1.mydb_production"

Run PHPUnit tests with specific combination

# Run tests with PHP 8.3 and MySQL 8.0
docker-compose run --rm cli-php83-mysql80 phpunit

# Run tests with PHP 8.4 and MySQL 8.4
docker-compose run --rm cli-php84-mysql84 phpunit

# Run PostgreSQL end-to-end tests (record baseline on first run)
docker-compose run --rm \
  -e DB_HOST_POSTGRES=db-postgres16 \
  cli-php83-postgres16 \
  bash -c "DBDIFF_RECORD_MODE=true scripts/run-tests.sh --postgres db-postgres16"

# Run PostgreSQL end-to-end tests (compare against baseline)
docker-compose run --rm \
  -e DB_HOST_POSTGRES=db-postgres16 \
  cli-php83-postgres16 \
  bash -c "scripts/run-tests.sh --postgres db-postgres16"

# Run SQLite end-to-end tests (no extra service needed)
docker-compose run --rm cli-php83-mysql80 bash -c "scripts/run-tests.sh --sqlite"

Using the Start Script

The start.sh script provides an easy way to test different PHP/MySQL combinations with automatic cleanup to save disk space.

# Test specific PHP/MySQL combination
./start.sh 8.3 8.0

# Test all combinations (sequentially)
./start.sh all all

# HIGH PERFORMANCE: Test all combinations in parallel
./start.sh all all --parallel

# RECORD MODE: Update expected test fixtures for all versions
./start.sh all all --record

# FAST RESTART: Skip heavy Docker cleanup for faster iterations
./start.sh 8.3 8.0 --fast

# Watch mode - single combination
./start.sh 8.3 8.0 --watch

# Interactive mode - select from menus
./start.sh

Advanced Flags:

Test Runner Modes:

“All” Option Behavior:

Note: The start script automatically cleans up Docker containers, images, volumes, and build cache after each test to save disk space (unless –no-teardown is used).

Stop Script: Use ./stop.sh to manually clean up all containers and resources, especially useful after using --no-teardown:

# Normal cleanup
./stop.sh

# Aggressive cleanup (removes everything)
./stop.sh --aggressive

# Show help
./stop.sh --help

Start all services

# Start all databases and PHPMyAdmin instances
docker-compose up -d

# Or start specific combination
docker-compose up -d db-mysql80 phpmyadmin-mysql80 cli-php83-mysql80

Cleanup

# Stop all services
docker-compose down

# Remove all containers and images
docker-compose down --rmi all --volumes --remove-orphans

Database Connection Details

Default MySQL credentials (configurable via .env):

External Access Ports (configurable via .env)

PHPMyAdmin Access (configurable via .env)

Continuous Integration

The project uses GitHub Actions to ensure full compatibility across all supported versions on every pull request.

Matrix Grid:

Deterministic Testing

DBDiff is now built with deterministic SQL generation. This means:

  1. Tables are processed in alphabetical order.
  2. ALTER statements within a table (columns, keys, constraints) are sorted by item name.
  3. Data operations (INSERT, UPDATE, DELETE) are sorted by primary key.

This ensures that test fixtures are stable across platforms and different database versions.

Support for Modern PHP & PHPUnit