# Docker Compose Patterns - Quick Guide This guide provides a focused reference for all Docker Compose patterns used in this project. ## Overview This project uses **three Docker Compose files** for different purposes: ``` docker-compose.yml ← Start application server docker-compose.test.yml ← Run unit tests docker-compose.coverage.yml ← Generate coverage reports ``` --- ## Pattern 1: Application Server **File**: `docker-compose.yml` **Purpose**: Deploy JAX-WS application to Tomcat ### Commands ```bash # Start server docker-compose up -d # Start with build docker-compose up -d --build # View logs docker-compose logs -f # Stop server docker-compose down # Restart docker-compose restart ``` ### What Happens 1. Builds Docker image (3 stages): - Stage 1: Run unit tests - Stage 2: Build WAR file - Stage 3: Deploy to Tomcat 2. Starts Tomcat on port 8080 3. Creates/persists SQLite database ### Access - Hello World: http://localhost:8080/jaxws-hello-world/hello?wsdl - Loan Service: http://localhost:8080/jaxws-hello-world/loan?wsdl - Tomcat Manager: http://localhost:8080/manager (admin/admin123) --- ## Pattern 2: Run Unit Tests **File**: `docker-compose.test.yml` **Purpose**: Execute JUnit tests ### Commands ```bash # Run tests docker-compose -f docker-compose.test.yml up --build # View test output docker-compose -f docker-compose.test.yml logs # Clean up docker-compose -f docker-compose.test.yml down # One-liner (run and clean) docker-compose -f docker-compose.test.yml up --build && docker-compose -f docker-compose.test.yml down ``` ### Convenience Scripts **Windows:** ```cmd run-tests.bat ``` **Linux/Mac:** ```bash ./run-tests.sh ``` ### What Happens 1. Builds test environment 2. Runs `mvn test` 3. Executes all *Test.java files 4. Exports results to `./target/surefire-reports/` 5. Generates JaCoCo coverage data ### Output **Console:** ``` Tests run: 10, Failures: 0, Errors: 0, Skipped: 0 BUILD SUCCESS ``` **Files:** - `./target/surefire-reports/` - Test reports (text & XML) - `./target/jacoco.exec` - Coverage data --- ## Pattern 3: Generate Code Coverage **File**: `docker-compose.coverage.yml` **Purpose**: Generate JaCoCo coverage reports ### Commands ```bash # Generate coverage docker-compose -f docker-compose.coverage.yml up --build # View logs docker-compose -f docker-compose.coverage.yml logs # Clean up docker-compose -f docker-compose.coverage.yml down # One-liner (generate and clean) docker-compose -f docker-compose.coverage.yml up --build && docker-compose -f docker-compose.coverage.yml down ``` ### Convenience Scripts **Windows:** ```cmd run-coverage.bat ``` **Linux/Mac:** ```bash ./run-coverage.sh ``` ### What Happens 1. Builds test environment 2. Runs `mvn test` with JaCoCo agent 3. Generates coverage reports (HTML, XML, CSV) 4. Exports to `./target/site/jacoco/` ### Output **Console:** ``` ================================================================================= Coverage report generated successfully! ================================================================================= HTML Report: ./target/site/jacoco/index.html XML Report: ./target/site/jacoco/jacoco.xml CSV Report: ./target/site/jacoco/jacoco.csv ================================================================================= ``` **Files:** - `./target/site/jacoco/index.html` ← **Open this in browser** - `./target/site/jacoco/jacoco.xml` (for CI/CD) - `./target/site/jacoco/jacoco.csv` (for spreadsheets) --- ## Complete Workflow ### Typical Development Cycle ```bash # 1. Write code vim src/main/java/com/example/service/MyService.java # 2. Run tests docker-compose -f docker-compose.test.yml up --build docker-compose -f docker-compose.test.yml down # 3. Check coverage docker-compose -f docker-compose.coverage.yml up --build docker-compose -f docker-compose.coverage.yml down # 4. View coverage report # Open target/site/jacoco/index.html in browser # 5. Deploy if tests pass docker-compose up -d --build # 6. Verify curl http://localhost:8080/jaxws-hello-world/hello?wsdl # 7. View logs docker-compose logs -f # 8. Stop when done docker-compose down ``` ### Using Convenience Scripts (Faster) **Windows:** ```cmd REM 1. Write code notepad src\main\java\com\example\service\MyService.java REM 2. Run tests run-tests.bat REM 3. Generate coverage run-coverage.bat REM 4. View coverage start target\site\jacoco\index.html REM 5. Deploy docker-compose up -d --build ``` **Linux/Mac:** ```bash # 1. Write code vim src/main/java/com/example/service/MyService.java # 2. Run tests ./run-tests.sh # 3. Generate coverage ./run-coverage.sh # 4. View coverage (Linux) xdg-open target/site/jacoco/index.html # 5. Deploy docker-compose up -d --build ``` --- ## Quick Reference Table | Task | Docker Compose Command | Script Alternative | |------|----------------------|-------------------| | **Run Tests** | `docker-compose -f docker-compose.test.yml up --build` | `run-tests.bat` / `./run-tests.sh` | | **Generate Coverage** | `docker-compose -f docker-compose.coverage.yml up --build` | `run-coverage.bat` / `./run-coverage.sh` | | **Start Server** | `docker-compose up -d` | N/A | | **Stop Server** | `docker-compose down` | N/A | | **View Logs** | `docker-compose logs -f` | N/A | | **Rebuild Server** | `docker-compose up -d --build` | N/A | --- ## Common Patterns ### Pattern: Test-Driven Development (TDD) ```bash # Watch-test loop (manual) while true; do docker-compose -f docker-compose.test.yml up --build docker-compose -f docker-compose.test.yml down read -p "Press Enter to run again, Ctrl+C to exit..." done ``` ### Pattern: CI/CD Pipeline ```yaml # GitHub Actions example - name: Run Tests run: docker-compose -f docker-compose.test.yml up --build - name: Generate Coverage run: docker-compose -f docker-compose.coverage.yml up --build - name: Upload Coverage uses: codecov/codecov-action@v3 with: files: ./target/site/jacoco/jacoco.xml - name: Deploy (if tests pass) run: docker-compose up -d --build ``` ### Pattern: Pre-commit Hook ```bash #!/bin/bash # .git/hooks/pre-commit echo "Running tests before commit..." docker-compose -f docker-compose.test.yml up --build if [ $? -ne 0 ]; then echo "Tests failed! Commit aborted." docker-compose -f docker-compose.test.yml down exit 1 fi docker-compose -f docker-compose.test.yml down echo "Tests passed! Proceeding with commit." ``` --- ## Troubleshooting ### Tests Failing ```bash # View detailed test output docker-compose -f docker-compose.test.yml up # Check test container logs docker-compose -f docker-compose.test.yml logs # Access test container docker-compose -f docker-compose.test.yml run --rm test bash ``` ### Coverage Report Empty ```bash # Ensure tests are running docker-compose -f docker-compose.test.yml up --build # Check if target directory is mounted docker-compose -f docker-compose.coverage.yml config | grep target # Manually verify mount ls -la target/site/jacoco/ ``` ### Server Won't Start ```bash # Check if port 8080 is in use netstat -ano | findstr :8080 # Windows lsof -i :8080 # Linux/Mac # View server logs docker-compose logs -f # Rebuild from scratch docker-compose down docker-compose build --no-cache docker-compose up -d ``` --- ## Advanced Usage ### Run Specific Test ```bash # Override command to run specific test docker-compose -f docker-compose.test.yml run --rm test \ mvn test -Dtest=HelloWorldServiceImplTest ``` ### Custom Memory Settings ```bash # Override environment variable docker-compose -f docker-compose.test.yml run --rm \ -e MAVEN_OPTS="-Xmx1024m" test mvn test ``` ### Debug Mode ```bash # Run tests with Maven debug output docker-compose -f docker-compose.test.yml run --rm test \ mvn test -X ``` --- ## Summary - **3 Docker Compose files** = 3 different purposes - **Test first** before deploying - **Check coverage** to ensure quality - **Use scripts** for convenience - **All outputs** go to `./target/` **Quick commands to remember:** ```bash run-tests.bat # or ./run-tests.sh run-coverage.bat # or ./run-coverage.sh docker-compose up -d # start server ``` That's it! You now have everything you need to use Docker Compose patterns in this project.