# Docker Development Guide

**Version**: 2.0.0  
**Last Updated**: August 28, 2025  
**Audience**: Developers, QA Engineers  
**Platform**: HVAC Community Events

## Executive Summary

This guide provides comprehensive documentation for the Docker-based development and testing environment for the HVAC Community Events WordPress plugin. The environment includes a complete WordPress stack with testing tools, database management, and email testing capabilities.

## Table of Contents

1. [Environment Overview](#environment-overview)
2. [Prerequisites](#prerequisites)
3. [Initial Setup](#initial-setup)
4. [Container Management](#container-management)
5. [Database Operations](#database-operations)
6. [Test Framework Architecture](#test-framework-architecture)
7. [Running Tests](#running-tests)
8. [Debugging](#debugging)
9. [Performance Testing](#performance-testing)
10. [Troubleshooting](#troubleshooting)
11. [Best Practices](#best-practices)
12. [Advanced Configuration](#advanced-configuration)

## Environment Overview

### Architecture Diagram

```
┌─────────────────────────────────────────────────────────────┐
│                     Host Machine                             │
│                                                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              Docker Compose Network                   │   │
│  │                                                       │   │
│  │  ┌──────────────┐  ┌──────────────┐  ┌───────────┐  │   │
│  │  │  WordPress   │  │    MySQL     │  │   Redis   │  │   │
│  │  │   PHP 8.2    │◄─┤    8.0       │◄─┤   Cache   │  │   │
│  │  │  Port: 8080  │  │  Port: 3307  │  │Port: 6380 │  │   │
│  │  └──────────────┘  └──────────────┘  └───────────┘  │   │
│  │                                                       │   │
│  │  ┌──────────────┐  ┌──────────────┐  ┌───────────┐  │   │
│  │  │  PhpMyAdmin  │  │   Mailhog    │  │  Selenium │  │   │
│  │  │  Port: 8081  │  │  Port: 8025  │  │ Port: 4444│  │   │
│  │  └──────────────┘  └──────────────┘  └───────────┘  │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                              │
│  Test Files ◄──────► Plugin Source ◄──────► Test Results   │
└─────────────────────────────────────────────────────────────┘
```

### Service Details

| Service | Image | Port | Purpose |
|---------|-------|------|---------|
| WordPress | wordpress:6.4-php8.2-apache | 8080 | Main application |
| MySQL | mysql:8.0 | 3307 | Database server |
| Redis | redis:7-alpine | 6380 | Object caching |
| PhpMyAdmin | phpmyadmin:5 | 8081 | Database management |
| Mailhog | mailhog/mailhog | 8025 | Email testing |
| Selenium | selenium/standalone-chrome | 4444 | Browser automation |

## Prerequisites

### System Requirements

```yaml
Operating System:
  - Linux (Ubuntu 20.04+, Debian 11+)
  - macOS (11.0+)
  - Windows 10/11 with WSL2

Docker:
  version: "20.10+"
  compose: "2.0+"

Resources:
  RAM: "8GB minimum, 16GB recommended"
  CPU: "4 cores minimum"
  Disk: "20GB free space"
  
Development Tools:
  - Node.js 16+
  - npm or yarn
  - Git
  - Visual Studio Code (recommended)
```

### Installation

#### Linux/macOS
```bash
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

# Install Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# Verify installation
docker --version
docker compose version
```

#### Windows (WSL2)
```powershell
# Install WSL2
wsl --install

# Install Docker Desktop
# Download from https://docker.com/products/docker-desktop

# Enable WSL2 integration in Docker Desktop settings
```

## Initial Setup

### 1. Clone Repository

```bash
# Clone the repository
git clone https://github.com/your-org/upskill-event-manager.git
cd upskill-event-manager

# Checkout development branch
git checkout development
```

### 2. Environment Configuration

```bash
# Copy environment template
cp tests/.env.template tests/.env

# Edit environment variables
nano tests/.env
```

#### Environment Variables
```env
# WordPress Configuration
WORDPRESS_DB_HOST=mysql-test
WORDPRESS_DB_USER=hvac_test_user
WORDPRESS_DB_PASSWORD=hvac_test_password
WORDPRESS_DB_NAME=hvac_test_db
WORDPRESS_DEBUG=1
WORDPRESS_DEBUG_LOG=1
WORDPRESS_DEBUG_DISPLAY=0

# Test Configuration
HVAC_TEST_MODE=true
HVAC_TEST_DATA_ISOLATION=true
HVAC_TEST_EMAIL=test@example.com

# Service Ports
WORDPRESS_PORT=8080
MYSQL_PORT=3307
REDIS_PORT=6380
PHPMYADMIN_PORT=8081
MAILHOG_PORT=8025
SELENIUM_PORT=4444

# Volumes
WORDPRESS_VOLUME=wordpress_test_data
MYSQL_VOLUME=mysql_test_data
REDIS_VOLUME=redis_test_data
```

### 3. Build and Start Containers

```bash
# Navigate to tests directory
cd tests

# Build and start all services
docker compose -f docker-compose.test.yml up -d --build

# Wait for services to be healthy
docker compose -f docker-compose.test.yml ps

# Check logs
docker compose -f docker-compose.test.yml logs -f
```

### 4. Initialize WordPress

```bash
# Install WordPress
docker compose exec wordpress-test wp core install \
  --url="http://localhost:8080" \
  --title="HVAC Test Site" \
  --admin_user="admin" \
  --admin_password="admin123" \
  --admin_email="admin@test.local"

# Activate plugin
docker compose exec wordpress-test wp plugin activate hvac-community-events

# Install The Events Calendar
docker compose exec wordpress-test wp plugin install the-events-calendar --activate

# Create test pages
docker compose exec wordpress-test wp eval 'HVAC_Page_Manager::create_required_pages();'

# Flush permalinks
docker compose exec wordpress-test wp rewrite flush
```

### 5. Seed Test Data

```bash
# Create test users
./scripts/seed-test-users.sh

# Create test events
./scripts/seed-test-events.sh

# Import sample venues
docker compose exec wordpress-test wp import fixtures/venues.xml --authors=create

# Generate test certificates
docker compose exec wordpress-test wp eval 'HVAC_Test_Data::generate_certificates(50);'
```

## Container Management

### Starting and Stopping

```bash
# Start all containers
docker compose -f docker-compose.test.yml up -d

# Stop all containers (preserves data)
docker compose -f docker-compose.test.yml stop

# Stop and remove containers (preserves volumes)
docker compose -f docker-compose.test.yml down

# Stop and remove everything (including volumes)
docker compose -f docker-compose.test.yml down -v

# Restart specific service
docker compose -f docker-compose.test.yml restart wordpress-test
```

### Accessing Services

```bash
# WordPress site
open http://localhost:8080

# WordPress admin
open http://localhost:8080/wp-admin
# Username: admin
# Password: admin123

# PhpMyAdmin
open http://localhost:8081
# Username: hvac_test_user
# Password: hvac_test_password

# Mailhog (email testing)
open http://localhost:8025

# Redis Commander (if installed)
docker run -d --name redis-commander \
  --network hvac-test-network \
  -p 8082:8081 \
  rediscommander/redis-commander \
  --redis-host redis-test
```

### Executing Commands

```bash
# WordPress CLI
docker compose exec wordpress-test wp [command]

# MySQL CLI
docker compose exec mysql-test mysql -u root -p

# Redis CLI
docker compose exec redis-test redis-cli

# PHP commands
docker compose exec wordpress-test php [script.php]

# Bash shell
docker compose exec wordpress-test bash
```

## Database Operations

### Backup and Restore

```bash
# Backup database
docker compose exec mysql-test mysqldump \
  -u hvac_test_user -phvac_test_password \
  hvac_test_db > backup-$(date +%Y%m%d).sql

# Restore database
docker compose exec -T mysql-test mysql \
  -u hvac_test_user -phvac_test_password \
  hvac_test_db < backup-20250828.sql

# Export specific tables
docker compose exec mysql-test mysqldump \
  -u hvac_test_user -phvac_test_password \
  hvac_test_db wp_posts wp_postmeta > posts-backup.sql
```

### Database Management

```bash
# Connect to MySQL
docker compose exec mysql-test mysql -u root -p

# Common queries
SHOW DATABASES;
USE hvac_test_db;
SHOW TABLES;
DESCRIBE wp_users;

# Check plugin tables
SHOW TABLES LIKE 'wp_hvac%';

# Query examples
SELECT * FROM wp_users WHERE user_login LIKE 'hvac_%';
SELECT COUNT(*) FROM wp_posts WHERE post_type = 'tribe_events';
```

### Reset Database

```bash
#!/bin/bash
# reset-database.sh

# Drop and recreate database
docker compose exec mysql-test mysql -u root -p -e "
  DROP DATABASE IF EXISTS hvac_test_db;
  CREATE DATABASE hvac_test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  GRANT ALL ON hvac_test_db.* TO 'hvac_test_user'@'%';
  FLUSH PRIVILEGES;
"

# Reinstall WordPress
docker compose exec wordpress-test wp core install \
  --url="http://localhost:8080" \
  --title="HVAC Test Site" \
  --admin_user="admin" \
  --admin_password="admin123" \
  --admin_email="admin@test.local"

# Reactivate plugins and recreate pages
docker compose exec wordpress-test wp plugin activate hvac-community-events
docker compose exec wordpress-test wp eval 'HVAC_Page_Manager::create_required_pages();'
```

## Test Framework Architecture

### Page Object Model (POM)

The test framework uses the Page Object Model pattern for maintainability and reusability:

```javascript
// Structure
tests/
├── e2e/
│   ├── page-objects/
│   │   ├── BasePage.js
│   │   ├── LoginPage.js
│   │   ├── DashboardPage.js
│   │   ├── EventPage.js
│   │   └── VenuePage.js
│   ├── fixtures/
│   │   ├── users.json
│   │   ├── events.json
│   │   └── venues.json
│   ├── helpers/
│   │   ├── BrowserManager.js
│   │   ├── TestData.js
│   │   └── Utilities.js
│   └── tests/
│       ├── authentication.test.js
│       ├── event-management.test.js
│       └── venue-management.test.js
```

### Browser Manager (Singleton)

```javascript
// BrowserManager.js
const { chromium, firefox, webkit } = require('playwright');

class BrowserManager {
  constructor() {
    if (BrowserManager.instance) {
      return BrowserManager.instance;
    }
    
    this.browser = null;
    this.context = null;
    this.page = null;
    BrowserManager.instance = this;
  }

  async initialize(options = {}) {
    const browserType = options.browser || 'chromium';
    const headless = options.headless !== false;
    
    this.browser = await chromium.launch({
      headless,
      args: ['--no-sandbox', '--disable-setuid-sandbox'],
    });
    
    this.context = await this.browser.newContext({
      viewport: { width: 1920, height: 1080 },
      ignoreHTTPSErrors: true,
      ...options.context,
    });
    
    this.page = await this.context.newPage();
    
    // Set up error handling
    this.page.on('pageerror', error => {
      console.error('Page error:', error.message);
    });
    
    return this.page;
  }

  async cleanup() {
    if (this.page) await this.page.close();
    if (this.context) await this.context.close();
    if (this.browser) await this.browser.close();
  }
}

module.exports = new BrowserManager();
```

### Test Configuration

```javascript
// test.config.js
module.exports = {
  baseURL: process.env.BASE_URL || 'http://localhost:8080',
  timeout: 30000,
  retries: 2,
  workers: 4,
  
  use: {
    headless: process.env.HEADLESS === 'true',
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
    trace: 'on-first-retry',
  },
  
  projects: [
    {
      name: 'Chrome',
      use: { browserName: 'chromium' },
    },
    {
      name: 'Firefox',
      use: { browserName: 'firefox' },
    },
    {
      name: 'Safari',
      use: { browserName: 'webkit' },
    },
  ],
  
  reporter: [
    ['html', { outputFolder: 'test-results/html' }],
    ['json', { outputFile: 'test-results/results.json' }],
    ['junit', { outputFile: 'test-results/junit.xml' }],
  ],
};
```

## Running Tests

### E2E Test Execution

```bash
# Run all tests (headless)
HEADLESS=true BASE_URL=http://localhost:8080 npm test

# Run specific test file
HEADLESS=true npm test -- test-master-trainer-e2e.js

# Run with visible browser
HEADLESS=false npm test

# Run specific test suite
npm test -- --grep "Event Management"

# Run in parallel
npm test -- --workers=4

# Generate HTML report
npm test -- --reporter=html
open test-results/index.html
```

### Test Categories

```bash
# Authentication tests
node tests/e2e/auth.test.js

# Event management tests
node tests/e2e/events.test.js

# Venue management tests
node tests/e2e/venues.test.js

# Certificate generation tests
node tests/e2e/certificates.test.js

# Master trainer features
node tests/e2e/master-trainer.test.js

# Performance tests
node tests/performance/load-test.js
```

### Cross-Browser Testing

```bash
# Chrome
BROWSER=chromium npm test

# Firefox
BROWSER=firefox npm test

# Safari (WebKit)
BROWSER=webkit npm test

# All browsers sequentially
npm run test:cross-browser

# All browsers in parallel
npm run test:cross-browser:parallel
```

### Visual Regression Testing

```bash
# Capture baseline screenshots
npm run test:visual:baseline

# Run visual comparison tests
npm run test:visual:compare

# Update baseline images
npm run test:visual:update

# View diff report
open test-results/visual-diff/index.html
```

## Debugging

### Debug Mode

```javascript
// Enable debug mode in tests
const DEBUG = process.env.DEBUG === 'true';

if (DEBUG) {
  // Slow down actions
  page.setDefaultTimeout(60000);
  
  // Pause on failures
  page.on('pageerror', async () => {
    await page.pause();
  });
  
  // Take screenshots at each step
  afterEach(async () => {
    await page.screenshot({ 
      path: `debug/step-${Date.now()}.png` 
    });
  });
}
```

### Interactive Debugging

```bash
# Launch browser with DevTools
PWDEBUG=1 node test-file.js

# Use Playwright Inspector
npx playwright test --debug

# Pause at specific point
await page.pause(); // Add in test code
```

### Container Debugging

```bash
# View container logs
docker compose logs -f wordpress-test

# Access container shell
docker compose exec wordpress-test bash

# Check PHP errors
docker compose exec wordpress-test tail -f /var/log/apache2/error.log

# Monitor MySQL queries
docker compose exec mysql-test tail -f /var/log/mysql/query.log

# Debug WordPress
docker compose exec wordpress-test wp shell
```

### Network Debugging

```bash
# Monitor network traffic
docker compose exec wordpress-test tcpdump -i any -w traffic.pcap

# Check container connectivity
docker compose exec wordpress-test ping mysql-test

# Inspect Docker network
docker network inspect hvac-test-network

# Port forwarding issues
netstat -tuln | grep 8080
```

## Performance Testing

### Load Testing Setup

```javascript
// load-test.js
const { chromium } = require('playwright');
const { performance } = require('perf_hooks');

async function loadTest(config) {
  const { concurrent = 10, iterations = 100 } = config;
  const results = [];
  
  const runTest = async () => {
    const start = performance.now();
    const browser = await chromium.launch({ headless: true });
    const page = await browser.newPage();
    
    await page.goto('http://localhost:8080/trainer/dashboard/');
    await page.waitForSelector('.hvac-dashboard');
    
    const end = performance.now();
    await browser.close();
    
    return end - start;
  };
  
  // Run concurrent tests
  for (let i = 0; i < iterations; i += concurrent) {
    const batch = Array(concurrent).fill().map(() => runTest());
    const times = await Promise.all(batch);
    results.push(...times);
  }
  
  // Calculate statistics
  const avg = results.reduce((a, b) => a + b, 0) / results.length;
  const max = Math.max(...results);
  const min = Math.min(...results);
  
  console.log(`Average: ${avg}ms, Max: ${max}ms, Min: ${min}ms`);
}

// Run load test
loadTest({ concurrent: 20, iterations: 200 });
```

### Performance Metrics

```bash
# Monitor container resources
docker stats

# MySQL performance
docker compose exec mysql-test mysqladmin -u root -p status

# Redis performance
docker compose exec redis-test redis-cli INFO stats

# Apache performance
docker compose exec wordpress-test apache2ctl -S
```

## Troubleshooting

### Common Issues

#### Container won't start

```bash
# Check for port conflicts
lsof -i :8080
lsof -i :3307

# Kill conflicting processes
kill -9 $(lsof -t -i:8080)

# Reset Docker
docker system prune -a
docker volume prune
```

#### Database connection errors

```bash
# Verify MySQL is running
docker compose ps mysql-test

# Check MySQL logs
docker compose logs mysql-test

# Test connection
docker compose exec wordpress-test wp db check

# Reset MySQL password
docker compose exec mysql-test mysql -u root -e "
  ALTER USER 'hvac_test_user'@'%' IDENTIFIED BY 'hvac_test_password';
  FLUSH PRIVILEGES;
"
```

#### Plugin activation fails

```bash
# Check PHP errors
docker compose exec wordpress-test tail -f /var/log/apache2/error.log

# Verify plugin files
docker compose exec wordpress-test ls -la /var/www/html/wp-content/plugins/hvac-community-events/

# Debug plugin activation
docker compose exec wordpress-test wp plugin activate hvac-community-events --debug
```

#### Tests timing out

```javascript
// Increase timeout in test
test.setTimeout(60000);

// Or globally
module.exports = {
  timeout: 60000,
  // ...
};

// Debug slow operations
console.time('operation');
await slowOperation();
console.timeEnd('operation');
```

### Reset Everything

```bash
#!/bin/bash
# full-reset.sh

# Stop and remove all containers
docker compose -f docker-compose.test.yml down -v

# Remove all test data
rm -rf wordpress_test_data/
rm -rf mysql_test_data/
rm -rf redis_test_data/

# Clean Docker system
docker system prune -a --volumes

# Rebuild and start fresh
docker compose -f docker-compose.test.yml up -d --build

# Wait for healthy state
sleep 30

# Initialize WordPress
./scripts/init-wordpress.sh

# Seed test data
./scripts/seed-all-data.sh
```

## Best Practices

### Development Workflow

1. **Branch Strategy**
   ```bash
   # Create feature branch
   git checkout -b feature/new-venue-system
   
   # Make changes and test locally
   docker compose up -d
   npm test
   
   # Commit with conventional commits
   git commit -m "feat: implement new venue management system"
   ```

2. **Test-Driven Development**
   ```javascript
   // Write test first
   test('should create new venue', async () => {
     await venuePage.createVenue({
       name: 'Test Venue',
       address: '123 Test St',
     });
     
     expect(await venuePage.venueExists('Test Venue')).toBe(true);
   });
   
   // Then implement feature
   ```

3. **Data Isolation**
   ```javascript
   // Use unique test data
   const testId = Date.now();
   const venueName = `Venue_${testId}`;
   
   // Clean up after tests
   afterEach(async () => {
     await cleanup(testId);
   });
   ```

### Code Quality

1. **Linting**
   ```bash
   # JavaScript
   npm run lint
   
   # PHP
   docker compose exec wordpress-test ./vendor/bin/phpcs
   
   # Fix automatically
   npm run lint:fix
   ```

2. **Code Coverage**
   ```bash
   # Generate coverage report
   npm run test:coverage
   
   # View report
   open coverage/index.html
   ```

3. **Security Scanning**
   ```bash
   # Scan for vulnerabilities
   npm audit
   
   # PHP dependencies
   docker compose exec wordpress-test ./vendor/bin/security-checker security:check
   ```

### Performance Optimization

1. **Container Resources**
   ```yaml
   # docker-compose.yml
   services:
     wordpress-test:
       deploy:
         resources:
           limits:
             cpus: '2'
             memory: 2G
           reservations:
             cpus: '1'
             memory: 1G
   ```

2. **Caching Strategy**
   ```bash
   # Enable Redis object cache
   docker compose exec wordpress-test wp plugin install redis-cache --activate
   docker compose exec wordpress-test wp redis enable
   ```

3. **Database Optimization**
   ```sql
   -- Add indexes
   ALTER TABLE wp_posts ADD INDEX idx_type_status (post_type, post_status);
   ALTER TABLE wp_postmeta ADD INDEX idx_meta_key (meta_key);
   
   -- Optimize tables
   OPTIMIZE TABLE wp_posts;
   OPTIMIZE TABLE wp_postmeta;
   ```

## Advanced Configuration

### Custom Docker Network

```yaml
# docker-compose.override.yml
networks:
  hvac-test-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16
          gateway: 172.28.0.1
```

### SSL Configuration

```bash
# Generate self-signed certificate
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout nginx/ssl/private.key \
  -out nginx/ssl/certificate.crt

# Add nginx proxy container
services:
  nginx:
    image: nginx:alpine
    ports:
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/ssl:/etc/nginx/ssl
```

### Multi-Site Testing

```yaml
# Enable WordPress Multisite
environment:
  WORDPRESS_CONFIG_EXTRA: |
    define('WP_ALLOW_MULTISITE', true);
    define('MULTISITE', true);
    define('SUBDOMAIN_INSTALL', false);
    define('DOMAIN_CURRENT_SITE', 'localhost');
    define('PATH_CURRENT_SITE', '/');
    define('SITE_ID_CURRENT_SITE', 1);
    define('BLOG_ID_CURRENT_SITE', 1);
```

### CI/CD Integration

```yaml
# .github/workflows/test.yml
name: E2E Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Start Docker Compose
        run: |
          docker compose -f tests/docker-compose.test.yml up -d
          sleep 30
      
      - name: Initialize WordPress
        run: |
          docker compose exec -T wordpress-test wp core install \
            --url="http://localhost:8080" \
            --title="Test" \
            --admin_user="admin" \
            --admin_password="admin123" \
            --admin_email="test@test.com"
      
      - name: Run Tests
        run: |
          npm ci
          npm test
      
      - name: Upload Results
        if: always()
        uses: actions/upload-artifact@v3
        with:
          name: test-results
          path: test-results/
```

---

## Quick Reference

### Essential Commands

```bash
# Start environment
docker compose -f tests/docker-compose.test.yml up -d

# Stop environment
docker compose -f tests/docker-compose.test.yml down

# View logs
docker compose -f tests/docker-compose.test.yml logs -f

# Run tests
HEADLESS=true npm test

# Access WordPress
open http://localhost:8080

# Access database
open http://localhost:8081

# View emails
open http://localhost:8025

# Shell access
docker compose exec wordpress-test bash

# WP-CLI
docker compose exec wordpress-test wp [command]
```

### Service URLs

| Service | URL | Credentials |
|---------|-----|-------------|
| WordPress | http://localhost:8080 | admin / admin123 |
| WordPress Admin | http://localhost:8080/wp-admin | admin / admin123 |
| PhpMyAdmin | http://localhost:8081 | hvac_test_user / hvac_test_password |
| Mailhog | http://localhost:8025 | No auth required |
| Redis Commander | http://localhost:8082 | No auth required |

### File Locations

```bash
# Plugin source
./

# Test files
./tests/

# Docker config
./tests/docker-compose.test.yml

# Test results
./test-results/

# Screenshots
./screenshots/

# Fixtures
./tests/fixtures/
```

---

*This guide is maintained by the HVAC Community Events development team. For updates or issues, please submit a pull request or open an issue in the repository.*

**Document Version**: 2.0.0  
**Last Updated**: August 28, 2025  
**Next Review**: September 28, 2025