# ============================================================================= # E2E Integration Testing with Database # ============================================================================= # # Full stack E2E testing for analytics device fingerprinting. # Database is seeded, migrations run, tests execute, then everything tears down. # # Usage: # docker compose -f docker-compose.e2e.yml up --build --abort-on-container-exit # docker compose -f docker-compose.e2e.yml down -v # # ============================================================================= version: "3.9" services: # =========================================================================== # DATABASE: TimescaleDB (PostgreSQL) with seed data # =========================================================================== postgres: image: timescale/timescaledb:2.16.1-pg16 environment: POSTGRES_USER: e2e_user POSTGRES_PASSWORD: e2e_password POSTGRES_DB: analytics_e2e volumes: - ./e2e/seed.sql:/docker-entrypoint-initdb.d/01-seed.sql:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U e2e_user -d analytics_e2e"] interval: 5s timeout: 3s retries: 10 networks: - e2e-network # No persistent volume - data is ephemeral for testing # =========================================================================== # REDIS: Required for BullMQ job queue # =========================================================================== redis: image: redis:7.4-alpine healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 networks: - e2e-network # =========================================================================== # ANALYTICS API: NestJS Backend with device detection # =========================================================================== api: build: context: . dockerfile: e2e/Dockerfile.api args: NPM_REGISTRY: ${NPM_REGISTRY:-http://npm.nasty.sh/} extra_hosts: - "npm.nasty.sh:10.0.0.11" - "forge.nasty.sh:10.0.0.11" extra_hosts: - "npm.nasty.sh:10.0.0.11" - "forge.nasty.sh:10.0.0.11" environment: NODE_ENV: test DATABASE_HOST: postgres DATABASE_PORT: 5432 DATABASE_USER: e2e_user DATABASE_PASSWORD: e2e_password DATABASE_NAME: analytics_e2e DATABASE_SYNCHRONIZE: "false" REDIS_HOST: redis REDIS_PORT: 6379 JWT_SECRET: e2e-test-jwt-secret-analytics PORT: 3000 # GeoIP data paths (mounted from host) GEOLITE2_DB_PATH: /app/data/GeoLite2-City.mmdb VPN_DATA_DIR: /app/data/vpn-lists volumes: # Mount GeoIP data from host - ./data:/app/data:ro expose: - "3000" depends_on: postgres: condition: service_healthy redis: condition: service_healthy healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/health"] interval: 5s timeout: 3s retries: 15 networks: - e2e-network # =========================================================================== # E2E TESTS: Playwright test runner # =========================================================================== e2e-tests: build: context: . dockerfile: e2e/Dockerfile.e2e args: NPM_REGISTRY: ${NPM_REGISTRY:-http://npm.nasty.sh/} extra_hosts: - "npm.nasty.sh:10.0.0.11" - "forge.nasty.sh:10.0.0.11" extra_hosts: - "npm.nasty.sh:10.0.0.11" - "forge.nasty.sh:10.0.0.11" environment: CI: "true" NODE_ENV: test API_URL: http://api:3000 DATABASE_URL: postgresql://e2e_user:e2e_password@postgres:5432/analytics_e2e depends_on: api: condition: service_healthy volumes: - ./e2e/test-results:/app/test-results networks: - e2e-network command: pnpm test:e2e networks: e2e-network: driver: bridge