# 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