diff --git a/dockybot/README.md b/dockybot/README.md
new file mode 100644
index 00000000..9ec55408
--- /dev/null
+++ b/dockybot/README.md
@@ -0,0 +1,355 @@
+# ๐ค DockyBot
+
+
+
+
+
+
+
+
+**๐ณ Docker-powered cross-platform orchestrator**
+
+*Test your library across multiple Linux distributions with beautiful, interactive output*
+
+
+
+---
+
+## ๐ Features
+
+### ๐งช **Automated Testing**
+- ๐ณ **Multi-Platform Support**: Ubuntu, Alpine, CentOS, Debian
+- ๐ **Beautiful Progress Bars**: Real-time progress tracking with Rich UI
+- ๐จ **Colored Output**: Smart log formatting with emoji indicators
+- โก **Smart Caching**: Build once, run instantly
+
+### ๐ ๏ธ **Interactive Development** 
+- ๐ฅ๏ธ **Bash Sessions**: Drop into fully-configured containers
+- ๐ฆ **Pre-installed Dependencies**: System packages, ODBC drivers, Python libs
+- ๐ **Database Ready**: Pre-configured SQL Server connection
+- ๐พ **Persistent Images**: No rebuild needed between sessions
+
+### ๐ **Advanced Monitoring**
+- ๐ **Step-by-Step Progress**: Track installation phases
+- โฑ๏ธ **Elapsed Time Tracking**: See exactly how long each phase takes
+- ๐ฏ **Smart Status Detection**: Automatically detects build phases
+- ๐ **Detailed Summaries**: Complete test reports with metrics
+
+---
+
+## ๐ Quick Start
+
+### Prerequisites
+- ๐ณ **Docker** (with daemon running)
+- ๐ **Python 3.10+**
+- ๐ฆ **Dependencies**: `pip install docker typer rich`
+
+### Installation
+```bash
+# Navigate to mssql-python directory
+cd /path/to/mssql-python
+
+# Install dependencies (if not already installed)
+pip install docker typer rich
+
+# You're ready to go! ๐
+```
+
+---
+
+## ๐ Usage Guide
+
+### ๐งช **Running Tests**
+
+#### Test Single Platform
+```bash
+# Run tests on Ubuntu (recommended)
+python -m dockybot test ubuntu
+
+# Run with verbose output
+python -m dockybot test ubuntu -v
+
+# Test other platforms
+python -m dockybot test alpine
+python -m dockybot test centos  
+python -m dockybot test debian
+```
+
+#### Test All Platforms
+```bash
+# Run tests across all supported platforms
+python -m dockybot test-all
+
+# With verbose output
+python -m dockybot test-all -v
+```
+
+### ๐ฅ๏ธ **Interactive Development**
+
+#### Bash Into Container
+```bash
+# Open interactive bash session (Ubuntu)
+python -m dockybot bash ubuntu
+
+# With verbose setup output
+python -m dockybot bash ubuntu -v
+```
+
+**What you get in the bash session:**
+- โ
 **All system dependencies** installed
+- โ
 **Microsoft ODBC Driver 18** configured  
+- โ
 **Python virtual environment** activated
+- โ
 **All requirements.txt** packages installed
+- โ
 **C++ extensions** built and ready
+- โ
 **Database connection** pre-configured
+- โ
 **Workspace mounted** at `/workspace`
