Docker Configuration for 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:
DB_PORT_MYSQL80,DB_PORT_MYSQL84,DB_PORT_MYSQL93- MySQL database portsDB_PORT_POSTGRES16- PostgreSQL 16 database port (default:5432)PHPMYADMIN_PORT_MYSQL80,PHPMYADMIN_PORT_MYSQL84,PHPMYADMIN_PORT_MYSQL93- PHPMyAdmin portsDB_ROOT_PASSWORD,DB_USER,DB_PASSWORD,DB_NAME- Database credentials (shared by MySQL and PostgreSQL)DATABASE_STARTUP_TIMEOUT,PHPUNIT_TEST_TIMEOUT- Timeout configurations
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:
- Map to a high port in
.env(e.g.DB_PORT_MYSQL80=13306) - Or run
sudo sysctl net.ipv4.ip_unprivileged_port_start=0once
Available Configurations
PHP Versions
- PHP 8.1
- PHP 8.2
- PHP 8.3
- PHP 8.4
- PHP 8.5
MySQL Versions
- MySQL 8.0 (port 3306)
- MySQL 8.4 (port 3307)
- MySQL 9.3 (port 3308)
- MySQL 9.6 (port 3309)
PostgreSQL Versions
- PostgreSQL 16 (port 5432)
Services
CLI Services (for running DBDiff)
cli-php81-mysql80- PHP 8.1 with MySQL 8.0cli-php81-mysql84- PHP 8.1 with MySQL 8.4cli-php81-mysql93- PHP 8.1 with MySQL 9.3cli-php81-mysql96- PHP 8.1 with MySQL 9.6cli-php82-mysql80- PHP 8.2 with MySQL 8.0cli-php82-mysql84- PHP 8.2 with MySQL 8.4cli-php82-mysql93- PHP 8.2 with MySQL 9.3cli-php82-mysql96- PHP 8.2 with MySQL 9.6cli-php83-mysql80- PHP 8.3 with MySQL 8.0cli-php83-mysql84- PHP 8.3 with MySQL 8.4cli-php83-mysql93- PHP 8.3 with MySQL 9.3cli-php84-mysql80- PHP 8.4 with MySQL 8.0cli-php84-mysql84- PHP 8.4 with MySQL 8.4cli-php84-mysql93- PHP 8.4 with MySQL 9.3cli-php83-postgres16- PHP 8.3 with PostgreSQL 16cli-php84-postgres16- PHP 8.4 with PostgreSQL 16
Database Services
db-mysql80- MySQL 8.0 (accessible on localhost:3306)db-mysql84- MySQL 8.4 (accessible on localhost:3307)db-mysql93- MySQL 9.3 (accessible on localhost:3308)db-postgres16- PostgreSQL 16 (accessible on localhost:5432)
PHPMyAdmin Services
phpmyadmin-mysql80- PHPMyAdmin for MySQL 8.0 (http://localhost:8080)phpmyadmin-mysql84- PHPMyAdmin for MySQL 8.4 (http://localhost:8081)phpmyadmin-mysql93- PHPMyAdmin for MySQL 9.3 (http://localhost:8082)
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:
- Parallel Mode (
--parallel): Spawns multiple background processes to test different MySQL major versions concurrently. This provides a ~3x speedup when runningall all. - Fast Mode (
--fast): Skips the aggressive deletion of Docker images and build caches between runs. Use this when iterating on code and the underlying environment/dependencies haven’t changed. - Record Mode (
--record): Tunnels theDBDIFF_RECORD_MODEenvironment variable into the test containers. This will cause tests to overwrite the expected fixtures intests/expected/with the actual current output. - Watch Mode (
--watch):- Single combination: Tests run once, then containers stay active for manual use.
- Multiple combinations: Each combination runs in sequence, press Ctrl+C to move to the next.
- No Teardown (
--no-teardown): Containers remain active after script completion (works with both single and watch modes).
Test Runner Modes:
- Single Run: Tests run once, then containers are cleaned up automatically
- Watch Mode (
--watch):- Single combination: Tests run once, then containers stay active for manual use
- Multiple combinations: Each combination runs sequentially, press Ctrl+C to move to next
- No Teardown (
--no-teardown): Containers remain active after script completion (works with both single and watch modes)
“All” Option Behavior:
- Single Mode: Each combination runs and cleans up sequentially (unless –no-teardown)
- Watch Mode: Each combination runs in sequence, user must Ctrl+C to move to next combination
- Watch + No Teardown: Each combination stays active permanently (no cleanup between combinations or at exit)
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):
- Root Password:
rootpass(DB_ROOT_PASSWORD) - Database:
diff1(DB_NAME) - User:
dbdiff(DB_USER) - Password:
dbdiff(DB_PASSWORD)
External Access Ports (configurable via .env)
- MySQL 8.0:
localhost:3306(DB_PORT_MYSQL80) - MySQL 8.4:
localhost:3307(DB_PORT_MYSQL84) - MySQL 9.3:
localhost:3308(DB_PORT_MYSQL93) - PostgreSQL 16:
localhost:5432(DB_PORT_POSTGRES16)
PHPMyAdmin Access (configurable via .env)
- MySQL 8.0: http://localhost:18080 (PHPMYADMIN_PORT_MYSQL80)
- MySQL 8.4: http://localhost:18081 (PHPMYADMIN_PORT_MYSQL84)
- MySQL 9.3: http://localhost:18082 (PHPMYADMIN_PORT_MYSQL93)
Continuous Integration
The project uses GitHub Actions to ensure full compatibility across all supported versions on every pull request.
Matrix Grid:
- PHP: 8.3, 8.4, 8.5
- MySQL: 8.0, 8.4, 9.3, 9.6
- PostgreSQL: 16
- SQLite: bundled (runs in every MySQL CLI container via
pdo_sqlite)
Deterministic Testing
DBDiff is now built with deterministic SQL generation. This means:
- Tables are processed in alphabetical order.
ALTERstatements within a table (columns, keys, constraints) are sorted by item name.- 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
- Fully compatible with PHP 8.4.
- Test suite modernized for PHPUnit 11.
- Clean test output with automatic suppression of third-party legacy deprecations in the
vendor/folder.