# Development Environment ## Container Setup Located in `devel/`. Uses Podman (Docker-compatible). ### Containerfile Base image: `php:8.4.14-apache` with Xdebug for profiling. ``` FROM php:8.4.14-apache # Xdebug installed with profile mode # Trigger profiling: ?XDEBUG_PROFILE=1 # Output: /tmp/cachegrind.out.* ``` ### compose.yaml **Default service** (demo mode): ```yaml default: build: ./ container_name: folderweb-default volumes: - ../app:/var/www/app:z - ./apache/custom.conf:/etc/apache2/conf-available/custom.conf:z - ./apache/default.conf:/etc/apache2/sites-available/000-default.conf:z ports: - "8080:80" ``` Mounts `app/` only — uses `app/default/content/` as demo content. **Custom service** (commented out, template for production-like setup): ```yaml custom: volumes: - ../app:/var/www/app:z - ../content:/var/www/html:z # Content as document root - ../custom:/var/www/custom:z # Custom overrides - ../docs:/var/www/html/docs:z # Docs served as content ports: - "4040:80" ``` ### Starting ```bash cd devel podman-compose build podman-compose up -d # Demo: http://localhost:8080 ``` ## Apache Configuration ### default.conf (VirtualHost) - `DocumentRoot /var/www/html` - `DirectoryIndex disabled` (no auto-index) - RewriteRule: all non-`/app/` requests → `/app/router.php` ### custom.conf (Aliases) Maps `/app/*` URLs to filesystem: ``` Alias /app/default-styles /var/www/app/default/styles Alias /app/styles /var/www/custom/styles Alias /app/fonts /var/www/custom/fonts Alias /app /var/www/app ``` More specific aliases listed first (Apache processes in order). Enables `mod_rewrite`. ### Production Deployment The Apache config in `devel/` is a reference. Production may vary but must ensure: 1. **All requests** (except `/app/*`) rewrite to `/app/router.php` 2. **`/app/` aliased** to the `app/` directory 3. **`/app/styles/`** aliased to `custom/styles/` 4. **`/app/fonts/`** aliased to `custom/fonts/` 5. **Document root** set to the content directory 6. **`custom/`** accessible to PHP at `../custom/` relative to `app/` 7. **`DirectoryIndex disabled`** — the router handles all paths Nginx equivalent: proxy all non-asset requests to `app/router.php`, alias `/app/` paths accordingly. ## Performance Testing **`devel/perf.sh`** — All-in-one profiling tool using Xdebug + Podman. ### Commands | Command | Purpose | |---|---| | `./perf.sh profile /url` | Profile a URL, show top 20 slowest functions | | `./perf.sh analyze [file]` | Analyze a cachegrind file (latest if omitted) | | `./perf.sh list` | List available cachegrind profiles | | `./perf.sh clean` | Remove all cachegrind files | | `./perf.sh generate ` | Generate test data: `small` (~100), `medium` (~500), `large` (~1500), `huge` (~5000+) | | `./perf.sh generate custom N M D` | Custom: N categories, M posts/cat, D depth levels | | `./perf.sh testdata-stats` | Show test data statistics | | `./perf.sh testdata-clean` | Remove test data | ### Environment Variables ```bash CONTAINER=folderweb-default # Target container name PORT=8080 # Target port ``` ### Profiling Workflow ```bash cd devel ./perf.sh generate medium # Create test dataset ./perf.sh profile / # Profile homepage ./perf.sh profile /blog-321/ # Profile a specific page # Export for KCachegrind podman cp folderweb-default:/tmp/cachegrind.out.123 ./profile.out kcachegrind ./profile.out ``` Focus on functions consuming >5% of total execution time. The analyzer shows time (ms), memory (KB), call count, and percentage.