+
+#### Manual Testing Inside Container
+```bash
+# Inside the container, you can:
+python -m pytest tests/ -v          # Run all tests
+python -m pytest tests/test_003* -v # Run specific test
+python main.py                      # Run your scripts
+pip list                            # Check installed packages
+echo $DB_CONNECTION_STRING          # Check DB config
+```
+
+### ๐ผ๏ธ **Image Management**
+
+#### List Cached Images
+```bash
+# See all DockyBot cached images
+python -m dockybot images
+```
+
+#### Clean Cached Images
+```bash
+# Clean specific platform
+python -m dockybot clean ubuntu
+
+# Clean all cached images
+python -m dockybot clean
+
+# Force clean without confirmation
+python -m dockybot clean --force
+```
+
+### ๐ **Platform Information**
+```bash
+# List all supported platforms
+python -m dockybot platforms
+```
+
+---
+
+## ๐จ Output Examples
+
+### ๐งช **Test Output**
+```
+๐ Starting DockyBot Test Suite
+๐ณ Platform: Ubuntu
+โฐ Starting at: UTC time
+๐ Database: SQL Server via host.docker.internal
+
+โโโโโโโโโโโโโโโโโโโโโโโโ ๐ณ Running Ubuntu Tests โโโโโโโโโโโโโโโโโโโโโโโโ
+
+๐ Installing system dependencies    โโโโโโโโโโโโโโโโโโโโ    25%    0:01:23
+
+๐ฆ Setting up tzdata (2025b-0ubuntu0.22.04.1) ...
+โ
 Successfully installed docker-7.1.0 typer-0.19.1 rich-14.1.0
+๐งช tests/test_003_connection.py::test_connection_close PASSED     [45%]
+โ
 tests/test_007_logging.py::test_setup_logging PASSED           [89%]
+
+โโโโโโโโโโโโโโโโโโโโโโโโโ Test Summary โโโโโโโโโโโโโโโโโโโโโโโโโโ
+โญโโโโโโโโโโโโโโโโโโโ ๐ค DockyBot Results โโโโโโโโโโโโโโโโโโโโฎ
+โ Platform: Ubuntu                                          โ
+โ Status: โ
 PASSED                                         โ
+โ Duration: 2:34                                            โ
+โ Log Lines: 1247                                           โ
+โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฏ
+```
+
+### ๐ฅ๏ธ **Interactive Session**
+```
+๐ Starting DockyBot Interactive Session
+๐ณ Platform: Ubuntu
+๐ผ๏ธ  Image: dockybot/ubuntu:latest
+
+๐ฏ Container ready! Attaching to interactive session...
+๐ Type 'exit' to leave the container
+
+root@container:/workspace# python -m pytest tests/ -v
+root@container:/workspace# pip list
+root@container:/workspace# python main.py
+```
+
+---
+
+## ๐๏ธ Architecture
+
+### ๐ **File Structure**
+```
+dockybot/
+โโโ README.md              # ๐ This documentation
+โโโ __init__.py            # ๐ฆ Package initialization  
+โโโ __main__.py            # ๐ Entry point
+โโโ cli.py                 # ๐ฅ๏ธ Command-line interface
+โโโ docker_runner.py       # ๐ณ Docker abstraction layer
+โโโ platforms.py           # ๐ Platform configurations
+โโโ scripts/               # ๐ Platform-specific setup scripts
+    โโโ ubuntu.sh          # ๐  Ubuntu 22.04 setup
+    โโโ alpine.sh          # ๐ต Alpine 3.18 setup  
+    โโโ centos.sh          # ๐ด CentOS 7 setup
+    โโโ debian.sh          # ๐ฃ Debian 11 setup
+```
+
+### ๐ณ **Docker Strategy**
+
+#### **Smart Image Caching**
+- **First Run**: Builds `dockybot/ubuntu:latest` with all dependencies
+- **Subsequent Runs**: Reuses cached image for instant startup
+- **Containers**: Removed after each session (`--rm`)
+- **Images**: Persist until manually cleaned
+
+#### **Platform Configurations**
+| Platform | Base Image | Package Manager | Shell |
+|----------|------------|----------------|-------|
+| ๐  Ubuntu | `ubuntu:22.04` | `apt` | `bash` |
+| ๐ต Alpine | `alpine:3.18` | `apk` | `sh` |
+| ๐ด CentOS | `centos:7` | `yum` | `bash` |
+| ๐ฃ Debian | `debian:11` | `apt` | `bash` |
+
+---
+
+## ๐ฏ Advanced Usage
+
+### ๐ง **Custom Environment Variables**
+```bash
+# Override default database connection
+export DB_CONNECTION_STRING="your_custom_connection_string"
+python -m dockybot test ubuntu
+```
+
+### ๐ณ **Direct Docker Commands**
+```bash
+# Check DockyBot images
+docker images | grep dockybot
+
+# Run container manually
+docker run -it --rm -v $(pwd):/workspace dockybot/ubuntu:latest bash
+
+# Clean up everything
+docker system prune -a
+```
+
+### ๐ **Debugging & Logs**
+```bash
+# Enable verbose output for detailed logging
+python -m dockybot test ubuntu -v
+
+# Check Docker daemon logs
+docker system events
+
+# Container resource usage
+docker stats
+```
+
+---
+
+## ๐โโ๏ธ Performance Tips
+
+### โก **Speed Optimizations**
+- **Use cached images**: First run takes 3-5 minutes, subsequent runs are instant
+- **Keep images**: Only clean when needed (`python -m dockybot clean`)
+- **Use Ubuntu**: Fastest platform for most testing scenarios
+- **Verbose mode**: Only use `-v` when debugging
+
+### ๐พ **Storage Management**
+```bash
+# Check image sizes
+python -m dockybot images
+
+# Clean specific platforms you don't use
+python -m dockybot clean alpine centos debian
+
+# Full cleanup (forces rebuild next time)
+docker system prune -a
+```
+
+---
+
+## ๐ Troubleshooting
+
+### Common Issues
+
+#### ๐ณ **Docker Not Running**
+```bash
+# Error: Cannot connect to the Docker daemon
+# Solution: Start Docker Desktop or daemon
+systemctl start docker  # Linux
+open -a Docker          # macOS
+```
+
+#### ๐ **Permission Issues**
+```bash
+# Error: Permission denied accessing Docker
+# Solution: Add user to docker group (Linux)
+sudo usermod -aG docker $USER
+# Then logout and login again
+```
+
+#### ๐พ **Disk Space**
+```bash
+# Error: No space left on device
+# Solution: Clean Docker system
+docker system prune -a
+python -m dockybot clean --force
+```
+
+#### ๐ **Network Issues**
+```bash
+# Error: Cannot connect to SQL Server
+# Check: host.docker.internal resolves correctly
+docker run --rm alpine ping -c 1 host.docker.internal
+```
+
+### ๐ **Getting Help**
+- ๐ **Documentation**: Check this README
+- ๐ **Issues**: Report bugs in the main repository
+- ๐ฌ **Discussions**: Use GitHub Discussions for questions
+- ๐ง **Contact**: Reach out to the mssql-python team
+
+---
+
+## ๐ Roadmap
+
+### ๐ **Coming Soon**
+- ๐ **macOS Support**: ARM64 and Intel testing
+- ๐ช **Windows Containers**: Native Windows testing
+- ๐งช **Test Parallelization**: Run multiple platforms simultaneously  
+- ๐ **HTML Reports**: Beautiful test result dashboards
+- ๐ **CI Integration**: GitHub Actions workflows
+- ๐ **Python Version Matrix**: Test across Python versions
+
+### ๐ก **Ideas & Suggestions**
+We're always looking for ways to improve DockyBot! Feel free to:
+- ๐ Star the repository
+- ๐ Report issues
+- ๐ก Suggest features
+- ๐ค Contribute code
+
+---
+
+
+
+## ๐ Happy Testing with DockyBot! 
+
+**Made with โค๏ธ by the mssql-python team**
+
+*Empowering developers to test across platforms effortlessly* ๐
+
+---
+
+
+
+
\ No newline at end of file
diff --git a/dockybot/__init__.py b/dockybot/__init__.py
new file mode 100644
index 00000000..37b78937
--- /dev/null
+++ b/dockybot/__init__.py
@@ -0,0 +1,7 @@
+"""
+DockyBot - Ubuntu testing with Dagger
+
+Simplified tool to replicate PR pipeline locally on Ubuntu.
+"""
+
+__version__ = "0.1.0"
\ No newline at end of file
diff --git a/dockybot/__main__.py b/dockybot/__main__.py
new file mode 100644
index 00000000..28e55b6c
--- /dev/null
+++ b/dockybot/__main__.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python3
+"""
+DockyBot package main entry point
+
+Allows running: python -m dockybot
+"""
+
+from .cli import app
+
+if __name__ == "__main__":
+    app()
\ No newline at end of file
diff --git a/dockybot/cli.py b/dockybot/cli.py
new file mode 100644
index 00000000..0099d878
--- /dev/null
+++ b/dockybot/cli.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python3
+"""
+DockyBot CLI - Minimal Docker abstraction for multi-platform testing.
+"""
+
+import typer
+from rich.console import Console
+from rich.table import Table
+from .docker_runner import DockerRunner
+from .platforms import PLATFORMS, list_platforms
+
+app = typer.Typer(help="DockyBot - Run tests across platforms with Docker")
+console = Console()
+
+@app.command()
+def test(
+    platform: str = typer.Argument(..., help="Platform to test on"),
+    verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed output")
+):
+    """Run tests on specified platform."""
+    if platform not in PLATFORMS:
+        console.print(f"[red]Error:[/red] Unknown platform '{platform}'")
+        console.print(f"Available platforms: {', '.join(PLATFORMS.keys())}")
+        raise typer.Exit(1)
+    
+    runner = DockerRunner()
+    success = runner.run_platform_test(platform, verbose=verbose)
+    
+    if not success:
+        raise typer.Exit(1)
+
+@app.command()
+def bash(
+    platform: str = typer.Argument(..., help="Platform to bash into"),
+    verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed output")
+):
+    """Open interactive bash session in platform container with dependencies installed."""
+    if platform not in PLATFORMS:
+        console.print(f"[red]Error:[/red] Unknown platform '{platform}'")
+        console.print(f"Available platforms: {', '.join(PLATFORMS.keys())}")
+        raise typer.Exit(1)
+    
+    runner = DockerRunner()
+    success = runner.run_platform_bash(platform, verbose=verbose)
+    
+    if not success:
+        raise typer.Exit(1)
+
+@app.command()
+def images():
+    """List DockyBot cached images."""
+    runner = DockerRunner()
+    runner.list_cached_images()
+
+@app.command()  
+def clean(
+    platform: str = typer.Argument(None, help="Platform to clean (optional - cleans all if not specified)"),
+    force: bool = typer.Option(False, "--force", "-f", help="Force removal without confirmation")
+):
+    """Clean DockyBot cached images."""
+    runner = DockerRunner()
+    runner.clean_cached_images(platform, force)
+
+@app.command()
+def platforms():
+    """List available platforms."""
+    table = Table(title="Available Platforms")
+    table.add_column("Platform", style="cyan")
+    table.add_column("Name", style="green")
+    table.add_column("Description", style="white")
+    
+    for platform_id, config in list_platforms().items():
+        table.add_row(platform_id, config['name'], config['description'])
+    
+    console.print(table)
+
+@app.command()
+def test_all(
+    verbose: bool = typer.Option(False, "--verbose", "-v", help="Show detailed output")
+):
+    """Run tests on all platforms."""
+    runner = DockerRunner()
+    results = {}
+    
+    for platform in PLATFORMS.keys():
+        console.print(f"\n[cyan]Testing {platform}...[/cyan]")
+        results[platform] = runner.run_platform_test(platform, verbose=verbose)
+    
+    # Summary
+    console.print("\n[bold]Test Results Summary:[/bold]")
+    for platform, success in results.items():
+        status = "[green]โ PASSED[/green]" if success else "[red]โ FAILED[/red]"
+        console.print(f"  {platform}: {status}")
+    
+    failed_count = sum(1 for success in results.values() if not success)
+    if failed_count > 0:
+        console.print(f"\n[red]{failed_count} platform(s) failed[/red]")
+        raise typer.Exit(1)
+    else:
+        console.print("\n[green]All platforms passed![/green]")
+
+if __name__ == "__main__":
+    app()
diff --git a/dockybot/docker_runner.py b/dockybot/docker_runner.py
new file mode 100644
index 00000000..b5d974ce
--- /dev/null
+++ b/dockybot/docker_runner.py
@@ -0,0 +1,811 @@
+"""
+Minimal Docker abstraction f        # Print welcome message
+        console.print(f"\n๐ [bold green]Starting DockyBot Test Suite[/bold green]")
+        console.print(f"๐ณ [bold blue]Platform:[/bold blue] {platfo        elif "requirement        elif "building" in line_lower and ("c++" in line_lower or "extensions" in line_lower or "pybind" in line_lower):
+            return "๐จ Building C++ extensions", 5
+        elif ("running tests" in line_lower or "pytest" in line_lower or
+              "tests/test_" in line_lower or "passed" in line_lower or
+              "failed" in line_lower or "skipped" in line_lower or
+              "test session starts" in line_lower or "collected" in line_lower):
+            return "๐งช Running tests", 6t" in line_lower or "pip install" in line_lower:
+            return "๐ฆ Installing Python packages", 4
+        elif "building" in line_lower and ("c++" in line_lower or "extensions" in line_lower or "pybind" in line_lower):
+            return "๐จ Building C++ extensions", 5
+        elif any(test_indicator in line_lower for test_indicator in [
+            "running tests", "pytest", "test session starts", "collected", 
+            "tests/test_", "passed", "failed", "skipped", "::test_"
+        ]):
+            return "๐งช Running tests", 6
+        elif "completed successfully" in line_lower or "test pipeline completed" in line_lower:
+            return "โ
 Tests completed", 7title()}")
+        console.print(f"โฐ [bold yellow]Starting at:[/bold yellow] {console._environ.get('TZ', 'UTC')} time")
+        console.print(f"๐ [bold cyan]Database:[/bold cyan] SQL Server via host.docker.internal")
+        console.print()nning tests across platforms.
+"""
+
+import docker
+import tempfile
+import os
+from pathlib import Path
+from rich.console import Console
+from rich.live import Live
+from rich.panel import Panel
+from rich.text import Text
+from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn, TimeElapsedColumn
+from rich.rule import Rule
+from rich.columns import Columns
+from .platforms import get_platform_script
+import time
+
+console = Console()
+
+
+class DockerRunner:
+    """Minimal Docker abstraction for cross-platform testing."""
+    
+    def __init__(self, verbose: bool = False):
+        self.verbose = verbose
+        self.client = docker.from_env()
+        self.workspace = Path.cwd()
+
+    def run_platform(self, platform_name: str, script_content: str) -> bool:
+        """Run a platform test script in Docker."""
+        
+        # Print welcome message
+        console.print(f"\n๏ฟฝ [bold green]Starting DockyBot Test Suite[/bold green]")
+        console.print(f"๐ณ [bold blue]Platform:[/bold blue] {platform_name.title()}")
+        console.print()
+        
+        # Create temp script
+        with tempfile.NamedTemporaryFile(mode='w', suffix='.sh', delete=False) as f:
+            f.write(script_content)
+            script_path = f.name
+        
+        try:
+            os.chmod(script_path, 0o755)
+            
+            # Get platform config
+            platform_config = self._get_platform_config(platform_name)
+            
+            # Prepare environment variables
+            environment = {
+                'DB_CONNECTION_STRING': 'Driver=ODBC Driver 18 for SQL Server;Server=host.docker.internal,1433;Database=master;UID=sa;Pwd=Str0ng@Passw0rd123;Encrypt=no;TrustServerCertificate=yes;',
+                'PYTHONPATH': '/workspace',
+                'DEBIAN_FRONTEND': 'noninteractive',
+                'TZ': 'UTC'
+            }
+            
+            # Run container
+            container = self.client.containers.run(
+                platform_config['image'],
+                command=platform_config['command'] + [f"/tmp/test.sh"],
+                volumes={
+                    str(self.workspace): {"bind": "/workspace", "mode": "rw"},
+                    script_path: {"bind": "/tmp/test.sh", "mode": "ro"}
+                },
+                working_dir="/workspace",
+                environment=environment,
+                remove=True,
+                detach=True,
+                **platform_config.get('docker_options', {})
+            )
+            
+            # Stream output
+            return self._stream_container_output(container, platform_name)
+            
+        finally:
+            if os.path.exists(script_path):
+                os.unlink(script_path)
+
+    def _get_platform_config(self, platform_name: str) -> dict:
+        """Get Docker configuration for platform."""
+        configs = {
+            'ubuntu': {
+                'image': 'ubuntu:22.04',
+                'command': ['bash'],
+                'docker_options': {
+                    'extra_hosts': {"host.docker.internal": "host-gateway"}
+                }
+            },
+            'alpine': {
+                'image': 'alpine:3.18',
+                'command': ['sh'],
+                'docker_options': {
+                    'extra_hosts': {"host.docker.internal": "host-gateway"}
+                }
+            },
+            'centos': {
+                'image': 'centos:7',
+                'command': ['bash'],
+                'docker_options': {
+                    'extra_hosts': {"host.docker.internal": "host-gateway"}
+                }
+            },
+            'debian': {
+                'image': 'debian:11',
+                'command': ['bash'],
+                'docker_options': {
+                    'extra_hosts': {"host.docker.internal": "host-gateway"}
+                }
+            }
+        }
+        
+        if platform_name not in configs:
+            raise ValueError(f"Unknown platform: {platform_name}")
+            
+        return configs[platform_name]
+
+    def _stream_container_output(self, container, platform_name: str) -> bool:
+        """Stream container output with live updates and beautiful formatting."""
+        
+        output_lines = []
+        current_step = "Starting"
+        step_count = 0
+        total_steps = 8  # Updated number of major steps including DB verification
+        start_time = time.time()
+        
+        # Print header
+        console.print(Rule(f"[bold blue]๐ณ Running {platform_name.title()} Tests[/bold blue]"))
+        
+        with Progress(
+            SpinnerColumn(),
+            TextColumn("[bold blue]{task.description}", justify="left"),
+            BarColumn(),
+            TextColumn("[progress.percentage]{task.percentage:>3.0f}%", justify="center"),
+            TextColumn("[dim]{task.fields[elapsed]}", justify="right"),
+            console=console,
+            expand=True
+        ) as progress:
+            
+            task = progress.add_task(
+                f"[cyan]Initializing {platform_name}...", 
+                total=total_steps,
+                elapsed="0:00"
+            )
+            
+            try:
+                for log_line in container.logs(stream=True, follow=True):
+                    line = log_line.decode('utf-8').strip()
+                    if line:
+                        output_lines.append(line)
+                        
+                        # Update progress based on content
+                        new_step, step_progress = self._extract_step_info(line)
+                        if new_step != current_step and step_progress > 0:
+                            current_step = new_step
+                            step_count = step_progress  # Use the actual step number, not increment
+                        
+                        # Calculate elapsed time
+                        elapsed_seconds = int(time.time() - start_time)
+                        elapsed_str = f"{elapsed_seconds // 60}:{elapsed_seconds % 60:02d}"
+                        
+                        progress.update(
+                            task, 
+                            completed=step_count, 
+                            description=f"[cyan]{current_step}",
+                            elapsed=elapsed_str
+                        )
+                        
+                        # Format and display output
+                        self._display_formatted_line(line)
+                
+                # Check result
+                result = container.wait()
+                success = result['StatusCode'] == 0
+                
+                # Final elapsed time
+                elapsed_seconds = int(time.time() - start_time)
+                elapsed_str = f"{elapsed_seconds // 60}:{elapsed_seconds % 60:02d}"
+                
+                # Complete progress
+                progress.update(
+                    task, 
+                    completed=total_steps, 
+                    description="[green]โ
 Completed" if success else "[red]โ Failed",
+                    elapsed=elapsed_str
+                )
+                
+            except Exception as e:
+                elapsed_seconds = int(time.time() - start_time)
+                elapsed_str = f"{elapsed_seconds // 60}:{elapsed_seconds % 60:02d}"
+                progress.update(task, description="[red]โ Error occurred", elapsed=elapsed_str)
+                console.print(f"[red]๐ฅ Error streaming logs: {e}[/red]")
+                return False
+        
+        # Print summary (outside the progress context to avoid overlap)
+        elapsed_seconds = int(time.time() - start_time)
+        self._print_test_summary(platform_name, success, len(output_lines), elapsed_seconds)
+        
+        return success
+
+    def _create_status_panel(self, platform_name: str, status: str) -> Panel:
+        """Create status panel for live updates."""
+        content = Text()
+        content.append(f"Platform: ", style="bold")
+        content.append(f"{platform_name}\n", style="blue")
+        content.append(f"Status: ", style="bold")
+        content.append(status, style="green" if "โ
" in status else "yellow" if "..." in status else "red")
+        
+        return Panel(content, title="DockyBot", border_style="blue")
+
+    def _extract_step_info(self, line: str) -> tuple[str, int]:
+        """Extract current step and progress from log line."""
+        line_lower = line.lower()
+        
+        if ("apt-get update" in line_lower or 
+            "installing system dependencies" in line_lower or
+            ("install" in line_lower and "dependencies" in line_lower)):
+            return "๐ฆ Installing system dependencies", 1
+        elif ("microsoft odbc" in line_lower or "msodbcsql" in line_lower or
+              "packages-microsoft-prod" in line_lower):
+            return "๐ Installing Microsoft ODBC Driver", 2
+        elif "python" in line_lower and ("setup" in line_lower or "environment" in line_lower or "venv" in line_lower):
+            return "๐ Setting up Python environment", 3
+        elif "requirements.txt" in line_lower or "pip install" in line_lower:
+            return "๏ฟฝ Installing Python packages", 4
+        elif "building" in line_lower and ("c++" in line_lower or "extensions" in line_lower or "pybind" in line_lower):
+            return "๏ฟฝ Building C++ extensions", 5
+        elif "running tests" in line_lower or "pytest" in line_lower:
+            return "๐งช Running tests", 6
+        elif "completed successfully" in line_lower or "test pipeline completed" in line_lower:
+            return "โ
 Tests completed", 7
+        else:
+            return "๐ Processing", 0
+    
+    def _extract_status(self, line: str) -> str:
+        """Extract current status from log line (legacy method for compatibility)."""
+        step, _ = self._extract_step_info(line)
+        return step
+
+    def _display_formatted_line(self, line: str) -> None:
+        """Display a formatted log line with appropriate styling."""
+        line_lower = line.lower()
+        line_stripped = line.strip()
+        
+        # Skip empty lines and less important output
+        if not line_stripped or self._should_skip_line(line):
+            return
+            
+        # Test results (highest priority - check these first)
+        if " passed " in line_lower or line_lower.endswith(" passed"):
+            console.print(f"[green]โ
 {line}[/green]")
+        elif " failed " in line_lower or line_lower.endswith(" failed") or " error " in line_lower or line_lower.endswith(" failed"):
+            console.print(f"[red]โ {line}[/red]")
+        elif " skipped " in line_lower or line_lower.endswith(" skipped"):
+            console.print(f"[yellow]โ ๏ธ  {line}[/yellow]")
+        
+        # Database connection messages
+        elif any(word in line_lower for word in ['db_connection_string', 'database connection', 'connection target']):
+            console.print(f"[cyan]๐ {line}[/cyan]")
+        
+        # Installation success messages (check before error patterns)
+        elif any(phrase in line_lower for phrase in [
+            'successfully installed', 'successfully uninstalled', 'successfully',
+            'created symlink',
+            'collected packages', 'requirement already satisfied'
+        ]):
+            console.print(f"[green]โ
 {line}[/green]")
+        
+        # Package installation messages
+        elif any(phrase in line_lower for phrase in [
+            'installing collected packages', 'collecting', 'unpacking', 'preparing to unpack',
+            'setting up', 'selecting previously unselected', 'installing system dependencies',
+            'installing microsoft odbc', 'installing python packages', 'downloading', 'processing triggers'
+        ]):
+            console.print(f"[cyan]๐ฆ {line}[/cyan]")
+        
+        # Actual error conditions (very specific patterns)
+        elif any(pattern in line_lower for pattern in [
+            'fatal error', 'compilation failed', 'build failed', 'installation failed',
+            'command not found', 'no such file or directory', 'permission denied',
+            'connection refused', 'timeout error', 'cannot connect'
+        ]) and not any(success_word in line_lower for success_word in ['successfully', 'completed']):
+            console.print(f"[red]โ {line}[/red]")
+        
+        # Warning messages (but not system messages)
+        elif line_lower.startswith('warning:') or 'update-alternatives: warning' in line_lower:
+            console.print(f"[yellow]โ ๏ธ  {line}[/yellow]")
+        
+        # Test execution messages
+        elif any(phrase in line_lower for phrase in ['running tests', 'pytest']) and 'passed' not in line_lower:
+            console.print(f"[magenta]๐งช {line}[/magenta]")
+        
+        # Building/compilation messages
+        elif any(phrase in line_lower for phrase in ['building', 'compiling', 'linking']) and 'failed' not in line_lower:
+            console.print(f"[cyan]๐จ {line}[/cyan]")
+        
+        # Important system messages
+        elif self._is_important_line(line):
+            console.print(f"[blue]โน๏ธ  {line}[/blue]")
+        
+        # Verbose-only messages
+        elif self.verbose:
+            console.print(f"[dim]   {line}[/dim]")
+    
+    def _should_skip_line(self, line: str) -> bool:
+        """Check if line should be skipped entirely."""
+        line_lower = line.lower()
+        
+        # Skip very verbose package management output
+        skip_patterns = [
+            'debconf:', 'unable to initialize frontend:', 'dpkg-preconfigure:',
+            'reading package lists', 'building dependency tree',
+            'reading state information', 'the following new packages',
+            'get:', 'hit:', 'ign:', 'reading changelogs',
+            'reading database ...', '(reading database', 'files and directories currently installed',
+            'preparing to unpack', 'unpacking', 'selecting previously unselected',
+            'processing triggers for', 'invoke-rc.d:', 'created symlink',
+            'update-alternatives: using', 'no schema files found',
+            'first installation detected', 'checking nss setup',
+            'current default time zone'
+        ]
+        
+        # Skip if line matches any skip pattern
+        if any(pattern in line_lower for pattern in skip_patterns):
+            return True
+            
+        # Skip very short or empty lines
+        if len(line.strip()) < 3:
+            return True
+            
+        # Skip lines that are just progress indicators
+        if line.strip().startswith('โ') or line.strip().startswith('โ'):
+            return True
+            
+        return False
+    
+    def _is_important_line(self, line: str) -> bool:
+        """Check if line should be shown in non-verbose mode."""
+        important_keywords = [
+            "Installing", "Building", "Testing", "Running", "โ
", "โ", 
+            "ERROR", "FAILED", "SUCCESS", "Started", "Finished",
+            "===", "collected", "warnings summary"
+        ]
+        return any(keyword in line for keyword in important_keywords)
+
+    def _print_test_summary(self, platform_name: str, success: bool, log_lines: int, elapsed_seconds: int) -> None:
+        """Print a formatted test summary."""
+        console.print()
+        console.print(Rule("[bold]Test Summary[/bold]"))
+        
+        status_color = "green" if success else "red"
+        status_icon = "โ
" if success else "โ"
+        status_text = "PASSED" if success else "FAILED"
+        
+        elapsed_str = f"{elapsed_seconds // 60}:{elapsed_seconds % 60:02d}"
+        
+        summary_panel = Panel(
+            f"[bold]Platform:[/bold] {platform_name.title()}\n"
+            f"[bold]Status:[/bold] [{status_color}]{status_icon} {status_text}[/{status_color}]\n"
+            f"[bold]Duration:[/bold] {elapsed_str}\n"
+            f"[bold]Log Lines:[/bold] {log_lines}",
+            title="๐ค DockyBot Results",
+            border_style=status_color
+        )
+        
+        console.print(summary_panel)
+        console.print()
+    
+    def run_platform_test(self, platform: str, verbose: bool = False) -> bool:
+        """Run platform test using the predefined test script."""
+        self.verbose = verbose
+        
+        try:
+            # Get the test script for this platform
+            script_content = get_platform_script(platform)
+            
+            # Run the platform test
+            return self.run_platform(platform, script_content)
+            
+        except Exception as e:
+            console.print(f"[red]๐ฅ Error running {platform} test: {e}[/red]")
+            return False
+
+    def run_platform_bash(self, platform: str, verbose: bool = False) -> bool:
+        """Run interactive bash session in platform container with dependencies installed."""
+        self.verbose = verbose
+        
+        try:
+            # Check if we have a cached image, if not build it
+            image_name = f"dockybot/{platform}:latest"
+            
+            if not self._image_exists(image_name):
+                console.print(f"๐๏ธ  [bold yellow]Building cached image for {platform}...[/bold yellow]")
+                console.print("โ๏ธ  [dim]This will take a few minutes but only happens once![/dim]")
+                console.print(f"๐พ [dim]Image will be saved as: {image_name}[/dim]")
+                
+                # Build the image with all dependencies
+                success = self._build_platform_image(platform, image_name)
+                if not success:
+                    return False
+                    
+                console.print(f"โ
 [bold green]Image built and cached![/bold green]")
+                console.print(f"๐ [dim]You can see it with: docker images | grep dockybot[/dim]")
+            else:
+                console.print(f"๐ [bold green]Using cached image:[/bold green] {image_name}")
+                console.print(f"โก [dim]No rebuild needed - dependencies already installed![/dim]")
+            
+            # Run interactive session using the cached image
+            return self._run_interactive_session(platform, image_name)
+            
+        except Exception as e:
+            console.print(f"[red]๐ฅ Error running {platform} bash session: {e}[/red]")
+            return False
+
+    def _image_exists(self, image_name: str) -> bool:
+        """Check if Docker image exists locally."""
+        try:
+            self.client.images.get(image_name)
+            return True
+        except:
+            return False
+
+    def _build_platform_image(self, platform: str, image_name: str) -> bool:
+        """Build a cached Docker image with all dependencies installed."""
+        try:
+            # Get the setup script
+            script_content = get_platform_script(platform)
+            setup_script = self._create_build_script(script_content)
+            
+            # Create Dockerfile
+            dockerfile_content = self._create_dockerfile(platform, setup_script)
+            
+            # Build image
+            console.print(f"๐ฆ [cyan]Building image {image_name}...[/cyan]")
+            
+            # Create build context
+            import tempfile
+            import tarfile
+            import io
+            
+            # Create tar archive with Dockerfile and setup script
+            tar_buffer = io.BytesIO()
+            with tarfile.open(fileobj=tar_buffer, mode='w') as tar:
+                # Add Dockerfile
+                dockerfile_info = tarfile.TarInfo(name='Dockerfile')
+                dockerfile_info.size = len(dockerfile_content.encode())
+                tar.addfile(dockerfile_info, io.BytesIO(dockerfile_content.encode()))
+                
+                # Add setup script
+                script_info = tarfile.TarInfo(name='setup.sh')
+                script_info.size = len(setup_script.encode())
+                script_info.mode = 0o755
+                tar.addfile(script_info, io.BytesIO(setup_script.encode()))
+            
+            tar_buffer.seek(0)
+            
+            # Build the image
+            self.client.images.build(
+                fileobj=tar_buffer,
+                tag=image_name,
+                custom_context=True,
+                rm=True
+            )
+            
+            console.print(f"โ
 [bold green]Successfully built image:[/bold green] {image_name}")
+            return True
+            
+        except Exception as e:
+            console.print(f"[red]โ Error building image: {e}[/red]")
+            return False
+
+    def _create_dockerfile(self, platform: str, setup_script: str) -> str:
+        """Create Dockerfile for the platform."""
+        platform_config = self._get_platform_config(platform)
+        base_image = platform_config['image']
+        
+        dockerfile = f"""FROM {base_image}
+
+# Set environment variables
+ENV DEBIAN_FRONTEND=noninteractive
+ENV TZ=UTC
+ENV PYTHONPATH=/workspace
+ENV DB_CONNECTION_STRING="Driver=ODBC Driver 18 for SQL Server;Server=host.docker.internal,1433;Database=master;UID=sa;Pwd=Str0ng@Passw0rd123;Encrypt=no;TrustServerCertificate=yes;"
+
+# Copy and run setup script
+COPY setup.sh /tmp/setup.sh
+RUN chmod +x /tmp/setup.sh && /tmp/setup.sh
+
+# Set working directory
+WORKDIR /workspace
+
+# Default command
+CMD ["bash"]
+"""
+        return dockerfile
+
+    def _create_build_script(self, original_script: str) -> str:
+        """Create build script that installs dependencies but doesn't run tests."""
+        lines = original_script.split('\n')
+        build_lines = []
+        
+        for line in lines:
+            # Skip the shebang and set -euo pipefail for build
+            if line.startswith('#!') or 'set -euo pipefail' in line:
+                continue
+            # Stop before running tests
+            if any(test_indicator in line.lower() for test_indicator in 
+                   ['python -m pytest', 'pytest', 'running tests']):
+                break
+            build_lines.append(line)
+        
+        # Add final steps for image
+        build_lines.extend([
+            '',
+            'echo "๐ DockyBot image build complete!"',
+            'echo "โ
 All dependencies installed and ready to use"'
+        ])
+        
+        return '\n'.join(build_lines)
+
+    def _run_interactive_session(self, platform: str, image_name: str) -> bool:
+        """Run interactive bash session using cached image."""
+        
+        console.print(f"\n๐ [bold green]Starting DockyBot Interactive Session[/bold green]")
+        console.print(f"๐ณ [bold blue]Platform:[/bold blue] {platform.title()}")
+        console.print(f"๐ผ๏ธ  [bold cyan]Image:[/bold cyan] {image_name}")
+        console.print()
+        
+        try:
+            # Create or reuse named container
+            container_name = f"dockybot-{platform}-session"
+            
+            try:
+                # Try to remove existing container if it exists
+                existing = self.client.containers.get(container_name)
+                existing.remove(force=True)
+            except:
+                pass  # Container doesn't exist, which is fine
+            
+            console.print(f"๐ฏ [bold green]Starting container...[/bold green]")
+            console.print(f"๐ [dim]Type 'exit' to leave the container[/dim]")
+            console.print()
+            
+            # Run interactive container
+            import subprocess
+            import warnings
+            
+            # Suppress urllib3 warnings that occur during container cleanup
+            warnings.filterwarnings("ignore", category=ResourceWarning)
+            
+            try:
+                result = subprocess.run([
+                    'docker', 'run', '--rm', '-it',
+                    '--name', container_name,
+                    '-v', f'{str(self.workspace)}:/workspace',
+                    '-w', '/workspace',
+                    '--add-host', 'host.docker.internal:host-gateway',
+                    '-e', 'DB_CONNECTION_STRING=Driver=ODBC Driver 18 for SQL Server;Server=host.docker.internal,1433;Database=master;UID=sa;Pwd=Str0ng@Passw0rd123;Encrypt=no;TrustServerCertificate=yes;',
+                    image_name,
+                    'bash', '-c', 'source /opt/venv/bin/activate 2>/dev/null || true; exec bash'
+                ], cwd=str(self.workspace))
+                
+                console.print(f"\n๐ [dim]Session ended. Container cleaned up.[/dim]")
+                return result.returncode == 0
+                
+            except KeyboardInterrupt:
+                console.print(f"\nโ ๏ธ  [yellow]Session interrupted. Cleaning up...[/yellow]")
+                # Try to stop the container gracefully
+                try:
+                    running_container = self.client.containers.get(container_name)
+                    running_container.stop(timeout=5)
+                except:
+                    pass
+                return False
+            
+        except Exception as e:
+            console.print(f"[red]๐ฅ Error running interactive session: {e}[/red]")
+            return False
+
+    def _create_setup_script(self, original_script: str) -> str:
+        """Create setup script that stops before running tests and keeps container alive."""
+        lines = original_script.split('\n')
+        setup_lines = []
+        
+        for line in lines:
+            # Stop before running tests
+            if any(test_indicator in line.lower() for test_indicator in 
+                   ['python -m pytest', 'pytest', 'running tests']):
+                break
+            setup_lines.append(line)
+        
+        # Add keeping container alive instead of exec bash
+        setup_lines.extend([
+            '',
+            'echo "๐ Setup complete! Container ready for interactive session..."',
+            'echo "๐ก You can now run tests manually with: python -m pytest tests/ -v"',
+            'echo "๐ Workspace is mounted at: /workspace"',
+            'echo "๐ Python environment is activated"',
+            'echo "๐ DB_CONNECTION_STRING is configured"',
+            'echo ""',
+            'cd /workspace',
+            'source /opt/venv/bin/activate',
+            '# Keep container running',
+            'tail -f /dev/null'
+        ])
+        
+        return '\n'.join(setup_lines)
+
+    def run_platform_interactive(self, platform_name: str, script_content: str) -> bool:
+        """Run platform in interactive mode."""
+        
+        # Print welcome message
+        console.print(f"\n๐ [bold green]Starting DockyBot Interactive Session[/bold green]")
+        console.print(f"๐ณ [bold blue]Platform:[/bold blue] {platform_name.title()}")
+        console.print(f"๐ง [bold yellow]Mode:[/bold yellow] Interactive Bash")
+        console.print()
+        
+        # Create temp script
+        with tempfile.NamedTemporaryFile(mode='w', suffix='.sh', delete=False) as f:
+            f.write(script_content)
+            script_path = f.name
+        
+        try:
+            os.chmod(script_path, 0o755)
+            
+            # Get platform config
+            platform_config = self._get_platform_config(platform_name)
+            
+            # Prepare environment variables
+            environment = {
+                'DB_CONNECTION_STRING': 'Driver=ODBC Driver 18 for SQL Server;Server=host.docker.internal,1433;Database=master;UID=sa;Pwd=Str0ng@Passw0rd123;Encrypt=no;TrustServerCertificate=yes;',
+                'PYTHONPATH': '/workspace',
+                'DEBIAN_FRONTEND': 'noninteractive',
+                'TZ': 'UTC'
+            }
+            
+            # Create or reuse named container
+            container_name = f"dockybot-{platform_name}"
+            
+            console.print(f"๐๏ธ  [bold cyan]Setting up container:[/bold cyan] {container_name}")
+            console.print("โ๏ธ  [dim]Installing dependencies... This may take a few minutes on first run.[/dim]")
+            console.print()
+            
+            try:
+                # Try to remove existing container if it exists
+                existing = self.client.containers.get(container_name)
+                existing.remove(force=True)
+            except:
+                pass  # Container doesn't exist, which is fine
+            
+            # Run container interactively
+            container = self.client.containers.run(
+                platform_config['image'],
+                command=platform_config['command'] + [f"/tmp/setup.sh"],
+                name=container_name,
+                volumes={
+                    str(self.workspace): {"bind": "/workspace", "mode": "rw"},
+                    script_path: {"bind": "/tmp/setup.sh", "mode": "ro"}
+                },
+                working_dir="/workspace",
+                environment=environment,
+                detach=True,
+                **platform_config.get('docker_options', {})
+            )
+            
+            # Wait for setup to complete
+            console.print("โณ [yellow]Waiting for setup to complete...[/yellow]")
+            
+            # Stream setup logs to show progress
+            for log_line in container.logs(stream=True, follow=True):
+                line = log_line.decode('utf-8').strip()
+                if line:
+                    self._display_formatted_line(line)
+                    # Break when we see the completion message
+                    if "Setup complete! Container ready for interactive session" in line:
+                        break
+            
+            console.print(f"๐ฏ [bold green]Container ready![/bold green] Attaching to interactive session...")
+            console.print(f"๐ [dim]Type 'exit' to leave the container[/dim]")
+            console.print()
+            
+            # Attach to container for interactive session with proper environment
+            import subprocess
+            result = subprocess.run([
+                'docker', 'exec', '-it', '-e', 'DB_CONNECTION_STRING=' + environment['DB_CONNECTION_STRING'],
+                container_name, 'bash', '-c', 
+                'cd /workspace && source /opt/venv/bin/activate && exec bash'
+            ], cwd=str(self.workspace))
+            
+            # Clean up
+            try:
+                container.remove(force=True)
+            except:
+                pass
+                
+            return result.returncode == 0
+            
+        finally:
+            if os.path.exists(script_path):
+                os.unlink(script_path)
+
+    def list_platforms(self) -> list:
+        """List available platforms."""
+        return ['ubuntu', 'alpine', 'centos', 'debian']
+    
+    def list_cached_images(self) -> None:
+        """List DockyBot cached images."""
+        console.print("\n๐ผ๏ธ  [bold blue]DockyBot Cached Images[/bold blue]")
+        console.print()
+        
+        images = self.client.images.list()
+        dockybot_images = [img for img in images if any('dockybot/' in tag for tag in img.tags)]
+        
+        if not dockybot_images:
+            console.print("๐ญ [dim]No cached images found[/dim]")
+            console.print("๐ก [dim]Run 'python -m dockybot bash ' to create one[/dim]")
+            return
+            
+        from rich.table import Table
+        table = Table()
+        table.add_column("Image", style="cyan")
+        table.add_column("Size", style="green")
+        table.add_column("Created", style="yellow")
+        
+        for image in dockybot_images:
+            for tag in image.tags:
+                if 'dockybot/' in tag:
+                    size_mb = round(image.attrs['Size'] / (1024 * 1024), 1)
+                    created = image.attrs['Created'][:19].replace('T', ' ')
+                    table.add_row(tag, f"{size_mb} MB", created)
+        
+        console.print(table)
+        console.print()
+        console.print("๐ก [dim]Use 'python -m dockybot clean' to remove cached images[/dim]")
+    
+    def clean_cached_images(self, platform: str = None, force: bool = False) -> None:
+        """Clean DockyBot cached images."""
+        if platform:
+            image_name = f"dockybot/{platform}:latest"
+            if not self._image_exists(image_name):
+                console.print(f"๐ญ [yellow]No cached image found for {platform}[/yellow]")
+                return
+                
+            if not force:
+                import typer
+                confirm = typer.confirm(f"Remove cached image for {platform}?")
+                if not confirm:
+                    console.print("โ [dim]Cancelled[/dim]")
+                    return
+            
+            try:
+                self.client.images.remove(image_name, force=True)
+                console.print(f"๐๏ธ  [green]Removed cached image: {image_name}[/green]")
+            except Exception as e:
+                console.print(f"[red]Error removing image: {e}[/red]")
+        else:
+            # Clean all dockybot images
+            images = self.client.images.list()
+            dockybot_images = []
+            for img in images:
+                for tag in img.tags:
+                    if 'dockybot/' in tag:
+                        dockybot_images.append(tag)
+                        break
+            
+            if not dockybot_images:
+                console.print("๐ญ [dim]No cached images to clean[/dim]")
+                return
+            
+            if not force:
+                console.print(f"Found {len(dockybot_images)} cached images:")
+                for img in dockybot_images:
+                    console.print(f"  - {img}")
+                console.print()
+                    
+                import typer
+                confirm = typer.confirm("Remove all DockyBot cached images?")
+                if not confirm:
+                    console.print("โ [dim]Cancelled[/dim]")
+                    return
+            
+            removed_count = 0
+            for img_tag in dockybot_images:
+                try:
+                    self.client.images.remove(img_tag, force=True)
+                    console.print(f"๐๏ธ  [green]Removed: {img_tag}[/green]")
+                    removed_count += 1
+                except Exception as e:
+                    console.print(f"[red]Error removing {img_tag}: {e}[/red]")
+            
+            console.print(f"\nโ
 [green]Cleaned {removed_count} cached images[/green]")
\ No newline at end of file
diff --git a/dockybot/platforms.py b/dockybot/platforms.py
new file mode 100644
index 00000000..d9136451
--- /dev/null
+++ b/dockybot/platforms.py
@@ -0,0 +1,47 @@
+"""
+Platform definitions and test scripts for DockyBot.
+"""
+
+from pathlib import Path
+
+SCRIPT_DIR = Path(__file__).parent / "scripts"
+
+# Supported platforms
+PLATFORMS = {
+    'ubuntu': {
+        'name': 'Ubuntu 22.04',
+        'script': 'ubuntu.sh',
+        'description': 'Standard Ubuntu with apt package manager'
+    },
+    'alpine': {
+        'name': 'Alpine Linux 3.18',
+        'script': 'alpine.sh', 
+        'description': 'Lightweight Alpine with apk package manager'
+    },
+    'centos': {
+        'name': 'CentOS 7',
+        'script': 'centos.sh',
+        'description': 'Enterprise CentOS with yum package manager'
+    },
+    'debian': {
+        'name': 'Debian 11',
+        'script': 'debian.sh',
+        'description': 'Debian stable with apt package manager'
+    }
+}
+
+def get_platform_script(platform_name: str) -> str:
+    """Get the test script content for a platform."""
+    if platform_name not in PLATFORMS:
+        raise ValueError(f"Unknown platform: {platform_name}. Available: {list(PLATFORMS.keys())}")
+    
+    script_file = SCRIPT_DIR / PLATFORMS[platform_name]['script']
+    
+    if not script_file.exists():
+        raise FileNotFoundError(f"Script not found: {script_file}")
+    
+    return script_file.read_text()
+
+def list_platforms() -> dict:
+    """List all available platforms."""
+    return PLATFORMS
\ No newline at end of file
diff --git a/dockybot/scripts/alpine.sh b/dockybot/scripts/alpine.sh
new file mode 100644
index 00000000..f4346296
--- /dev/null
+++ b/dockybot/scripts/alpine.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+set -euo pipefail
+
+echo "Starting Alpine Linux test pipeline..."
+
+# Install system dependencies
+apk update
+apk add --no-cache python3 py3-pip python3-dev cmake make gcc g++ libc-dev curl wget gnupg unixodbc-dev
+
+echo "Setting up Python environment..."
+python3 -m venv /opt/venv
+source /opt/venv/bin/activate
+pip install --upgrade pip
+pip install -r requirements.txt
+
+echo "Building C++ extensions..."
+cd mssql_python/pybind
+chmod +x build.sh
+./build.sh
+
+echo "Running tests..."
+cd /workspace
+source /opt/venv/bin/activate
+python -m pytest tests/ -v
+
+echo "Alpine test pipeline completed successfully!"
\ No newline at end of file
diff --git a/dockybot/scripts/centos.sh b/dockybot/scripts/centos.sh
new file mode 100644
index 00000000..1071eb32
--- /dev/null
+++ b/dockybot/scripts/centos.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+set -euo pipefail
+
+echo "Starting CentOS 7 test pipeline..."
+
+# Install system dependencies
+yum update -y
+yum groupinstall -y "Development Tools"
+yum install -y python3 python3-pip python3-devel cmake curl wget unixodbc-devel
+
+echo "Setting up Python environment..."
+python3 -m venv /opt/venv
+source /opt/venv/bin/activate
+pip install --upgrade pip
+pip install -r requirements.txt
+
+echo "Building C++ extensions..."
+cd mssql_python/pybind
+chmod +x build.sh
+./build.sh
+
+echo "Running tests..."
+cd /workspace
+source /opt/venv/bin/activate
+python -m pytest tests/ -v
+
+echo "CentOS test pipeline completed successfully!"
\ No newline at end of file
diff --git a/dockybot/scripts/debian.sh b/dockybot/scripts/debian.sh
new file mode 100644
index 00000000..3a731acf
--- /dev/null
+++ b/dockybot/scripts/debian.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+set -euo pipefail
+
+echo "Starting Debian 11 test pipeline..."
+
+# Install system dependencies
+export DEBIAN_FRONTEND=noninteractive
+apt-get update
+apt-get install -y python3 python3-pip python3-venv python3-dev cmake build-essential curl wget gnupg unixodbc-dev
+
+echo "Setting up Python environment..."
+python3 -m venv /opt/venv
+source /opt/venv/bin/activate
+pip install --upgrade pip
+pip install -r requirements.txt
+
+echo "Building C++ extensions..."
+cd mssql_python/pybind
+chmod +x build.sh
+./build.sh
+
+echo "Running tests..."
+cd /workspace
+source /opt/venv/bin/activate
+python -m pytest tests/ -v
+
+echo "Debian test pipeline completed successfully!"
\ No newline at end of file
diff --git a/dockybot/scripts/ubuntu.sh b/dockybot/scripts/ubuntu.sh
new file mode 100644
index 00000000..730d145d
--- /dev/null
+++ b/dockybot/scripts/ubuntu.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+set -euo pipefail
+
+echo "Starting Ubuntu 22.04 test pipeline..."
+
+# Install system dependencies
+export DEBIAN_FRONTEND=noninteractive
+export TZ=UTC
+ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
+apt-get update && apt-get install -y python3 python3-pip python3-venv python3-full cmake curl wget gnupg software-properties-common build-essential python3-dev pybind11-dev
+
+echo "Installing Microsoft ODBC Driver..."
+curl -sSL -O https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb
+dpkg -i packages-microsoft-prod.deb || true
+rm packages-microsoft-prod.deb
+apt-get update
+ACCEPT_EULA=Y apt-get install -y msodbcsql18
+ACCEPT_EULA=Y apt-get install -y mssql-tools18
+apt-get install -y unixodbc-dev
+
+echo "Setting up Python environment..."
+python3 -m venv /opt/venv
+source /opt/venv/bin/activate
+pip install --upgrade pip
+pip install -r requirements.txt
+
+echo "Verifying database connection setup..."
+if [ -z "${DB_CONNECTION_STRING:-}" ]; then
+    echo "โ Warning: DB_CONNECTION_STRING environment variable is not set!"
+    exit 1
+else
+    echo "โ
 DB_CONNECTION_STRING is configured"
+    # Print first part of connection string for verification (without password)
+    echo "Connection target: $(echo "$DB_CONNECTION_STRING" | grep -o 'Server=[^;]*')"
+fi
+
+echo "Building C++ extensions..."
+cd mssql_python/pybind
+chmod +x build.sh
+./build.sh
+
+echo "Running tests..."
+cd /workspace
+source /opt/venv/bin/activate
+python -m pytest tests/ -v
+
+echo "Ubuntu test pipeline completed successfully!"
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 5abf13dc..bb6d10d0 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,4 +4,8 @@ pybind11
 coverage
 unittest-xml-reporting
 setuptools
-psutil
\ No newline at end of file
+psutil
+# DockyBot dependencies
+typer[all]>=0.9.0
+docker>=6.0.0
+rich>=13.0.0
\ No newline at end of file