Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:43:27 +08:00
commit e082963336
43 changed files with 6129 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
{
"name": "typo3-ddev",
"description": "Set up and manage TYPO3 development environments using DDEV. Includes DDEV configuration, local development workflows, container management, database handling, and integration with TYPO3-specific tooling.",
"version": "1.6.0-20251121",
"author": {
"name": "Netresearch DTT GmbH",
"email": "info@netresearch.de"
},
"skills": [
"./"
]
}

19
.gitignore vendored Normal file
View File

@@ -0,0 +1,19 @@
# macOS
.DS_Store
.AppleDouble
.LSOverride
# Thumbnails
._*
# IDE
.idea/
.vscode/
*.swp
*.swo
*~
# Temporary files
*.tmp
*.bak
skill-completion.txt

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Netresearch DTT GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# typo3-ddev
Set up and manage TYPO3 development environments using DDEV. Includes DDEV configuration, local development workflows, container management, database handling, and integration with TYPO3-specific tooling.

903
SKILL.md Normal file
View File

@@ -0,0 +1,903 @@
---
name: typo3-ddev
description: "Automate DDEV environment setup for TYPO3 extension development. Use when setting up local development environment, configuring DDEV for TYPO3 extensions, or creating multi-version TYPO3 testing environments. Covers: DDEV configuration generation, TYPO3 11.5/12.4/13.4 LTS installation, custom DDEV commands, Apache vhost setup, Docker volume management, and .gitignore best practices (avoid double-ignore anti-pattern). Provides complete automation from metadata detection to ready-to-use TYPO3 backend access."
license: MIT License - see LICENSE file
metadata:
author: Netresearch
repository: https://github.com/netresearch/typo3-ddev-skill
version: 1.6.0
tags:
- typo3
- ddev
- docker
- development
- testing
- devops
platforms:
- linux
- macos
- windows
typo3-versions:
- 11.5-lts
- 12.4-lts
- 13.4-lts
---
# TYPO3 DDEV Setup Skill
This skill automates DDEV environment setup for TYPO3 extension development projects. It creates a complete TYPO3 development environment for testing and developing extensions across multiple TYPO3 versions.
## Purpose
This skill automates the setup of DDEV for TYPO3 extension development projects. It creates a multi-version TYPO3 testing environment where the extension can be developed and tested across TYPO3 11.5 LTS, 12.4 LTS, and 13.4 LTS simultaneously.
## When to Use This Skill
Use this skill when:
- Developer has a TYPO3 extension project and wants to set up DDEV
- Project contains `ext_emconf.php` or is identified as a TYPO3 extension in `composer.json`
- Developer needs to test extension across multiple TYPO3 versions
- Quick development environment spin-up is needed
## Prerequisites Validation
Before executing ANY DDEV commands, perform comprehensive prerequisite validation:
1. **Run validation script**: Execute `scripts/validate-prerequisites.sh` to check:
- Docker daemon status (must be running)
- Docker CLI version (requires >= 20.10)
- Docker Compose version (requires >= 2.0)
- DDEV installation (must be present)
- TYPO3 extension project structure (must be valid)
2. **If validation fails**: Consult `references/prerequisites-validation.md` for platform-specific installation instructions (Linux/WSL2, macOS, Windows), version requirements, manual validation steps, and troubleshooting
3. **Report results**: Display validation status to user with specific instructions for any missing prerequisites
Always validate on the FIRST DDEV command in a session to catch environment issues early.
## Step-by-Step Workflow
### Step 1: Extract Extension Metadata
Scan the project to extract:
1. **Extension Key** (e.g., `my_ext`):
- From `ext_emconf.php`: Look for the array key or filename pattern
- From `composer.json`: Look for `extra.typo3/cms.extension-key`
- Fallback: Ask user to provide
2. **Composer Package Name** (e.g., `vendor/my-ext`):
- From `composer.json`: Look for `name` field
- Fallback: Construct from extension key or ask user
3. **Vendor Namespace** (e.g., `Vendor\MyExt`):
- From `composer.json`: Look for `autoload.psr-4` keys
- Fallback: Ask user to provide
4. **Extension Name** (PascalCase, e.g., `MyExt`):
- Convert extension key to PascalCase
- Or extract from namespace
### Step 2: Confirm Configuration
Present extracted values to user and confirm:
```
Detected TYPO3 Extension Configuration:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Extension Key: my_ext
Package Name: vendor/my-ext
DDEV Sitename: my-ext
Vendor Namespace: Vendor\MyExt
TYPO3 Versions: 11.5, 12.4, 13.4
PHP Version: 8.2
Is this correct? (y/n)
```
Allow user to adjust any values if needed.
### Step 3: Generate DDEV Configuration
Create the following directory structure and files:
```
.ddev/
├── config.yaml
├── docker-compose.web.yaml
├── apache/
│ └── apache-site.conf
├── web-build/
│ └── Dockerfile
└── commands/
└── web/
├── install-v11
├── install-v12
├── install-v13
└── install-all
.envrc
```
#### 3.1: .ddev/config.yaml
Replace these variables:
- `{{DDEV_SITENAME}}` → DDEV sitename (e.g., `my-ext`)
```yaml
name: {{DDEV_SITENAME}}
type: php
docroot: ""
no_project_mount: true
php_version: "8.2"
composer_version: "2"
webserver_type: apache-fpm
router_http_port: "80"
router_https_port: "443"
xdebug_enabled: false
additional_hostnames:
- docs.{{DDEV_SITENAME}}
- v11.{{DDEV_SITENAME}}
- v12.{{DDEV_SITENAME}}
- v13.{{DDEV_SITENAME}}
additional_fqdns: []
use_dns_when_possible: true
```
#### 3.2: .ddev/docker-compose.web.yaml
Replace these variables:
- `{{EXTENSION_KEY}}` → Extension key with underscores (e.g., `my_ext`)
- `{{PACKAGE_NAME}}` → Composer package name (e.g., `vendor/my-ext`)
- `{{DDEV_SITENAME}}` → DDEV sitename for volumes
```yaml
services:
web:
environment:
- EXTENSION_KEY={{EXTENSION_KEY}}
- PACKAGE_NAME={{PACKAGE_NAME}}
# TYPO3 v11 and v12 config
- TYPO3_INSTALL_DB_DRIVER=mysqli
- TYPO3_INSTALL_DB_USER=root
- TYPO3_INSTALL_DB_PASSWORD=root
- TYPO3_INSTALL_DB_HOST=db
- TYPO3_INSTALL_DB_UNIX_SOCKET=
- TYPO3_INSTALL_DB_USE_EXISTING=0
- TYPO3_INSTALL_ADMIN_USER=admin
- TYPO3_INSTALL_ADMIN_PASSWORD=Password:joh316
- TYPO3_INSTALL_SITE_NAME=EXT:{{EXTENSION_KEY}} Dev Environment
- TYPO3_INSTALL_SITE_SETUP_TYPE=site
- TYPO3_INSTALL_WEB_SERVER_CONFIG=apache
# TYPO3 v13 config
- TYPO3_DB_DRIVER=mysqli
- TYPO3_DB_USERNAME=root
- TYPO3_DB_PASSWORD=root
- TYPO3_DB_HOST=db
- TYPO3_SETUP_ADMIN_EMAIL=admin@example.com
- TYPO3_SETUP_ADMIN_USERNAME=admin
- TYPO3_SETUP_ADMIN_PASSWORD=Password:joh316
- TYPO3_PROJECT_NAME=EXT:{{EXTENSION_KEY}} Dev Environment
- TYPO3_SERVER_TYPE=apache
volumes:
- type: bind
source: ../
target: /var/www/{{EXTENSION_KEY}}
consistency: cached
- v11-data:/var/www/html/v11
- v12-data:/var/www/html/v12
- v13-data:/var/www/html/v13
volumes:
v11-data:
name: "${DDEV_SITENAME}-v11-data"
v12-data:
name: "${DDEV_SITENAME}-v12-data"
v13-data:
name: "${DDEV_SITENAME}-v13-data"
```
#### 3.3-3.7: Additional Configuration Files
Generate the following files using the templates from this skill repository:
- `.ddev/apache/apache-site.conf` (replace `{{EXTENSION_KEY}}` and `{{DDEV_SITENAME}}`)
- `.ddev/web-build/Dockerfile` (replace `{{EXTENSION_KEY}}` and `{{DDEV_SITENAME}}`)
- `.ddev/commands/web/install-v11` (make executable)
- `.ddev/commands/web/install-v12` (make executable)
- `.ddev/commands/web/install-v13` (make executable)
- `.ddev/commands/web/install-all` (make executable)
- `.ddev/commands/host/docs` (make executable) - for rendering documentation
#### 3.8: .envrc (direnv Configuration)
Generate `.envrc` in the project root for direnv integration:
Replace these variables:
- `{{EXTENSION_KEY}}` → Extension key with underscores (e.g., `my_ext`)
- `{{DDEV_SITENAME}}` → DDEV sitename (e.g., `my-ext`)
```bash
# direnv configuration for {{EXTENSION_KEY}}
# Auto-generated by typo3-ddev-skill
# Add composer bin directory to PATH
PATH_add vendor/bin
# Composer configuration
export COMPOSER_PROCESS_TIMEOUT=600
# DDEV environment variables
export DDEV_PROJECT={{DDEV_SITENAME}}
export DDEV_PRIMARY_URL=https://{{DDEV_SITENAME}}.ddev.site
export DDEV_DOCROOT_URL=https://docs.{{DDEV_SITENAME}}.ddev.site
# Load local environment overrides if present
dotenv_if_exists .env.local
# Display activation message
echo "✅ {{EXTENSION_KEY}} development environment activated"
echo ""
echo "🌐 DDEV Environment:"
echo " Primary: https://{{DDEV_SITENAME}}.ddev.site"
echo " Docs: https://docs.{{DDEV_SITENAME}}.ddev.site"
echo " TYPO3 v11: https://v11.{{DDEV_SITENAME}}.ddev.site"
echo " TYPO3 v12: https://v12.{{DDEV_SITENAME}}.ddev.site"
echo " TYPO3 v13: https://v13.{{DDEV_SITENAME}}.ddev.site"
echo ""
echo "🚀 DDEV Commands:"
echo " ddev start Start DDEV environment"
echo " ddev stop Stop DDEV environment"
echo " ddev restart Restart DDEV environment"
echo " ddev install-v11 Install TYPO3 11.5 LTS"
echo " ddev install-v12 Install TYPO3 12.4 LTS"
echo " ddev install-v13 Install TYPO3 13.4 LTS"
echo " ddev install-all Install all TYPO3 versions"
```
**What it does:**
- Adds `vendor/bin` to PATH for Composer tools
- Exports DDEV environment variables for easy access
- Displays helpful information when entering the project directory
- Lists available DDEV URLs and commands
**User action required:** Run `direnv allow` to activate the configuration.
**Optional:** If direnv is not installed, the file can be safely ignored.
### Step 4: Initialize DDEV
After generating all files, guide the user through starting DDEV:
```bash
# Start DDEV containers
ddev start
```
Wait for DDEV to start successfully.
### Step 5: Install TYPO3 Environments
Provide options to user:
**Option A: Install All Versions** (Recommended for compatibility testing)
```bash
ddev install-all
```
**Option B: Install Specific Version** (Faster for targeted development)
```bash
ddev install-v11 # TYPO3 11.5 LTS
ddev install-v12 # TYPO3 12.4 LTS
ddev install-v13 # TYPO3 13.4 LTS
```
Installation time: ~2-5 minutes per version (depending on network speed)
**What gets installed automatically:**
- ✅ TYPO3 Core (specified version)
- ✅ Your extension (activated and ready to use)
- ✅ TYPO3 Backend Styleguide (for UI pattern reference)
- ✅ Extension Manager
- ✅ Introduction Package (86+ pages with demo content for testing)
### Step 6: Provide Access Information
After successful installation, display:
```
✅ DDEV Environment Ready!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📋 Overview Dashboard:
https://{{DDEV_SITENAME}}.ddev.site/
🌐 TYPO3 Installations:
TYPO3 11.5 LTS
Frontend: https://v11.{{DDEV_SITENAME}}.ddev.site/
Backend: https://v11.{{DDEV_SITENAME}}.ddev.site/typo3/
TYPO3 12.4 LTS
Frontend: https://v12.{{DDEV_SITENAME}}.ddev.site/
Backend: https://v12.{{DDEV_SITENAME}}.ddev.site/typo3/
TYPO3 13.4 LTS
Frontend: https://v13.{{DDEV_SITENAME}}.ddev.site/
Backend: https://v13.{{DDEV_SITENAME}}.ddev.site/typo3/
🔑 Backend Credentials:
Username: admin
Password: Password:joh316
📦 Your Extension:
Installed in all TYPO3 versions
Source: /var/www/{{EXTENSION_KEY}}/ (bind-mounted from project root)
⚙️ Useful Commands:
ddev restart # Restart containers
ddev ssh # SSH into web container
ddev logs # View container logs
ddev describe # Show project details
ddev stop # Stop containers
ddev delete # Remove containers (keeps volumes)
```
### Step 7: Generate Makefile (Optional but Recommended)
After DDEV setup, generate a standardized Makefile following Netresearch's pattern for convenient command access:
```bash
ddev generate-makefile
```
#### Makefile Features
The generated Makefile provides a unified interface with 30+ targets:
**DDEV Management:**
```bash
make up # Complete startup (start DDEV + install all TYPO3 versions)
make start # Start DDEV environment
make stop # Stop DDEV environment
make install-v11 # Install TYPO3 11.5 LTS
make install-v12 # Install TYPO3 12.4 LTS
make install-v13 # Install TYPO3 13.4 LTS
make install-all # Install all TYPO3 versions
make urls # Show all access URLs
```
**Testing & Quality:**
```bash
make test # Run all tests (unit + functional)
make test-unit # Run unit tests only
make test-functional # Run functional tests
make lint # Run all linters (PHP syntax + PHPStan + code style)
make format # Auto-fix code style issues
make typecheck # Run PHPStan static analysis
make ci # Complete CI pipeline (pre-commit checks)
```
**Developer Convenience:**
```bash
make help # Show all available commands (default target)
make ssh # SSH into DDEV web container
make clean # Clean temporary files and caches
```
**Extension-Specific Commands:**
The Makefile includes a customizable section for extension-specific commands. Developers can add their own targets following the pattern:
```makefile
.PHONY: my-command
my-command: ## Description of my command
ddev ssh -d v12 "vendor/bin/typo3 extension:command"
```
#### Why Use the Makefile?
1. **Consistency** - Follows Netresearch's established pattern across TYPO3 extensions
2. **Single Command Setup** - `make up` does everything (DDEV start + install all versions)
3. **Discoverability** - `make help` shows all available commands with descriptions
4. **CI Integration** - Standardized `make ci`, `make test`, `make lint` for pipelines
5. **Developer Experience** - Familiar interface, shorter commands than `ddev` equivalents
6. **Documentation** - Self-documenting with auto-generated help
#### Example Workflow
```bash
# Initial setup
make up # Start DDEV + install all TYPO3 versions
# Development
make lint # Check code quality
make test # Run tests
make format # Fix code style
# Check URLs
make urls # Show all access URLs
# Complete CI check before commit
make ci # Run full quality pipeline
```
#### Customization
After generation, edit the Makefile to add project-specific commands while keeping core targets (up, start, test, lint, ci) unchanged for consistency across projects.
The Makefile is optional but highly recommended for improved developer experience.
### Step 8: Generate Project Index Page (Optional but Recommended)
After DDEV setup, generate a beautiful overview page for easy access to all TYPO3 versions and development tools:
```bash
ddev generate-index
```
#### Index Page Features
The generated `index.html` provides a centralized dashboard with:
**Visual Overview:**
- Modern, responsive design with gradient background
- Card-based layout for each TYPO3 version
- Clear visual hierarchy and hover effects
- Mobile-friendly responsive grid
**Quick Access Links:**
```
TYPO3 v12 LTS:
- Frontend: https://v12.{project}.ddev.site/
- Backend: https://v12.{project}.ddev.site/typo3/
TYPO3 v13 LTS:
- Frontend: https://v13.{project}.ddev.site/
- Backend: https://v13.{project}.ddev.site/typo3/
```
**Development Tools:**
- Backend credentials display (admin / Password:joh316)
- Mailpit access link
- Documentation link (if available)
#### Why Use the Index Page?
1. **Single Entry Point** - Access all TYPO3 versions from one beautiful page
2. **Eliminates URL Guessing** - No need to remember subdomain patterns
3. **Professional Presentation** - Polished interface for the development environment
4. **Credential Reference** - Backend login info always visible
5. **Tool Discovery** - Links to Mailpit and other development tools
6. **Multi-Version Testing** - Easy switching between TYPO3 12 and 13
#### Example Usage
```bash
# After DDEV setup
ddev generate-index
# Access the overview page
open https://{project}.ddev.site/
# or
open http://{project}.ddev.site/
```
The index page is accessible at both the main domain (e.g., `temporal-cache.ddev.site`) and serves as the landing page for the entire development environment.
#### Customization
After generation, you can edit `index.html` to:
- Add extension-specific documentation links
- Include CI/CD status badges
- Add custom tool links (PHPMyAdmin, Redis Commander, etc.)
- Customize colors, branding, or layout
- Add project-specific information or notes
The index page is optional but highly recommended for improved developer experience, especially in multi-version testing environments.
**For advanced branding and customization details including:**
- Automatic branding detection (Netresearch/TYPO3/generic)
- Brand-specific color schemes and typography
- Design specifications
See: `references/index-page-generation.md`
## Error Handling
When encountering errors during setup or installation:
1. **Check error category**: Identify if the error relates to prerequisites, database setup, extension detection, or service configuration
2. **Consult troubleshooting guide**: Read `references/troubleshooting.md` and locate the relevant error category
3. **Apply recommended solution**: Follow the step-by-step resolution guide for the specific error
4. **For Windows/WSL2 environments**: If error persists on Windows, consult `references/windows-fixes.md` for platform-specific solutions (CRLF issues, health check failures, Apache config problems)
5. **Performance issues on Windows**: Consult `references/windows-optimizations.md` for performance tuning
Report the error to the user with the specific solution being applied, then re-attempt the failed operation.
## Advanced Configuration
When user requests customizations beyond the standard setup:
1. **Identify customization type**: Determine if request involves PHP version, database engine, debugging tools, TYPO3 versions, or additional services
2. **Consult advanced options guide**: Read `references/advanced-options.md` for the relevant configuration section
3. **Present options to user**: Show available choices (e.g., PHP 8.1/8.2/8.3, database engines with tiered selection logic)
4. **Apply configuration**: Follow the templates and instructions in `references/advanced-options.md` to implement the requested customization
5. **Configure optional services**: If user needs Valkey/Redis caching, MailPit, Ofelia scheduler, or other services, follow the service configuration templates in the advanced guide
Offer customization options proactively when user mentions performance requirements, specific PHP versions, or debugging needs.
## Documentation Rendering
### Rendering Extension Documentation
If the extension has a `Documentation/` directory with reStructuredText (.rst) files:
```bash
ddev docs
```
**What it does:**
- Renders `.rst` documentation files to HTML using TYPO3's official render-guides Docker image
- Outputs to `Documentation-GENERATED-temp/`
- Makes documentation accessible at `https://docs.{{DDEV_SITENAME}}.ddev.site/`
**Requirements:**
- `Documentation/Index.rst` must exist
- Docker must be running on the host
**Output:**
```
📚 Rendering TYPO3 Extension Documentation
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📖 Source: Documentation/
📦 Output: Documentation-GENERATED-temp/
🔨 Rendering documentation with TYPO3 render-guides...
✅ Documentation rendered successfully!
🌐 View at: https://docs.{{DDEV_SITENAME}}.ddev.site/
```
**Note:** The docs subdomain is automatically configured in `.ddev/apache/apache-site.conf` and accessible after running `ddev docs`.
## Demo Content (Introduction Package)
When discussing testing capabilities with users, inform them that the Introduction Package is automatically installed with every TYPO3 version during setup, providing:
- 86+ pages with full page tree structure for testing navigation
- 226+ content elements (text, images, forms, tables) for testing rendering
- Multi-language support (English, German, Danish) for testing translations
- Bootstrap Package responsive theme for testing frontend integration
- RTE feature examples for testing rich text functionality
Direct users to test their extension against this demo content at:
- Frontend: `https://v11.{{DDEV_SITENAME}}.ddev.site/` (or v12, v13)
- Backend: `https://v11.{{DDEV_SITENAME}}.ddev.site/typo3/` (or v12, v13)
No manual installation required—the package installs automatically during `ddev install-all` or individual version commands.
## Extension Auto-Configuration
When user's extension requires additional setup beyond standard installation (RTE configuration, Page TSConfig, TypoScript), guide them through creating a custom configuration command:
```bash
# Copy the configure-extension template
cp .ddev/templates/commands/web/configure-extension.optional .ddev/commands/web/configure-{{EXTENSION_KEY}}
chmod +x .ddev/commands/web/configure-{{EXTENSION_KEY}}
# Edit to add your extension-specific configuration
# Examples: RTE YAML, Page TSConfig, site package setup
# Run after TYPO3installation
ddev configure-{{EXTENSION_KEY}} v13
```
### Identify Configuration Needs by Extension Type
**For RTE/CKEditor Extensions**, configure:
- RTE YAML configuration importing the plugin
- Toolbar buttons and editor config
- Page TSConfig for RTE presets
- Example reference: `rte_ckeditor_image` with custom image handling
**For Backend Module Extensions**, configure:
- Page TSConfig for module access
- User permissions setup
- Initial database records
**For Frontend Plugin Extensions**, configure:
- TypoScript configuration
- Example content elements
- Plugin settings
### Template Structure
The `configure-extension.optional` template includes:
1. **Introduction Package Installation** - Demo content for testing
2. **Site Package Creation** - Programmatic extension setup with:
- `ext_emconf.php` - Extension metadata
- `ext_localconf.php` - Global configuration
- `ext_tables.php` - Table definitions and TSConfig loading
3. **Configuration Files** - RTE YAML, Page TSConfig, TypoScript
4. **Cache Flushing** - Ensure changes take effect
5. **Success Message** - Clear next steps for developer
### TYPO3 v13 Site Sets Approach
**Important:** TYPO3 v13 introduces site sets as the modern approach for TypoScript and configuration loading, replacing static templates.
**Site Sets vs Static Templates:**
| Feature | Site Sets (TYPO3 v13+) | Static Templates (Legacy) |
|---------|------------------------|---------------------------|
| Configuration | `config.yaml` in site config | `sys_template` database records |
| Loading Order | Dependency-based | Include order in template |
| Type Safety | Schema-validated | No validation |
| Maintenance | Version-controlled files | Database-stored |
| Best Practice | ✅ Use for TYPO3 v13+ | ⚠️ Legacy approach |
**How Extensions Should Provide Configuration:**
1. **Create a Site Set** in your extension:
```
Configuration/Sets/YourExtensionName/
├── config.yaml # Site set metadata
├── setup.typoscript # TypoScript configuration
└── page.tsconfig # Page TSConfig (optional)
```
2. **Define Site Set** in `config.yaml`:
```yaml
name: vendor/extension-name
label: 'Your Extension Name'
# Optional dependencies load BEFORE your set
optionalDependencies:
- typo3/fluid-styled-content
- bk2k/bootstrap-package
```
3. **Import TypoScript** in `setup.typoscript`:
```typoscript
@import 'EXT:your_extension/Configuration/TypoScript/*.typoscript'
```
4. **Users Add to Site Configuration** (`config/sites/main/config.yaml`):
```yaml
dependencies:
- bootstrap-package/full # Frontend rendering
- vendor/extension-name # Your extension
```
**Benefits:**
- ✅ No sys_template database records needed
- ✅ Proper dependency ordering
- ✅ Version-controlled configuration
- ✅ No static template conflicts
- ✅ Type-safe settings with schema
**Common Pitfall:** Avoid loading TypoScript via BOTH site sets AND static templates - this causes double-loading and configuration conflicts (e.g., duplicate `lib.parseFunc_RTE.tags.img` processors causing unexpected behavior).
**Debugging Site Sets:**
```bash
# Check active site sets for a site
ddev exec vendor/bin/typo3 site:show <siteIdentifier>
# View resolved TypoScript (TYPO3 v13)
Backend → Site Management → Sites → [Your Site] → Dependencies
```
### Example: RTE Configuration Command
For a CKEditor plugin extension:
```bash
#!/bin/bash
VERSION=${1:-v13}
INSTALL_DIR=/var/www/html/$VERSION
# Install demo content
composer require typo3/cms-introduction -d $INSTALL_DIR
vendor/bin/typo3 extension:setup --extension=introduction
# Create site package
mkdir -p $INSTALL_DIR/public/typo3conf/ext/site_rte/Configuration/RTE
# Create RTE YAML importing your plugin
cat > .../Configuration/RTE/Default.yaml << 'EOF'
imports:
- { resource: "EXT:rte_ckeditor/Configuration/RTE/Default.yaml" }
- { resource: "EXT:your_extension/Configuration/RTE/Plugin.yaml" }
editor:
config:
toolbar:
items:
- your_custom_button
- ...
EOF
# Flush caches
vendor/bin/typo3 cache:flush
```
**Benefits:**
- One-command setup after TYPO3 installation
- Consistent configuration across team
- Demo content ready for testing
- Reduces manual configuration errors
### Step 9: Verify Installation
After installation completes, perform these verification steps in order:
1. **Confirm prerequisites passed**: Review output from Step 1 prerequisite validation
2. **Verify extension metadata**: Check that extracted values match project configuration
3. **Test DDEV status**: Run `ddev describe` to confirm containers are running
4. **Validate TYPO3 installations**: Confirm at least one version installed without errors
5. **Test URL accessibility**: Open each TYPO3 version URL in browser to verify routing
6. **Verify backend access**: Log in to TYPO3 backend with credentials (admin / Password:joh316)
## Troubleshooting
### Database Already Exists Error
If reinstalling TYPO3 and you get "database already exists" errors:
```bash
# Clean up and recreate database
ddev mysql -e "DROP DATABASE IF EXISTS v13; CREATE DATABASE v13;"
# Now retry installation
ddev install-v13
```
### TYPO3 Setup Shows "Database contains tables" Error
```bash
# Option 1: Clean database
ddev mysql v13 -e "DROP DATABASE v13; CREATE DATABASE v13;"
# Option 2: Use different database name
# Edit install-v* script to use different DB name
```
### Services Not Loading
If Redis, MailPit, or Ofelia containers don't start:
```bash
# Check container status
docker ps --filter "name=ddev-{{DDEV_SITENAME}}"
# View logs
docker logs ddev-{{DDEV_SITENAME}}-redis
docker logs ddev-{{DDEV_SITENAME}}-mailpit
docker logs ddev-{{DDEV_SITENAME}}-ofelia
# Restart DDEV
ddev restart
```
### Extension Not Appearing in Backend
```bash
# Flush all caches
ddev exec -d /var/www/html/v13 vendor/bin/typo3 cache:flush
# Check extension is symlinked
ddev exec ls -la /var/www/html/v13/vendor/{{VENDOR}}/{{EXTENSION_KEY}}
```
### .gitignore Configuration Best Practices
**CRITICAL:** Ensure `.ddev/.gitignore` is committed to version control, NOT ignored!
**The Double-Ignore Anti-Pattern:**
DDEV often generates `.ddev/.gitignore` with this problematic structure:
```
#ddev-generated: Automatically generated ddev .gitignore.
# You can remove the above line if you want to edit and maintain this file yourself.
/.gitignore ← File ignores ITSELF!
```
**The Problem:**
1. `.ddev/.gitignore` ignores itself (`/.gitignore`)
2. Root `.gitignore` also ignores it (`.ddev/.gitignore`)
3. Result: DDEV ignore rules NOT shared with team
4. Each developer must generate their own DDEV config
5. Inconsistent git behavior across team members
**The Fix:**
1. **Remove from root `.gitignore`:**
```diff
# .gitignore (ROOT)
.ddev/.homeadditions
.ddev/.ddev-docker-compose-full.yaml
- .ddev/.gitignore ← REMOVE THIS LINE
```
2. **Fix `.ddev/.gitignore` to not self-ignore:**
```diff
# .ddev/.gitignore (UPDATED)
- #ddev-generated: Automatically generated ddev .gitignore.
- # You can remove the above line if you want to edit and maintain this file yourself.
- /.gitignore
+ # DDEV gitignore rules
+ # Manually maintained to ensure consistency across team
/**/*.example
/.dbimageBuild
/.ddev-docker-*.yaml
```
3. **Commit DDEV configuration to share with team:**
```bash
git add .ddev/.gitignore .ddev/config.yaml .ddev/docker-compose.*.yaml
git add .ddev/apache/ .ddev/commands/ .ddev/web-build/
git commit -m "[TASK] Add DDEV configuration for development environment"
```
**What to Commit vs. Ignore:**
✅ **Commit (share with team):**
- `.ddev/.gitignore` (ignore rules)
- `.ddev/config.yaml` (main config)
- `.ddev/docker-compose.*.yaml` (custom services)
- `.ddev/apache/` (custom Apache config)
- `.ddev/commands/` (custom DDEV commands)
- `.ddev/web-build/` (custom Dockerfile)
❌ **Ignore (personal/generated):**
- `.ddev/.homeadditions` (personal shell config)
- `.ddev/.ddev-docker-compose-full.yaml` (auto-generated)
- `.ddev/db_snapshots/` (database snapshots)
- `.ddev/.sshimageBuild` (build artifacts)
- `.ddev/.webimageBuild` (build artifacts)
**Validation:**
After fixing, verify:
```bash
# Should show .ddev/.gitignore as tracked
git ls-files .ddev/.gitignore
# Should list DDEV files to be committed
git status .ddev/
```
**Benefits:**
- ✅ Consistent environment across all developers
- ✅ Shared DDEV ignore rules
- ✅ Quick onboarding: `git clone && ddev start`
- ✅ No manual DDEV configuration needed
- ✅ Team follows same git patterns
## Validation Checklist
Before completing, verify:
1. **Confirm prerequisites passed**: Review output from Step 1 prerequisite validation
2. **Verify extension metadata**: Check that extracted values match project configuration
3. **Test DDEV status**: Run `ddev describe` to confirm containers are running
4. **Validate TYPO3 installations**: Confirm at least one version installed without errors
5. **Test URL accessibility**: Open each TYPO3 version URL in browser to verify routing
6. **Verify backend access**: Log in to TYPO3 backend with credentials (admin / Password:joh316)
7. **Confirm extension activation**: Check Extension Manager to ensure extension is loaded
If any verification fails, consult the Troubleshooting section above for resolution steps.
## Output Formatting Guidelines
Throughout all steps, format output for clarity:
- Use emojis for visual indicators: ✅ (success), ❌ (error), 🔧 (configuration), 📦 (installation), 🌐 (URLs), 🔑 (credentials)
- Display progress indicators during operations taking >5 seconds
- Provide copy-pasteable command blocks with explanations
- Present configuration values in formatted tables or code blocks
- Explain what each command does before executing it

44
assets/templates/.envrc Normal file
View File

@@ -0,0 +1,44 @@
# direnv configuration for {{EXTENSION_KEY}}
# Auto-generated by typo3-ddev-skill
#
# Usage: Run `direnv allow` to activate this configuration
# Install direnv: https://direnv.net/
# Add composer bin directory to PATH
PATH_add vendor/bin
# Composer configuration
export COMPOSER_PROCESS_TIMEOUT=600
# DDEV environment variables
export DDEV_PROJECT={{DDEV_SITENAME}}
export DDEV_PRIMARY_URL=https://{{DDEV_SITENAME}}.ddev.site
export DDEV_DOCROOT_URL=https://docs.{{DDEV_SITENAME}}.ddev.site
# Load local environment overrides if present
dotenv_if_exists .env.local
# Display activation message
echo "✅ {{EXTENSION_KEY}} development environment activated"
echo ""
echo "🌐 DDEV Environment:"
echo " Primary: https://{{DDEV_SITENAME}}.ddev.site"
echo " Docs: https://docs.{{DDEV_SITENAME}}.ddev.site"
echo " TYPO3 v11: https://v11.{{DDEV_SITENAME}}.ddev.site"
echo " TYPO3 v12: https://v12.{{DDEV_SITENAME}}.ddev.site"
echo " TYPO3 v13: https://v13.{{DDEV_SITENAME}}.ddev.site"
echo ""
echo "🚀 Quick Start:"
echo " make up Complete startup (start + setup) ⭐"
echo " make start Start DDEV environment"
echo " make setup Complete setup (docs + install + configure)"
echo ""
echo "📚 DDEV Commands:"
echo " ddev docs Render extension documentation"
echo " ddev install-v11 Install TYPO3 11.5 LTS"
echo " ddev install-v12 Install TYPO3 12.4 LTS"
echo " ddev install-v13 Install TYPO3 13.4 LTS"
echo " ddev install-all Install all TYPO3 versions"
echo ""
echo "📦 Composer Tools: Available in vendor/bin/"
echo "🔧 More Commands: make help (if Makefile present)"

View File

@@ -0,0 +1,124 @@
# Makefile for {{EXTENSION_NAME}} TYPO3 Extension
# Auto-generated by ddev setup
.PHONY: help
help: ## Show available targets
@awk 'BEGIN{FS=":.*##";print "\nUsage: make <target>\n"} /^[a-zA-Z0-9_.-]+:.*##/ {printf " %-22s %s\n", $$1, $$2}' $(MAKEFILE_LIST)
# ===================================
# DDEV Environment Commands
# ===================================
.PHONY: up
up: start setup ## Complete startup (start DDEV + run setup) - ONE COMMAND TO RULE THEM ALL
.PHONY: start
start: ## Start DDEV environment
ddev start
.PHONY: stop
stop: ## Stop DDEV environment
ddev stop
.PHONY: setup
setup: ## Complete setup (install all TYPO3 versions)
@ddev describe >/dev/null 2>&1 || ddev start
ddev install-all
.PHONY: install-v12
install-v12: ## Install TYPO3 v12.4 LTS with extension
ddev install-v12
.PHONY: install-v13
install-v13: ## Install TYPO3 v13.0 LTS with extension
ddev install-v13
.PHONY: install-all
install-all: ## Install all TYPO3 versions
ddev install-all
.PHONY: ddev-restart
ddev-restart: ## Restart DDEV containers
ddev restart
.PHONY: ssh
ssh: ## SSH into DDEV web container
ddev ssh
# ===================================
# Composer & Quality Commands
# ===================================
.PHONY: install
install: ## Install composer dependencies
composer install
.PHONY: lint
lint: ## Run all linters (PHP syntax + PHPStan + code style)
@echo "==> Running PHP lint..."
composer ci:test:php:lint || composer lint
@echo "==> Running PHPStan..."
composer phpstan || composer ci:phpstan || echo "⚠️ PHPStan not configured"
@echo "==> Running code style check..."
composer ci:test:php:cgl || composer cs:check || echo "⚠️ Code style check not configured"
@echo "✅ All linters passed"
.PHONY: format
format: ## Auto-fix code style issues (PSR-12)
composer code:fix || composer cs:fix
.PHONY: typecheck
typecheck: ## Run PHPStan static analysis
composer phpstan || composer ci:phpstan
.PHONY: test
test: ## Run all tests (unit + functional)
composer test
.PHONY: test-unit
test-unit: ## Run unit tests only
composer test:unit
.PHONY: test-functional
test-functional: ## Run functional tests
composer test:functional
.PHONY: test-coverage
test-coverage: ## Generate test coverage report
composer test:coverage
.PHONY: ci
ci: ## Run complete CI pipeline (pre-commit checks)
composer ci || composer ci:test
.PHONY: clean
clean: ## Clean temporary files and caches
rm -rf .php-cs-fixer.cache
rm -rf var/
rm -rf .Build/.cache
# ===================================
# Extension-Specific Commands
# (Customize based on your extension)
# ===================================
.PHONY: urls
urls: ## Show all access URLs
@echo ""
@echo "{{EXTENSION_NAME}} - Access URLs"
@echo "==============================="
@echo ""
@echo "TYPO3 v12.4 LTS:"
@echo " Frontend: https://v12.{{DDEV_PROJECT}}.ddev.site/"
@echo " Backend: https://v12.{{DDEV_PROJECT}}.ddev.site/typo3/"
@echo ""
@echo "TYPO3 v13.0 LTS:"
@echo " Frontend: https://v13.{{DDEV_PROJECT}}.ddev.site/"
@echo " Backend: https://v13.{{DDEV_PROJECT}}.ddev.site/typo3/"
@echo ""
@echo "Backend Credentials:"
@echo " Username: admin"
@echo " Password: Password:joh316"
@echo ""
.DEFAULT_GOAL := help

View File

@@ -0,0 +1,361 @@
# DDEV Services Documentation
This DDEV setup includes additional services for TYPO3 extension development.
## Included Services
### 1. Redis (Caching)
**Container**: `ddev-rte-ckeditor-image-redis`
**Image**: `redis:7-alpine`
**Port**: 6379 (internal)
**Purpose**: High-performance caching for TYPO3
**Access**:
```bash
# From host
ddev redis-cli
# From web container
ddev ssh
redis-cli -h redis
```
**Configuration**:
- See `.ddev/config.redis.yaml` for TYPO3 configuration example
- Add to `/var/www/html/v13/config/system/additional.php`
**Testing**:
```bash
ddev ssh
redis-cli -h redis ping
# Should return: PONG
```
---
### 2. MailPit (Email Testing)
**Container**: `ddev-{{DDEV_SITENAME}}-mailpit`
**Image**: `axllent/mailpit`
**Ports**:
- 1025 (SMTP)
- 8025 (Web UI)
**Purpose**: Catch all emails sent by TYPO3 for testing
**Access**:
- **Web UI**: `http://rte-ckeditor-image.ddev.site:8025`
- **SMTP**: `mailpit:1025` (from containers)
**TYPO3 Configuration**:
Already configured in `.ddev/docker-compose.web.yaml`:
```yaml
TYPO3_INSTALL_MAIL_TRANSPORT: smtp
TYPO3_INSTALL_MAIL_TRANSPORT_SMTP_SERVER: mailpit:1025
```
Or manually in `AdditionalConfiguration.php`:
```php
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport'] = 'smtp';
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['transport_smtp_server'] = 'mailpit:1025';
```
**Testing**:
```bash
# Send test email from TYPO3
ddev ssh
cd /var/www/html/v13
vendor/bin/typo3 mailer:spool:send
# View in MailPit UI
open http://rte-ckeditor-image.ddev.site:8025
```
---
### 3. Ofelia (Cron/Scheduler)
**Container**: `ddev-rte-ckeditor-image-ofelia`
**Image**: `ghcr.io/netresearch/ofelia:latest`
**Purpose**: Run TYPO3 scheduler tasks automatically
**Configuration**: `.ddev/docker-compose.ofelia.yaml`
**Scheduled Jobs**:
- TYPO3 scheduler for v11, v12, v13: Every 1 minute
- Cache warmup for v13: Every 1 hour
**View Logs**:
```bash
# Check if Ofelia is running
docker ps | grep ofelia
# View Ofelia logs
docker logs -f ddev-rte-ckeditor-image-ofelia
# Check scheduler execution
ddev ssh
cd /var/www/html/v13
vendor/bin/typo3 scheduler:list
```
**Manual Execution**:
```bash
ddev ssh
t3-scheduler-v13 # alias for scheduler:run on v13
t3-scheduler-all # run scheduler on all versions
```
---
## Alternative: Traditional Cron in Web Container
If you prefer traditional cron instead of Ofelia:
1. **Enable cron in Dockerfile**:
Edit `.ddev/web-build/Dockerfile` and add:
```dockerfile
RUN apt-get update && apt-get install -y cron
COPY install-cron.sh /opt/install-cron.sh
RUN chmod +x /opt/install-cron.sh && /opt/install-cron.sh
```
2. **Restart DDEV**:
```bash
ddev restart
```
3. **Verify cron**:
```bash
ddev ssh
crontab -l
service cron status
```
---
## Service Management
### Start/Stop Services
```bash
# Restart all services
ddev restart
# Stop DDEV (keeps volumes)
ddev stop
# Remove containers (keeps volumes)
ddev delete
# Remove everything including volumes
ddev delete --omit-snapshot --yes
docker volume rm rte-ckeditor-image-redis-data
```
### View Service Status
```bash
# All DDEV containers
ddev describe
# All containers
docker ps | grep rte-ckeditor-image
# Service logs
docker logs ddev-rte-ckeditor-image-redis
docker logs ddev-{{DDEV_SITENAME}}-mailpit
docker logs ddev-rte-ckeditor-image-ofelia
```
### Access Services
```bash
# Redis CLI
ddev redis-cli
# Or from web container
ddev ssh
redis-cli -h redis
# MailPit web interface
open http://rte-ckeditor-image.ddev.site:8025
# Check Redis connection from TYPO3
ddev ssh
cd /var/www/html/v13
vendor/bin/typo3 cache:flush
```
---
## TYPO3 Scheduler Configuration
### Enable Scheduler Tasks
1. **Access TYPO3 Backend**: https://v13.rte-ckeditor-image.ddev.site/typo3/
2. **Login**: admin / Password:joh316
3. **System → Scheduler**
4. **Create tasks** (examples):
- Table garbage collection
- Index queue worker
- File abstraction layer indexing
- Import/Export tasks
### Verify Scheduler is Running
```bash
ddev ssh
cd /var/www/html/v13
# List all scheduler tasks
vendor/bin/typo3 scheduler:list
# Run manually (for testing)
vendor/bin/typo3 scheduler:run
# Check last execution time
vendor/bin/typo3 scheduler:list --verbose
```
---
## Performance Tuning
### Redis
**Memory Limit**: Currently 256MB
**Eviction Policy**: `allkeys-lru` (Least Recently Used)
To adjust:
```yaml
# .ddev/docker-compose.services.yaml
environment:
- REDIS_MAXMEMORY=512mb # Increase if needed
```
### MailPit
No tuning needed for development. All emails are stored in memory.
### Ofelia/Cron
**Frequency**: Default is every 1 minute
To adjust, edit `.ddev/docker-compose.ofelia.yaml`:
```yaml
# Every 5 minutes instead
ofelia.job-exec.typo3-scheduler-v13.schedule: "@every 5m"
# Specific time (e.g., 2am daily)
ofelia.job-exec.cache-warmup.schedule: "0 2 * * *"
```
---
## Troubleshooting
### Redis Not Connecting
```bash
# Test Redis
ddev ssh
redis-cli -h redis ping
# Should return: PONG
# If not, check Redis container
docker logs ddev-rte-ckeditor-image-redis
```
### MailPit Not Receiving Emails
```bash
# Check TYPO3 mail configuration
ddev ssh
cd /var/www/html/v13
vendor/bin/typo3 configuration:show MAIL
# Test email sending
vendor/bin/typo3 mailer:spool:send
```
### Scheduler Not Running
```bash
# Check Ofelia logs
docker logs -f ddev-rte-ckeditor-image-ofelia
# Manually run scheduler
ddev ssh
t3-scheduler-v13
# Check for errors
cd /var/www/html/v13
vendor/bin/typo3 scheduler:list --verbose
```
### Remove Service
To remove a service, comment it out in `.ddev/docker-compose.services.yaml` and restart:
```bash
ddev restart
```
---
## Additional Services (Optional)
### Adminer (Database GUI)
```bash
ddev get ddev/ddev-adminer
ddev restart
# Access: https://rte-ckeditor-image.ddev.site:9999
```
### Elasticsearch
```yaml
# Add to .ddev/docker-compose.services.yaml
elasticsearch:
image: elasticsearch:8.10.2
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ports:
- "9200"
```
### Solr
```yaml
# Add to .ddev/docker-compose.services.yaml
solr:
image: solr:9
ports:
- "8983"
volumes:
- solr-data:/var/solr
```
---
## Quick Reference
| Service | Access | Purpose |
|---------|--------|---------|
| Redis | `redis-cli -h redis` | Caching |
| MailPit UI | http://localhost:8025 | Email testing |
| MailPit SMTP | `mailpit:1025` | Email delivery |
| Ofelia | Background | Cron jobs |
| Web | https://*.ddev.site | TYPO3 instances |
| Database | `ddev mysql` | MariaDB |
---
**Questions?** Check DDEV docs: https://ddev.readthedocs.io/

View File

@@ -0,0 +1,161 @@
ServerName {{DDEV_SITENAME}}.ddev.site
<VirtualHost *:80>
# Workaround from https://mail-archives.apache.org/mod_mbox/httpd-users/201403.mbox/%3C49404A24C7FAD94BB7B45E86A9305F6214D04652@MSGEXSV21103.ent.wfb.bank.corp%3E
# See also https://gist.github.com/nurtext/b6ac07ac7d8c372bc8eb
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d
RewriteRule ^(.+[^/])$ https://%{HTTP_HOST}$1/ [redirect,last]
SetEnvIf X-Forwarded-Proto "https" HTTPS=on
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
<Directory "/var/www/html/">
AllowOverride All
Allow from All
</Directory>
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog /dev/stdout
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
# Simple ddev technique to get a phpstatus
Alias "/phpstatus" "/var/www/phpstatus.php"
</VirtualHost>
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/ssl/certs/master.crt
SSLCertificateKeyFile /etc/ssl/certs/master.key
# Workaround from https://mail-archives.apache.org/mod_mbox/httpd-users/201403.mbox/%3C49404A24C7FAD94BB7B45E86A9305F6214D04652@MSGEXSV21103.ent.wfb.bank.corp%3E
# See also https://gist.github.com/nurtext/b6ac07ac7d8c372bc8eb
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d
RewriteRule ^(.+[^/])$ https://%{HTTP_HOST}$1/ [redirect,last]
SetEnvIf X-Forwarded-Proto "https" HTTPS=on
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
<Directory "/var/www/html/">
AllowOverride All
Allow from All
</Directory>
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog /dev/stdout
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
# Simple ddev technique to get a phpstatus
Alias "/phpstatus" "/var/www/phpstatus.php"
</VirtualHost>
<VirtualHost *:80>
SetEnvIf X-Forwarded-Proto "https" HTTPS=on
DocumentRoot /var/www/{{EXTENSION_KEY}}/Documentation-GENERATED-temp
ServerAlias docs.{{DDEV_SITENAME}}.ddev.site
<Directory "/var/www/{{EXTENSION_KEY}}/Documentation-GENERATED-temp/">
AllowOverride All
Allow from All
DirectoryIndex Index.html
</Directory>
ErrorLog /dev/stdout
Alias "/phpstatus" "/var/www/phpstatus.php"
</VirtualHost>
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d
RewriteRule ^(.+[^/])$ https://%{HTTP_HOST}$1/ [redirect,last]
SetEnvIf X-Forwarded-Proto "https" HTTPS=on
DocumentRoot /var/www/html/v11/public
ServerAlias v11.{{DDEV_SITENAME}}.ddev.site
<Directory "/var/www/html/v11/">
AllowOverride All
Allow from All
</Directory>
ErrorLog /dev/stdout
CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias "/phpstatus" "/var/www/phpstatus.php"
</VirtualHost>
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d
RewriteRule ^(.+[^/])$ https://%{HTTP_HOST}$1/ [redirect,last]
SetEnvIf X-Forwarded-Proto "https" HTTPS=on
DocumentRoot /var/www/html/v12/public
ServerAlias v12.{{DDEV_SITENAME}}.ddev.site
<Directory "/var/www/html/v12/">
AllowOverride All
Allow from All
</Directory>
ErrorLog /dev/stdout
CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias "/phpstatus" "/var/www/phpstatus.php"
</VirtualHost>
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} -d
RewriteRule ^(.+[^/])$ https://%{HTTP_HOST}$1/ [redirect,last]
SetEnvIf X-Forwarded-Proto "https" HTTPS=on
DocumentRoot /var/www/html/v13/public
ServerAlias v13.{{DDEV_SITENAME}}.ddev.site
<Directory "/var/www/html/v13/">
AllowOverride All
Allow from All
</Directory>
ErrorLog /dev/stdout
CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias "/phpstatus" "/var/www/phpstatus.php"
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

View File

@@ -0,0 +1,74 @@
#!/bin/bash
## Description: Render TYPO3 extension documentation to HTML
## Usage: docs
## Example: "ddev docs"
set -e
PROJECT_DIR="$(pwd)"
DOC_SOURCE="${PROJECT_DIR}/Documentation"
DOC_OUTPUT="${PROJECT_DIR}/Documentation-GENERATED-temp"
echo "📚 Rendering TYPO3 Extension Documentation"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Check if Documentation directory exists
if [ ! -d "$DOC_SOURCE" ]; then
echo "❌ Error: Documentation directory not found"
echo "💡 Tip: Create a Documentation/ directory with Index.rst to get started"
exit 1
fi
# Check if Index.rst exists
if [ ! -f "$DOC_SOURCE/Index.rst" ]; then
echo "❌ Error: Index.rst not found in Documentation/"
echo "💡 Tip: Create Documentation/Index.rst as the main entry point"
exit 1
fi
echo "📖 Source: Documentation/"
echo "📦 Output: Documentation-GENERATED-temp/"
echo ""
# Clean previous output
if [ -d "$DOC_OUTPUT" ]; then
echo "🧹 Cleaning previous documentation build..."
rm -rf "$DOC_OUTPUT"
fi
# Render documentation using TYPO3's official docker image
echo "🔨 Rendering documentation with TYPO3 render-guides..."
echo ""
docker run --rm \
-v "${PROJECT_DIR}:/project" \
--user "$(id -u):$(id -g)" \
ghcr.io/typo3-documentation/render-guides:latest \
--no-progress \
--output=/project/Documentation-GENERATED-temp \
/project/Documentation 2>&1
if [ $? -eq 0 ]; then
# Check for output files (structure may vary)
if [ -f "$DOC_OUTPUT/Result/project/0.0.0/Index.html" ] || \
[ -f "$DOC_OUTPUT/Index.html" ] || \
[ -d "$DOC_OUTPUT" ]; then
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ Documentation rendered successfully!"
echo ""
echo "🌐 View at: https://docs.$(ddev describe -j | jq -r .raw.name).ddev.site/"
echo "📁 Output: Documentation-GENERATED-temp/"
echo ""
else
echo ""
echo "⚠️ Build completed but output structure unclear"
echo "📁 Check: Documentation-GENERATED-temp/"
fi
else
echo ""
echo "❌ Documentation rendering failed"
echo "💡 Check your .rst files for syntax errors"
exit 1
fi

View File

@@ -0,0 +1,17 @@
#!/bin/bash
## Description: Capture git info for landing page before container build
## Usage: Runs automatically before ddev start
## Example: "ddev start"
# Get git info from host
GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
GIT_COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
GIT_PR=$(gh pr view --json number 2>/dev/null | jq -r '.number // "unknown"' || echo "unknown")
# Export for docker-compose to use
export DDEV_GIT_BRANCH="$GIT_BRANCH"
export DDEV_GIT_COMMIT="$GIT_COMMIT"
export DDEV_GIT_PR="$GIT_PR"
echo "Git info captured: $GIT_BRANCH @ $GIT_COMMIT (PR: $GIT_PR)"

View File

@@ -0,0 +1,41 @@
#!/bin/bash
## Description: Complete setup - docs, install TYPO3, configure extension
## Usage: setup
## Example: "ddev setup"
set -e
echo "🚀 Complete DDEV Environment Setup"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Step 1: Render documentation
echo "📚 Step 1/3: Rendering documentation..."
if [ -d "/var/www/${EXTENSION_KEY}/Documentation" ]; then
ddev docs
else
echo "⚠️ No Documentation/ directory found, skipping docs rendering"
fi
echo ""
# Step 2: Install TYPO3
echo "🌐 Step 2/3: Installing TYPO3..."
ddev exec /mnt/ddev_config/commands/web/install-all
echo ""
# Done
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ Setup Complete!"
echo ""
echo "🌐 Access Your Environment:"
echo " Overview: https://${DDEV_SITENAME}.ddev.site/"
echo " Documentation: https://docs.${DDEV_SITENAME}.ddev.site/"
echo " TYPO3 v11: https://v11.${DDEV_SITENAME}.ddev.site/"
echo " TYPO3 v12: https://v12.${DDEV_SITENAME}.ddev.site/"
echo " TYPO3 v13: https://v13.${DDEV_SITENAME}.ddev.site/"
echo ""
echo "🔑 Backend Login:"
echo " Username: admin"
echo " Password: Password:joh316"
echo ""

View File

@@ -0,0 +1,16 @@
#!/bin/bash
## Description: Install all TYPO3 versions (11, 12, 13) with your extension
## Usage: install-all
## Example: ddev install-all
echo "Installing TYPO3 11.5 LTS..."
/mnt/ddev_config/commands/web/install-v11
echo "Installing TYPO3 12.4 LTS..."
/mnt/ddev_config/commands/web/install-v12
echo "Installing TYPO3 13.4 LTS..."
/mnt/ddev_config/commands/web/install-v13
echo "✅ All TYPO3 versions installed successfully!"

View File

@@ -0,0 +1,54 @@
#!/bin/bash
## Description: Install TYPO3 11.5 LTS with your extension
## Usage: install-v11
## Example: ddev install-v11
VERSION=v11
rm -rf /var/www/html/$VERSION/*
mkdir -p /var/www/html/$VERSION/
echo "{}" > /var/www/html/$VERSION/composer.json
composer config extra.typo3/cms.web-dir public -d /var/www/html/$VERSION
composer config repositories.$EXTENSION_KEY path ../../$EXTENSION_KEY -d /var/www/html/$VERSION
composer config --no-plugins allow-plugins.typo3/cms-composer-installers true -d /var/www/html/$VERSION
composer config --no-plugins allow-plugins.typo3/class-alias-loader true -d /var/www/html/$VERSION
composer req t3/cms:'^11' $PACKAGE_NAME:'*@dev' --no-progress -n -d /var/www/html/$VERSION
composer req typo3/cms-extensionmanager --no-progress -n -d /var/www/html/$VERSION
composer req --dev typo3/cms-styleguide --no-progress -n -d /var/www/html/$VERSION
composer req typo3/cms-introduction --no-progress -n -d /var/www/html/$VERSION
cd /var/www/html/$VERSION
TYPO3_INSTALL_DB_DBNAME=$VERSION
vendor/bin/typo3cms install:setup -n --database-name $VERSION
vendor/bin/typo3cms configuration:set 'BE/debug' 1
vendor/bin/typo3cms configuration:set 'FE/debug' 1
vendor/bin/typo3cms configuration:set 'SYS/devIPmask' '*'
vendor/bin/typo3cms configuration:set 'SYS/displayErrors' 1
vendor/bin/typo3cms configuration:set 'SYS/trustedHostsPattern' '.*\.{{DDEV_SITENAME}}\.ddev\.site'
vendor/bin/typo3cms configuration:set 'MAIL/transport' 'smtp'
vendor/bin/typo3cms configuration:set 'MAIL/transport_smtp_server' 'localhost:1025'
vendor/bin/typo3cms configuration:set 'GFX/processor' 'ImageMagick'
vendor/bin/typo3cms configuration:set 'GFX/processor_path' '/usr/bin/'
vendor/bin/typo3cms configuration:set 'GFX/processor_path_lzw' '/usr/bin/'
sed -i "/'deprecations'/,/^[[:space:]]*'disabled' => true,/s/'disabled' => true,/'disabled' => false,/" /var/www/html/$VERSION/public/typo3conf/LocalConfiguration.php
sed -i -e "s/base: ht\//base: \//g" /var/www/html/$VERSION/config/sites/main/config.yaml
sed -i -e 's/base: \/en\//base: \//g' /var/www/html/$VERSION/config/sites/main/config.yaml
vendor/bin/typo3cms cache:flush
echo ""
echo "✅ TYPO3 $VERSION installation complete!"
echo "📦 Your extension is activated and ready to use"
echo "📐 TYPO3 Styleguide is available for UI pattern reference"
echo "📦 Introduction Package installed with demo content (86+ pages, 226+ content elements)"
# Auto-configure extension if configure script exists
if [ -f "/mnt/ddev_config/commands/web/configure-{{EXTENSION_KEY}}" ]; then
echo ""
echo "🔧 Auto-configuring {{EXTENSION_KEY}} extension..."
/mnt/ddev_config/commands/web/configure-{{EXTENSION_KEY}} $VERSION
fi

View File

@@ -0,0 +1,54 @@
#!/bin/bash
## Description: Install TYPO3 12.4 LTS with your extension
## Usage: install-v12
## Example: ddev install-v12
VERSION=v12
rm -rf /var/www/html/$VERSION/*
mkdir -p /var/www/html/$VERSION/
echo "{}" > /var/www/html/$VERSION/composer.json
composer config extra.typo3/cms.web-dir public -d /var/www/html/$VERSION
composer config repositories.$EXTENSION_KEY path ../../$EXTENSION_KEY -d /var/www/html/$VERSION
composer config --no-plugins allow-plugins.typo3/cms-composer-installers true -d /var/www/html/$VERSION
composer config --no-plugins allow-plugins.typo3/class-alias-loader true -d /var/www/html/$VERSION
composer req t3/cms:'^12' $PACKAGE_NAME:'*@dev' --no-progress -n -d /var/www/html/$VERSION
composer req typo3/cms-extensionmanager --no-progress -n -d /var/www/html/$VERSION
composer req --dev typo3/cms-styleguide --no-progress -n -d /var/www/html/$VERSION
composer req typo3/cms-introduction --no-progress -n -d /var/www/html/$VERSION
cd /var/www/html/$VERSION
TYPO3_INSTALL_DB_DBNAME=$VERSION
vendor/bin/typo3 install:setup -n --database-name $VERSION
vendor/bin/typo3 configuration:set 'BE/debug' 1
vendor/bin/typo3 configuration:set 'FE/debug' 1
vendor/bin/typo3 configuration:set 'SYS/devIPmask' '*'
vendor/bin/typo3 configuration:set 'SYS/displayErrors' 1
vendor/bin/typo3 configuration:set 'SYS/trustedHostsPattern' '.*\.{{DDEV_SITENAME}}\.ddev\.site'
vendor/bin/typo3 configuration:set 'MAIL/transport' 'smtp'
vendor/bin/typo3 configuration:set 'MAIL/transport_smtp_server' 'localhost:1025'
vendor/bin/typo3 configuration:set 'MAIL/defaultMailFromAddress' 'admin@example.com'
vendor/bin/typo3 configuration:set 'GFX/processor' 'ImageMagick'
vendor/bin/typo3 configuration:set 'GFX/processor_path' '/usr/bin/'
sed -i "/'deprecations'/,/^[[:space:]]*'disabled' => true,/s/'disabled' => true,/'disabled' => false,/" /var/www/html/$VERSION/config/system/settings.php
sed -i -e "s/base: ht\//base: \//g" /var/www/html/$VERSION/config/sites/main/config.yaml
sed -i -e 's/base: \/en\//base: \//g' /var/www/html/$VERSION/config/sites/main/config.yaml
vendor/bin/typo3 cache:flush
echo ""
echo "✅ TYPO3 $VERSION installation complete!"
echo "📦 Your extension is activated and ready to use"
echo "📐 TYPO3 Styleguide is available for UI pattern reference"
echo "📦 Introduction Package installed with demo content (86+ pages, 226+ content elements)"
# Auto-configure extension if configure script exists
if [ -f "/mnt/ddev_config/commands/web/configure-{{EXTENSION_KEY}}" ]; then
echo ""
echo "🔧 Auto-configuring {{EXTENSION_KEY}} extension..."
/mnt/ddev_config/commands/web/configure-{{EXTENSION_KEY}} $VERSION
fi

View File

@@ -0,0 +1,56 @@
#!/bin/bash
## Description: Install TYPO3 13.4 LTS with your extension
## Usage: install-v13
## Example: ddev install-v13
VERSION=v13
rm -rf /var/www/html/$VERSION/*
mkdir -p /var/www/html/$VERSION/
echo "{}" > /var/www/html/$VERSION/composer.json
composer config extra.typo3/cms.web-dir public -d /var/www/html/$VERSION
composer config repositories.$EXTENSION_KEY path ../../$EXTENSION_KEY -d /var/www/html/$VERSION
composer config --no-plugins allow-plugins.typo3/cms-composer-installers true -d /var/www/html/$VERSION
composer config --no-plugins allow-plugins.typo3/class-alias-loader true -d /var/www/html/$VERSION
composer req t3/cms:'^13' $PACKAGE_NAME:'*@dev' --no-progress -n -d /var/www/html/$VERSION
composer req typo3/cms-extensionmanager --no-progress -n -d /var/www/html/$VERSION
composer req --dev typo3/cms-styleguide --no-progress -n -d /var/www/html/$VERSION
composer req typo3/cms-introduction --no-progress -n -d /var/www/html/$VERSION
cd /var/www/html/$VERSION
mysql -h db -u root -p"root" -e "DROP DATABASE IF EXISTS ${VERSION};"
mysql -h db -u root -p"root" -e "CREATE DATABASE ${VERSION};"
vendor/bin/typo3 setup -n --dbname=$VERSION --password=$TYPO3_DB_PASSWORD --create-site="https://${VERSION}.{{DDEV_SITENAME}}.ddev.site" --admin-user-password=$TYPO3_SETUP_ADMIN_PASSWORD
vendor/bin/typo3 configuration:set 'BE/debug' 1
vendor/bin/typo3 configuration:set 'FE/debug' 1
vendor/bin/typo3 configuration:set 'SYS/devIPmask' '*'
vendor/bin/typo3 configuration:set 'SYS/displayErrors' 1
vendor/bin/typo3 configuration:set 'SYS/trustedHostsPattern' '.*\.{{DDEV_SITENAME}}\.ddev\.site'
vendor/bin/typo3 configuration:set 'MAIL/transport' 'smtp'
vendor/bin/typo3 configuration:set 'MAIL/transport_smtp_server' 'localhost:1025'
vendor/bin/typo3 configuration:set 'MAIL/defaultMailFromAddress' 'admin@example.com'
vendor/bin/typo3 configuration:set 'GFX/processor' 'ImageMagick'
vendor/bin/typo3 configuration:set 'GFX/processor_path' '/usr/bin/'
sed -i "/'deprecations'/,/^[[:space:]]*'disabled' => true,/s/'disabled' => true,/'disabled' => false,/" /var/www/html/$VERSION/config/system/settings.php
vendor/bin/typo3 extension:setup
vendor/bin/typo3 cache:flush
echo ""
echo "✅ TYPO3 $VERSION installation complete!"
echo "📦 Your extension is activated and ready to use"
echo "📐 TYPO3 Styleguide is available for UI pattern reference"
echo "📦 Introduction Package installed with demo content (86+ pages, 226+ content elements)"
# Auto-configure extension if configure script exists
if [ -f "/mnt/ddev_config/commands/web/configure-{{EXTENSION_KEY}}" ]; then
echo ""
echo "🔧 Auto-configuring {{EXTENSION_KEY}} extension..."
/mnt/ddev_config/commands/web/configure-{{EXTENSION_KEY}} $VERSION
fi

View File

@@ -0,0 +1,113 @@
#!/bin/bash
## Description: Auto-configure your TYPO3 extension with demo content and settings
## Usage: configure-extension [VERSION]
## Example: ddev configure-extension v13
VERSION=${1:-v13}
INSTALL_DIR=/var/www/html/$VERSION
echo "🔧 Configuring {{EXTENSION_KEY}} extension for $VERSION..."
# Install Introduction Package for demo content
echo "📦 Installing TYPO3 Introduction Package..."
composer require typo3/cms-introduction --no-progress -d $INSTALL_DIR
# Activate Introduction extension
echo "✅ Activating Introduction extension..."
cd $INSTALL_DIR
vendor/bin/typo3 extension:setup --extension=introduction
# Remove default "main" site created by typo3 setup (Introduction creates its own site)
echo "🧹 Removing default site (Introduction package provides its own)..."
rm -rf $INSTALL_DIR/config/sites/main
# Optional: Create site package for extension-specific configuration
# Uncomment and customize for extensions needing RTE, TsConfig, or TypoScript setup
# echo "📝 Creating site configuration package..."
# mkdir -p $INSTALL_DIR/public/typo3conf/ext/site_config/Configuration
#
# cat > $INSTALL_DIR/public/typo3conf/ext/site_config/ext_emconf.php << 'EOF'
# <?php
# $EM_CONF[$_EXTKEY] = [
# 'title' => 'Site Configuration',
# 'description' => 'Configuration for {{EXTENSION_KEY}}',
# 'category' => 'templates',
# 'state' => 'stable',
# 'version' => '1.0.0',
# 'constraints' => [
# 'depends' => [
# 'typo3' => '13.4.0-13.4.99',
# '{{EXTENSION_KEY}}' => '',
# ],
# ],
# ];
# EOF
# Example: RTE configuration for CKEditor plugins
# IMPORTANT: When defining editor.config, YAML replaces the entire block instead of merging!
# DO NOT override importModules or externalPlugins - let Plugin.yaml handle them.
#
# mkdir -p $INSTALL_DIR/public/typo3conf/ext/site_config/Configuration/RTE
#
# cat > $INSTALL_DIR/public/typo3conf/ext/site_config/Configuration/RTE/Default.yaml << 'EOF'
# imports:
# - { resource: "EXT:rte_ckeditor/Configuration/RTE/Default.yaml" }
# - { resource: "EXT:{{EXTENSION_KEY}}/Configuration/RTE/Plugin.yaml" }
#
# editor:
# config:
# # IMPORTANT: DO NOT override importModules here!
# # Plugin.yaml provides: importModules: ['@vendor/extension/Plugins/myplugin.js']
# # Plugin.yaml provides: externalPlugins: { myplugin: { route: ... } }
# # If you need html-support, add it to Plugin.yaml or merge arrays properly
#
# toolbar:
# items:
# - heading
# - '|'
# - bold
# - italic
# # Add your custom toolbar buttons here
# EOF
# Example: Page TSConfig
# mkdir -p $INSTALL_DIR/public/typo3conf/ext/site_config/Configuration/TsConfig/Page
#
# cat > $INSTALL_DIR/public/typo3conf/ext/site_config/Configuration/TsConfig/Page/Config.tsconfig << 'EOF'
# # Add your Page TSConfig here
# # Example: RTE.default.preset = default
# EOF
# IMPORTANT: If creating site_config extension, you must register it!
# Since site_config is not a composer-installed extension, ext_localconf.php
# and ext_tables.php won't be loaded automatically. Instead:
#
# 1. Register RTE preset in AdditionalConfiguration.php:
# cat >> $INSTALL_DIR/config/system/additional.php << 'EOF'
#
# // Register custom RTE preset
# $GLOBALS['TYPO3_CONF_VARS']['RTE']['Presets']['default'] = 'EXT:site_config/Configuration/RTE/Default.yaml';
# EOF
#
# 2. Add Page TSConfig to site configuration:
# cat >> $INSTALL_DIR/config/sites/introduction/config.yaml << 'EOF'
# pagesTsConfig:
# 'RTE.default.preset': 'default'
# EOF
# Flush caches
echo "🧹 Flushing caches..."
cd $INSTALL_DIR
vendor/bin/typo3 cache:flush
echo "✅ Extension configuration complete!"
echo ""
echo "📌 Access your TYPO3 installation:"
echo " Frontend: https://$VERSION.{{DDEV_SITENAME}}.ddev.site/"
echo " Backend: https://$VERSION.{{DDEV_SITENAME}}.ddev.site/typo3/"
echo " Username: admin"
echo " Password: Password:joh316"
echo ""
echo "🎨 Your extension is now configured and ready to test!"

View File

@@ -0,0 +1,17 @@
#!/bin/bash
## Description: Generate index.html overview page
## Usage: generate-index
## Example: ddev generate-index
EXTENSION_KEY=$(basename "$(pwd)")
DDEV_PROJECT=$(ddev describe -j | jq -r '.name' 2>/dev/null || echo "$EXTENSION_KEY")
# Simple sed-based substitution
sed -e "s/{{EXTENSION_NAME}}/$EXTENSION_KEY/g" \
-e "s/{{EXTENSION_KEY}}/$EXTENSION_KEY/g" \
-e "s/{{DDEV_PROJECT}}/$DDEV_PROJECT/g" \
/var/www/html/.ddev/index.html.template > /var/www/html/index.html
echo "✅ index.html generated successfully!"
echo "Access your project at: http://$DDEV_PROJECT.ddev.site/"

View File

@@ -0,0 +1,17 @@
#!/bin/bash
## Description: Generate Makefile for TYPO3 extension development
## Usage: generate-makefile
## Example: ddev generate-makefile
EXTENSION_KEY=$(basename "$(pwd)")
DDEV_PROJECT=$(ddev describe -j | jq -r '.name' 2>/dev/null || echo "$EXTENSION_KEY")
# Simple sed-based substitution
sed -e "s/{{EXTENSION_NAME}}/$EXTENSION_KEY/g" \
-e "s/{{EXTENSION_KEY}}/$EXTENSION_KEY/g" \
-e "s/{{DDEV_PROJECT}}/$DDEV_PROJECT/g" \
/var/www/html/.ddev/Makefile.template > /var/www/html/Makefile
echo "✅ Makefile generated successfully!"
echo "Run 'make help' to see available commands"

View File

@@ -0,0 +1,33 @@
#!/bin/bash
## Description: Install TYPO3 Introduction Package with demo content
## Usage: install-introduction [VERSION]
## Example: ddev install-introduction
## Example: ddev install-introduction v13
VERSION=${1:-v13}
echo "Installing Introduction Package for $VERSION..."
cd /var/www/html/$VERSION
# Install introduction package
composer require typo3/cms-introduction --no-progress
# Setup extension
vendor/bin/typo3 extension:setup --extension=introduction
# Flush caches
vendor/bin/typo3 cache:flush
echo "✅ Introduction Package installed successfully!"
echo ""
echo "Demo content includes:"
echo " - 86+ pages with example content"
echo " - 226+ content elements"
echo " - Multi-language support (EN, DE, DA)"
echo " - Bootstrap Package theme"
echo ""
echo "Access your demo site at:"
echo " Frontend: https://${DDEV_SITENAME}.ddev.site/"
echo " Backend: https://${DDEV_SITENAME}.ddev.site/typo3/"

View File

@@ -0,0 +1,34 @@
# Redis configuration for TYPO3
# Add this to your TYPO3 AdditionalConfiguration.php or settings.php
# For TYPO3 v11/v12/v13 - AdditionalConfiguration.php
# Located at: /var/www/html/v13/config/system/additional.php
<?php
# Redis Cache Configuration
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['pages'] = [
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
'options' => [
'hostname' => 'redis',
'database' => 0,
'port' => 6379,
],
];
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['pagesection'] = [
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
'options' => [
'hostname' => 'redis',
'database' => 1,
'port' => 6379,
],
];
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['rootline'] = [
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
'options' => [
'hostname' => 'redis',
'database' => 2,
'port' => 6379,
],
];

View File

@@ -0,0 +1,31 @@
name: {{DDEV_SITENAME}}
type: php
docroot: ""
no_project_mount: true
php_version: "8.2"
composer_version: "2"
webserver_type: apache-fpm
router_http_port: "80"
router_https_port: "443"
xdebug_enabled: false
additional_hostnames:
- docs.{{DDEV_SITENAME}}
- v11.{{DDEV_SITENAME}}
- v12.{{DDEV_SITENAME}}
- v13.{{DDEV_SITENAME}}
additional_fqdns: []
use_dns_when_possible: true
webimage_extra_dockerfiles:
- web-build
hooks:
post-start:
- exec-host: |
# Capture git info and write to container automatically on every ddev start
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
COMMIT=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")
PR=$(gh pr view --json number -q .number 2>/dev/null || echo "unknown")
# Write git info as JSON to web container
ddev exec "printf '{\"branch\":\"%s\",\"commit\":\"%s\",\"pr\":\"%s\"}' '$BRANCH' '$COMMIT' '$PR' > /var/www/html/.git-info.json"
echo "📋 Git info updated: Branch=$BRANCH, Commit=$COMMIT, PR=$PR"

View File

@@ -0,0 +1,9 @@
# Docker Compose override to pass git information to web container build
# This allows the landing page to display current branch, commit, and PR info
services:
web:
build:
args:
GIT_BRANCH: "{{GIT_BRANCH}}"
GIT_COMMIT: "{{GIT_COMMIT}}"
GIT_PR: "{{GIT_PR}}"

View File

@@ -0,0 +1,24 @@
# Ofelia configuration for TYPO3 scheduler jobs
# This runs the TYPO3 scheduler every minute
# Uses ghcr.io/netresearch/ofelia (TYPO3-optimized fork)
services:
web:
labels:
# Run TYPO3 scheduler every minute for all versions
ofelia.job-exec.typo3-scheduler-v11.schedule: "@every 1m"
ofelia.job-exec.typo3-scheduler-v11.command: "bash -c 'cd /var/www/html/v11 && [ -f vendor/bin/typo3 ] && vendor/bin/typo3 scheduler:run || true'"
ofelia.job-exec.typo3-scheduler-v11.no-overlap: "true"
ofelia.job-exec.typo3-scheduler-v12.schedule: "@every 1m"
ofelia.job-exec.typo3-scheduler-v12.command: "bash -c 'cd /var/www/html/v12 && [ -f vendor/bin/typo3 ] && vendor/bin/typo3 scheduler:run || true'"
ofelia.job-exec.typo3-scheduler-v12.no-overlap: "true"
ofelia.job-exec.typo3-scheduler-v13.schedule: "@every 1m"
ofelia.job-exec.typo3-scheduler-v13.command: "bash -c 'cd /var/www/html/v13 && [ -f vendor/bin/typo3 ] && vendor/bin/typo3 scheduler:run || true'"
ofelia.job-exec.typo3-scheduler-v13.no-overlap: "true"
# Optional: Clear cache every hour
ofelia.job-exec.cache-warmup-v13.schedule: "@every 1h"
ofelia.job-exec.cache-warmup-v13.command: "bash -c 'cd /var/www/html/v13 && vendor/bin/typo3 cache:warmup || true'"
ofelia.job-exec.cache-warmup-v13.no-overlap: "true"

View File

@@ -0,0 +1,62 @@
services:
# Redis 7 for TYPO3 caching (alternative to Valkey for legacy production parity)
# See docs/adr/0001-valkey-default-with-redis-alternative.md for context
#
# Use this template if:
# - Your production environment explicitly uses Redis 7.x
# - Corporate policy requires battle-tested technology only
# - You need exact production-development parity with existing infrastructure
#
# To use this instead of Valkey:
# 1. Copy this file: cp docker-compose.services-redis.yaml.optional docker-compose.services.yaml
# 2. Restart DDEV: ddev restart
redis:
container_name: ddev-${DDEV_SITENAME}-redis
image: redis:7-alpine
restart: unless-stopped
ports:
- "6379"
volumes:
- redis-data:/data
labels:
com.ddev.site-name: ${DDEV_SITENAME}
com.ddev.approot: $DDEV_APPROOT
environment:
- REDIS_MAXMEMORY=256mb
- REDIS_MAXMEMORY_POLICY=allkeys-lru
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
# MailPit for email testing
mailpit:
container_name: ddev-${DDEV_SITENAME}-mailpit
image: axllent/mailpit:latest
restart: unless-stopped
ports:
- "1025" # SMTP port
- "8025" # Web UI port
labels:
com.ddev.site-name: ${DDEV_SITENAME}
com.ddev.approot: $DDEV_SITENAME
environment:
MP_SMTP_BIND_ADDR: 0.0.0.0:1025
MP_UI_BIND_ADDR: 0.0.0.0:8025
# Ofelia for cron jobs (TYPO3 scheduler)
ofelia:
container_name: ddev-${DDEV_SITENAME}-ofelia
image: ghcr.io/netresearch/ofelia:latest
restart: unless-stopped
depends_on:
- web
labels:
com.ddev.site-name: ${DDEV_SITENAME}
com.ddev.approot: $DDEV_APPROOT
ofelia.enabled: "true"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- .:/src
command: daemon --docker-events
volumes:
redis-data:
name: "${DDEV_SITENAME}-redis-data"

View File

@@ -0,0 +1,54 @@
services:
# Valkey for TYPO3 caching (open source, wire-compatible with Redis)
# See docs/adr/0001-valkey-default-with-redis-alternative.md for rationale
# For Redis 7 alternative, see templates/docker-compose.services-redis.yaml.optional
valkey:
container_name: ddev-${DDEV_SITENAME}-valkey
image: valkey/valkey:8-alpine
restart: unless-stopped
ports:
- "6379"
volumes:
- valkey-data:/data
labels:
com.ddev.site-name: ${DDEV_SITENAME}
com.ddev.approot: $DDEV_APPROOT
environment:
- VALKEY_MAXMEMORY=256mb
- VALKEY_MAXMEMORY_POLICY=allkeys-lru
command: valkey-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
# MailPit for email testing
mailpit:
container_name: ddev-${DDEV_SITENAME}-mailpit
image: axllent/mailpit:latest
restart: unless-stopped
ports:
- "1025" # SMTP port
- "8025" # Web UI port
labels:
com.ddev.site-name: ${DDEV_SITENAME}
com.ddev.approot: $DDEV_SITENAME
environment:
MP_SMTP_BIND_ADDR: 0.0.0.0:1025
MP_UI_BIND_ADDR: 0.0.0.0:8025
# Ofelia for cron jobs (TYPO3 scheduler)
ofelia:
container_name: ddev-${DDEV_SITENAME}-ofelia
image: ghcr.io/netresearch/ofelia:latest
restart: unless-stopped
depends_on:
- web
labels:
com.ddev.site-name: ${DDEV_SITENAME}
com.ddev.approot: $DDEV_APPROOT
ofelia.enabled: "true"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- .:/src
command: daemon --docker-events
volumes:
valkey-data:
name: "${DDEV_SITENAME}-valkey-data"

View File

@@ -0,0 +1,44 @@
services:
web:
environment:
- EXTENSION_KEY={{EXTENSION_KEY}}
- PACKAGE_NAME={{PACKAGE_NAME}}
# TYPO3 v11 and v12 config
- TYPO3_INSTALL_DB_DRIVER=mysqli
- TYPO3_INSTALL_DB_USER=root
- TYPO3_INSTALL_DB_PASSWORD=root
- TYPO3_INSTALL_DB_HOST=db
- TYPO3_INSTALL_DB_UNIX_SOCKET=
- TYPO3_INSTALL_DB_USE_EXISTING=0
- TYPO3_INSTALL_ADMIN_USER=admin
- TYPO3_INSTALL_ADMIN_PASSWORD=Password:joh316
- TYPO3_INSTALL_SITE_NAME=EXT:{{EXTENSION_KEY}} Dev Environment
- TYPO3_INSTALL_SITE_SETUP_TYPE=site
- TYPO3_INSTALL_WEB_SERVER_CONFIG=apache
# TYPO3 v13 config
- TYPO3_DB_DRIVER=mysqli
- TYPO3_DB_USERNAME=root
- TYPO3_DB_PASSWORD=root
- TYPO3_DB_HOST=db
- TYPO3_SETUP_ADMIN_EMAIL=admin@example.com
- TYPO3_SETUP_ADMIN_USERNAME=admin
- TYPO3_SETUP_ADMIN_PASSWORD=Password:joh316
- TYPO3_PROJECT_NAME=EXT:{{EXTENSION_KEY}} Dev Environment
- TYPO3_SERVER_TYPE=apache
volumes:
- type: bind
source: ../
target: /var/www/{{EXTENSION_KEY}}
consistency: cached
- v11-data:/var/www/html/v11
- v12-data:/var/www/html/v12
- v13-data:/var/www/html/v13
volumes:
v11-data:
name: "${DDEV_SITENAME}-v11-data"
v12-data:
name: "${DDEV_SITENAME}-v12-data"
v13-data:
name: "${DDEV_SITENAME}-v13-data"

View File

@@ -0,0 +1,15 @@
# TYPO3 Scheduler Aliases
alias t3-scheduler-v11='cd /var/www/html/v11 && vendor/bin/typo3 scheduler:run'
alias t3-scheduler-v12='cd /var/www/html/v12 && vendor/bin/typo3 scheduler:run'
alias t3-scheduler-v13='cd /var/www/html/v13 && vendor/bin/typo3 scheduler:run'
alias t3-scheduler-all='t3-scheduler-v11 && t3-scheduler-v12 && t3-scheduler-v13'
# Redis CLI access
alias redis='redis-cli -h redis'
# Cache management
alias t3-cache-flush-v13='cd /var/www/html/v13 && vendor/bin/typo3 cache:flush'
alias t3-cache-warmup-v13='cd /var/www/html/v13 && vendor/bin/typo3 cache:warmup'
# Quick TYPO3 commands
alias t3='cd /var/www/html/v13 && vendor/bin/typo3'

View File

@@ -0,0 +1,215 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{EXTENSION_NAME}} - TYPO3 Development Environment</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container {
background: white;
border-radius: 16px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
max-width: 900px;
width: 100%;
padding: 40px;
}
h1 {
color: #2d3748;
font-size: 2.5em;
margin-bottom: 10px;
text-align: center;
}
.subtitle {
color: #718096;
text-align: center;
margin-bottom: 40px;
font-size: 1.1em;
}
.versions {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.version-card {
border: 2px solid #e2e8f0;
border-radius: 12px;
padding: 25px;
transition: all 0.3s ease;
}
.version-card:hover {
border-color: #667eea;
transform: translateY(-2px);
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.2);
}
.version-title {
color: #2d3748;
font-size: 1.5em;
font-weight: 600;
margin-bottom: 15px;
display: flex;
align-items: center;
}
.version-badge {
background: #667eea;
color: white;
padding: 4px 12px;
border-radius: 6px;
font-size: 0.7em;
margin-left: 10px;
}
.links {
display: flex;
flex-direction: column;
gap: 10px;
}
.link {
display: inline-flex;
align-items: center;
padding: 12px 16px;
background: #f7fafc;
border-radius: 8px;
text-decoration: none;
color: #4a5568;
transition: all 0.2s ease;
font-weight: 500;
}
.link:hover {
background: #667eea;
color: white;
transform: translateX(5px);
}
.link-icon {
margin-right: 10px;
font-size: 1.2em;
}
.info-section {
background: #f7fafc;
border-radius: 12px;
padding: 20px;
margin-top: 30px;
}
.info-title {
color: #2d3748;
font-size: 1.2em;
font-weight: 600;
margin-bottom: 15px;
}
.info-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 15px;
}
.info-item {
display: flex;
flex-direction: column;
}
.info-label {
color: #718096;
font-size: 0.9em;
margin-bottom: 5px;
}
.info-value {
color: #2d3748;
font-weight: 600;
font-family: 'Courier New', monospace;
}
.tools {
margin-top: 20px;
padding-top: 20px;
border-top: 2px solid #e2e8f0;
}
.tool-link {
display: inline-block;
padding: 10px 20px;
background: #48bb78;
color: white;
text-decoration: none;
border-radius: 8px;
margin-right: 10px;
margin-bottom: 10px;
transition: all 0.2s ease;
}
.tool-link:hover {
background: #38a169;
transform: translateY(-2px);
}
@media (max-width: 768px) {
.versions {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<div class="container">
<h1>🚀 {{EXTENSION_NAME}}</h1>
<p class="subtitle">Development Environment - Multi-Version Testing</p>
<div class="versions">
<div class="version-card">
<div class="version-title">
TYPO3 v12
<span class="version-badge">LTS</span>
</div>
<div class="links">
<a href="https://v12.{{DDEV_PROJECT}}.ddev.site/" class="link">
<span class="link-icon">🌐</span>
Frontend
</a>
<a href="https://v12.{{DDEV_PROJECT}}.ddev.site/typo3/" class="link">
<span class="link-icon">🔧</span>
Backend
</a>
</div>
</div>
<div class="version-card">
<div class="version-title">
TYPO3 v13
<span class="version-badge">LTS</span>
</div>
<div class="links">
<a href="https://v13.{{DDEV_PROJECT}}.ddev.site/" class="link">
<span class="link-icon">🌐</span>
Frontend
</a>
<a href="https://v13.{{DDEV_PROJECT}}.ddev.site/typo3/" class="link">
<span class="link-icon">🔧</span>
Backend
</a>
</div>
</div>
</div>
<div class="info-section">
<div class="info-title">📋 Backend Access</div>
<div class="info-grid">
<div class="info-item">
<div class="info-label">Username</div>
<div class="info-value">admin</div>
</div>
<div class="info-item">
<div class="info-label">Password</div>
<div class="info-value">Password:joh316</div>
</div>
</div>
<div class="tools">
<div class="info-title">🛠️ Development Tools</div>
<a href="https://{{DDEV_PROJECT}}.ddev.site:8026/" class="tool-link">📧 Mailpit</a>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,141 @@
ARG BASE_IMAGE
FROM $BASE_IMAGE
ENV EXTENSION_KEY "{{EXTENSION_KEY}}"
ENV DDEV_SITENAME "{{DDEV_SITENAME}}"
ENV GITHUB_URL "{{GITHUB_URL}}"
# Remove default Apache index.html and create PHP-based landing page
RUN rm -f /var/www/html/index.html
RUN cat > /var/www/html/index.php << 'PHPEOF'
<?php
// Get git info from runtime file (updated automatically on each ddev start)
$gitInfoFile = '/var/www/html/.git-info.json';
$gitInfo = file_exists($gitInfoFile) ? json_decode(file_get_contents($gitInfoFile), true) : [];
$gitBranch = $gitInfo['branch'] ?? 'unknown';
$gitCommit = $gitInfo['commit'] ?? 'unknown';
$prNumber = isset($gitInfo['pr']) && $gitInfo['pr'] !== 'unknown' ? $gitInfo['pr'] : null;
$githubUrl = '{{GITHUB_URL}}';
$branchUrl = $githubUrl && $gitBranch !== 'unknown' ? $githubUrl . '/tree/' . urlencode($gitBranch) : null;
$prUrl = $githubUrl && $prNumber ? $githubUrl . '/pull/' . $prNumber : null;
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>EXT:{{EXTENSION_KEY}} - DDEV Environment</title>
<style>
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;max-width:900px;margin:50px auto;padding:0 20px;line-height:1.6;color:#333;background:#f5f5f5}
.container{background:#fff;padding:40px;border-radius:8px;box-shadow:0 2px 10px rgba(0,0,0,0.1)}
h1{color:#ff8700;border-bottom:3px solid #ff8700;padding-bottom:10px;margin-bottom:10px}
.git-info{font-size:0.85em;color:#666;margin-bottom:30px;padding:10px;background:#f9f9f9;border-radius:4px}
.git-info a{color:#0078e7;text-decoration:none;font-weight:500}
.git-info a:hover{text-decoration:underline}
.git-info .separator{margin:0 8px;color:#ccc}
h2{color:#666;margin-top:30px;margin-bottom:15px;font-size:1.3em}
.card{background:#f9f9f9;border-left:4px solid #ff8700;padding:20px;margin:15px 0;border-radius:4px}
.card h3{margin-top:0;color:#ff8700}
a{color:#0078e7;text-decoration:none;font-weight:500}
a:hover{text-decoration:underline}
code{background:#eee;padding:2px 6px;border-radius:3px;font-family:monospace;font-size:0.9em}
.links{display:flex;gap:15px;margin-top:10px;flex-wrap:wrap}
.btn{display:inline-block;padding:10px 20px;background:#0078e7;color:#fff!important;border-radius:4px;text-decoration:none;transition:background 0.3s}
.btn:hover{background:#0056b3;text-decoration:none}
.btn-docs{background:#ff8700}
.btn-docs:hover{background:#e67700}
ul{list-style:none;padding:0}
li{padding:5px 0}
.version-card{margin:10px 0}
</style>
</head>
<body>
<div class="container">
<h1>🚀 EXT:{{EXTENSION_KEY}} Development Environment</h1>
<?php if ($gitBranch !== 'unknown' || $prNumber): ?>
<div class="git-info">
<?php if ($branchUrl): ?>
<a href="<?= htmlspecialchars($branchUrl) ?>" target="_blank" title="View branch on GitHub">
🌿 <?= htmlspecialchars($gitBranch) ?><?php if ($gitCommit !== 'unknown'): ?> @ <?= htmlspecialchars($gitCommit) ?><?php endif; ?>
</a>
<?php elseif ($gitBranch !== 'unknown'): ?>
🌿 <?= htmlspecialchars($gitBranch) ?><?php if ($gitCommit !== 'unknown'): ?> @ <?= htmlspecialchars($gitCommit) ?><?php endif; ?>
<?php endif; ?>
<?php if ($prUrl): ?>
<span class="separator">|</span>
<a href="<?= htmlspecialchars($prUrl) ?>" target="_blank" title="View pull request">
🔀 PR #<?= htmlspecialchars($prNumber) ?>
</a>
<?php endif; ?>
</div>
<?php endif; ?>
<div class="card">
<h3>📚 Documentation</h3>
<p>View the extension documentation (run <code>ddev docs</code> to render):</p>
<a href="https://docs.{{DDEV_SITENAME}}.ddev.site/" class="btn btn-docs">View Documentation</a>
</div>
<div class="card">
<h3>🌐 TYPO3 Environments</h3>
<div class="version-card">
<strong>TYPO3 11.5 LTS</strong>
<div class="links">
<a href="https://v11.{{DDEV_SITENAME}}.ddev.site/" class="btn">Frontend</a>
<a href="https://v11.{{DDEV_SITENAME}}.ddev.site/typo3/" class="btn">Backend</a>
</div>
</div>
<div class="version-card">
<strong>TYPO3 12.4 LTS</strong>
<div class="links">
<a href="https://v12.{{DDEV_SITENAME}}.ddev.site/" class="btn">Frontend</a>
<a href="https://v12.{{DDEV_SITENAME}}.ddev.site/typo3/" class="btn">Backend</a>
</div>
</div>
<div class="version-card">
<strong>TYPO3 13.4 LTS</strong>
<div class="links">
<a href="https://v13.{{DDEV_SITENAME}}.ddev.site/" class="btn">Frontend</a>
<a href="https://v13.{{DDEV_SITENAME}}.ddev.site/typo3/" class="btn">Backend</a>
</div>
</div>
</div>
<div class="card">
<h3>🔑 Backend Credentials</h3>
<ul>
<li><strong>Username:</strong> <code>admin</code></li>
<li><strong>Password:</strong> <code>Password:joh316</code></li>
<li><em>(also works for Install Tool)</em></li>
</ul>
</div>
<div class="card">
<h3>⚙️ Quick Commands</h3>
<ul>
<li><code>ddev setup</code> - <strong>Complete setup (all-in-one)</strong></li>
<li><code>ddev docs</code> - Render documentation</li>
<li><code>ddev install-v11</code> - Install TYPO3 11.5 LTS</li>
<li><code>ddev install-v12</code> - Install TYPO3 12.4 LTS</li>
<li><code>ddev install-v13</code> - Install TYPO3 13.4 LTS</li>
<li><code>ddev install-all</code> - Install all TYPO3 versions</li>
</ul>
</div>
</div>
</body>
</html>
PHPEOF
RUN mkdir -p /var/www/html/v11/public/typo3
RUN echo "<h1>Perform this first</h1> <code>ddev install-v11</code>" > /var/www/html/v11/public/index.html
RUN echo "<h1>Perform this first</h1> <code>ddev install-v11</code>" > /var/www/html/v11/public/typo3/index.html
RUN mkdir -p /var/www/html/v12/public/typo3
RUN echo "<h1>Perform this first</h1> <code>ddev install-v12</code>" > /var/www/html/v12/public/index.html
RUN echo "<h1>Perform this first</h1> <code>ddev install-v12</code>" > /var/www/html/v12/public/typo3/index.html
RUN mkdir -p /var/www/html/v13/public/typo3
RUN echo "<h1>Perform this first</h1> <code>ddev install-v13</code>" > /var/www/html/v13/public/index.html
RUN echo "<h1>Perform this first</h1> <code>ddev install-v13</code>" > /var/www/html/v13/public/typo3/index.html
ARG uid
ARG gid
RUN chown -R $uid:$gid /var/www/html

View File

@@ -0,0 +1,20 @@
#!/bin/bash
# Install cron in web container (alternative to Ofelia)
# This script sets up traditional cron jobs in the web container
cat > /etc/cron.d/typo3-scheduler << 'EOF'
# TYPO3 Scheduler - runs every minute for all versions
* * * * * www-data cd /var/www/html/v11 && [ -f vendor/bin/typo3 ] && vendor/bin/typo3 scheduler:run > /dev/null 2>&1
* * * * * www-data cd /var/www/html/v12 && [ -f vendor/bin/typo3 ] && vendor/bin/typo3 scheduler:run > /dev/null 2>&1
* * * * * www-data cd /var/www/html/v13 && [ -f vendor/bin/typo3 ] && vendor/bin/typo3 scheduler:run > /dev/null 2>&1
# Optional: Cache warmup every hour
0 * * * * www-data cd /var/www/html/v13 && vendor/bin/typo3 cache:warmup > /dev/null 2>&1
EOF
chmod 0644 /etc/cron.d/typo3-scheduler
crontab /etc/cron.d/typo3-scheduler
# Start cron daemon
service cron start

View File

@@ -0,0 +1,246 @@
# TYPO3 DDEV Skill Refactoring Summary
## Overview
Refactored `SKILL.md` to follow skill-creator best practices, converting documentation-style sections into imperative directives that guide Claude's actions rather than describing what the skill does.
## Skill-Creator Best Practices Applied
### 1. Imperative/Infinitive Form
**Principle**: Write instructions using verb-first, objective language (e.g., "To accomplish X, do Y") instead of second-person or descriptive language.
**Before**: "Common issues and their solutions are documented..."
**After**: "When encountering errors during setup or installation..."
### 2. Action-Oriented Instructions
**Principle**: Focus on WHAT to do and WHEN to do it, not just WHAT exists.
**Before**: "The script validates: Docker daemon status, Docker CLI version..."
**After**: "Run validation script: Execute `scripts/validate-prerequisites.sh` to check..."
### 3. Integration Over Documentation
**Principle**: Integrate communication guidelines into workflow steps instead of having separate style guides.
**Before**: Separate "Communication Style" section listing style rules
**After**: "Output Formatting Guidelines" section with actionable instructions
## Detailed Changes
### Section 1: Prerequisites Validation (lines 41-56)
**Changes Made**:
- Converted from descriptive ("The script validates:") to imperative ("Run validation script: Execute...")
- Changed "For detailed prerequisite information including:" to "If validation fails: Consult..."
- Added explicit action: "Report results: Display validation status..."
**Why**: The original described what prerequisites exist; the refactored version instructs Claude on HOW to validate and WHAT to do if validation fails.
---
### Section 2: Error Handling (lines 514-524)
**Original Structure**:
```markdown
## Error Handling
Common issues and their solutions are documented in the troubleshooting guide.
**Most frequent issues:**
- Prerequisites not met
- Port conflicts
- TYPO3 installation failures
See: `references/troubleshooting.md`
```
**Refactored Structure**:
```markdown
## Error Handling
When encountering errors during setup or installation:
1. Check error category: Identify if the error relates to...
2. Consult troubleshooting guide: Read `references/troubleshooting.md`...
3. Apply recommended solution: Follow the step-by-step resolution guide...
4. For Windows/WSL2 environments: If error persists on Windows, consult...
Report the error to the user with the specific solution being applied...
```
**Why**: Original listed what errors exist (descriptive). Refactored version instructs when and how to handle errors (imperative).
---
### Section 3: Advanced Configuration (lines 526-536)
**Original Structure**:
```markdown
## Advanced Options
For advanced configuration and optional features, see the comprehensive guide.
**Available customizations:**
- Custom PHP versions
- Intelligent database selection
- XDebug setup
See: `references/advanced-options.md`
```
**Refactored Structure**:
```markdown
## Advanced Configuration
When user requests customizations beyond the standard setup:
1. Identify customization type: Determine if request involves...
2. Consult advanced options guide: Read `references/advanced-options.md`...
3. Present options to user: Show available choices...
4. Apply configuration: Follow the templates and instructions...
Offer customization options proactively when user mentions...
```
**Why**: Original described what options exist. Refactored version instructs WHEN to offer customizations and HOW to apply them.
---
### Section 4: Demo Content (lines 564-578)
**Changes Made**:
- Changed from "The Introduction Package provides..." to "When discussing testing capabilities with users, inform them that..."
- Changed "What's Included:" bullet list to active voice with purpose (e.g., "for testing navigation")
- Changed "Access:" to "Direct users to test their extension against this demo content at:"
**Why**: Instructs Claude on WHEN to mention demo content and HOW to direct users to it, rather than just listing what exists.
---
### Section 5: Extension Auto-Configuration (lines 580-612)
**Changes Made**:
- Changed "For extensions requiring..." to "When user's extension requires..."
- Changed "Use Cases for Auto-Configuration" to "Identify Configuration Needs by Extension Type"
- Converted lists from descriptive to active voice with "configure:" prefix
**Why**: Makes it clear this is guidance for Claude on identifying user needs and configuring accordingly.
---
### Section 6: Validation Checklist → Step 9: Verify Installation (lines 708-720)
**Original Structure**:
```markdown
## Validation Checklist
Before completing, verify:
- [ ] All prerequisite checks passed
- [ ] Extension metadata extracted correctly
- [ ] User confirmed configuration values
```
**Refactored Structure**:
```markdown
### Step 9: Verify Installation
After installation completes, perform these verification steps in order:
1. Confirm prerequisites passed: Review output from Step 1...
2. Verify extension metadata: Check that extracted values match...
3. Test DDEV status: Run `ddev describe` to confirm...
```
**Why**: Checkbox lists are passive todo items. Numbered imperative steps are active instructions. Also integrated this as Step 9 in the workflow for better flow.
---
### Section 7: Communication Style → Output Formatting Guidelines (lines 722-729)
**Original Structure**:
```markdown
## Communication Style
- Use clear, concise language
- Show progress indicators during long operations
- Use emojis for visual clarity
- Provide copy-pasteable commands
```
**Refactored Structure**:
```markdown
## Output Formatting Guidelines
Throughout all steps, format output for clarity:
- Use emojis for visual indicators: ✅ (success), ❌ (error)...
- Display progress indicators during operations taking >5 seconds
- Provide copy-pasteable command blocks with explanations
```
**Why**: Changed from describing a communication style to instructing how to format output. More specific and actionable.
---
### Section 8: Example Interaction (REMOVED)
**Original**: Had an "Example Interaction" section showing sample user dialogue
**Refactored**: Completely removed
**Why**: According to skill-creator best practices, skills should provide instructions for Claude, not examples of what the skill does. The Step-by-Step Workflow already demonstrates usage.
---
## Impact Summary
### What Changed
1. ✅ All major sections converted from descriptive to imperative form
2. ✅ Communication guidelines integrated into workflow
3. ✅ Removed redundant "Example Interaction" section
4. ✅ Validation checklist converted to procedural Step 9
5. ✅ Error handling and advanced options now instruct WHEN and HOW
### What Stayed the Same
- Core workflow steps (Steps 1-8)
- Configuration file templates
- Reference file structure
- Metadata (name, description, frontmatter)
### Why This Matters
**Before Refactoring**: Skill read like documentation ABOUT the skill
**After Refactoring**: Skill reads like instructions FOR Claude
This reduces confusion where Claude might output the skill's instructions verbatim to users, instead of using them as internal guidance to perform the task.
## Skill-Creator Compliance Checklist
✅ Written in imperative/infinitive form throughout
✅ Action-oriented with clear triggers (When X, do Y)
✅ References to resources include WHEN to use them
✅ No second-person language ("you should")
✅ No descriptive sections that should be directives
✅ Communication style integrated into workflow
✅ Validation converted from checklist to procedural steps
## Testing Recommendations
To verify the improvements work as intended:
1. **Invoke the skill**: Run the typo3-ddev skill on a test project
2. **Watch for output**: Claude should execute the workflow, NOT output the skill instructions
3. **Check formatting**: Output should use emojis and formatting guidelines automatically
4. **Verify error handling**: If an error occurs, Claude should consult troubleshooting.md and apply solutions
5. **Test advanced options**: Request a custom PHP version and verify Claude follows the advanced configuration workflow
## Next Steps
1. ✅ Refactoring complete
2. ⏳ Test skill with actual TYPO3 projects
3. ⏳ Gather feedback on whether Claude uses instructions correctly
4. ⏳ Iterate based on real-world usage
---
**Refactored by**: Claude Code with skill-creator skill
**Date**: 2025-11-14
**Version**: 1.5.0 → 1.6.0 (recommended version bump for major structural changes)

201
plugin.lock.json Normal file
View File

@@ -0,0 +1,201 @@
{
"$schema": "internal://schemas/plugin.lock.v1.json",
"pluginId": "gh:netresearch/claude-code-marketplace:skills/typo3-ddev",
"normalized": {
"repo": null,
"ref": "refs/tags/v20251128.0",
"commit": "6c66718fc826f9e6e3b8a5b230b64ad6ab7782f8",
"treeHash": "5b1240462b8a4ac69491bb70ff27942f81df756a2862bb5eb5430250c01419a7",
"generatedAt": "2025-11-28T10:27:19.367922Z",
"toolVersion": "publish_plugins.py@0.2.0"
},
"origin": {
"remote": "git@github.com:zhongweili/42plugin-data.git",
"branch": "master",
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
},
"manifest": {
"name": "typo3-ddev",
"description": "Set up and manage TYPO3 development environments using DDEV. Includes DDEV configuration, local development workflows, container management, database handling, and integration with TYPO3-specific tooling.",
"version": "1.6.0-20251121"
},
"content": {
"files": [
{
"path": "LICENSE",
"sha256": "ab373f9ef890455f235a4ccfab7ae7f1157d5edd45e659abae687b3b6255a8d6"
},
{
"path": "README.md",
"sha256": "70d03809baaacb1280d4005b81b19ac46a16bb4175e522c8ee32bd2817041317"
},
{
"path": ".gitignore",
"sha256": "593d792f248e0cbea5d41215b10771ad52198bc565f0f20b640e9be3eecacf53"
},
{
"path": "SKILL.md",
"sha256": "bfff69ac938e2e64d5d51056f8937eef72607a784c54f1925b711bbf04262f10"
},
{
"path": "references/windows-optimizations.md",
"sha256": "7eae23d263c5b026b183c2e42542b2efaa449ca9ad9c996768ca0c0e5cd08e5f"
},
{
"path": "references/0001-valkey-default-with-redis-alternative.md",
"sha256": "ba2b2598645132dec697fd19c7d838d503bfc22480daf5c249e105dd55be54fa"
},
{
"path": "references/windows-fixes.md",
"sha256": "e6ad59d54c2198f266f169afdf23f717d4f0865fecb95f927a93651db8904a74"
},
{
"path": "references/troubleshooting.md",
"sha256": "f242014dc3ee7088e43484aeaa79899d4afc09bd11936e28a72a6854d601a21a"
},
{
"path": "references/advanced-options.md",
"sha256": "91a5afc978a25e97208b781781f0eaeb08b11b8ee92db64f9d4e37caaa46200b"
},
{
"path": "references/prerequisites-validation.md",
"sha256": "cf809654a94cb872202843b9f4a95d9f3b1ae6dfeb1efa9d0b6569f11d0b1d42"
},
{
"path": "references/quickstart.md",
"sha256": "cc7ebde884323fcae12df2699dcdcf1e140b0b62117a8f7658dcc42fa3c68b34"
},
{
"path": "references/index-page-generation.md",
"sha256": "a667a23a99423bcdb1b6ee3c6e5782c4717dd679292b85af9dcbe321ca98cac7"
},
{
"path": "references/0002-mariadb-default-with-database-alternatives.md",
"sha256": "aec6ece3c744066b63023e40df82369e0719a99e988a2014414602f21cc16b21"
},
{
"path": "claudedocs/skill-refactoring-summary.md",
"sha256": "382d6d27e41b5395ddf31134f6d2ae787f761bb4870ac2e22a770a3846eb6a6c"
},
{
"path": "scripts/validate-prerequisites.sh",
"sha256": "5c1401510f9986e343749a56a8fa64f8046946637362848284748e4fb8aa01b3"
},
{
"path": ".claude-plugin/plugin.json",
"sha256": "a00b247ab69ffb08bdc5d4c5eb1dde0ec1a7802c73d434f74ca876c60dbcb077"
},
{
"path": "assets/templates/docker-compose.git-info.yaml",
"sha256": "c88eec7b034e5ff2c59e2bc4f1f99da7b768a8c917f8f53437786031c0891825"
},
{
"path": "assets/templates/config.redis.php.example",
"sha256": "d30b42cedfa7e6b1939518d91ff9a85959d137bb56ecae0616982917f7b07fbc"
},
{
"path": "assets/templates/.envrc",
"sha256": "35911511432d6c5fbbd00dc9b1f25d17658e30ddf1a44cd8da17b3c0d4e75cb6"
},
{
"path": "assets/templates/docker-compose.web.yaml",
"sha256": "703079576c5a3c970d3dedec4968de4391654f34834f7d1c36b3c4b147b6f23f"
},
{
"path": "assets/templates/Makefile.template",
"sha256": "d39015650acc88a43f89983de4cb141766f92bbf921269f439da53615b372986"
},
{
"path": "assets/templates/docker-compose.ofelia.yaml.optional",
"sha256": "b664d9d7b69c3ce7855603e1fa2c77f930a447a73fcfdfaceb845c24242f0b4b"
},
{
"path": "assets/templates/index.html.template",
"sha256": "b3c905e7b64dc1284ec8f5013c04e9c12180f75031d69232694538c601828bcf"
},
{
"path": "assets/templates/config.yaml",
"sha256": "3a83be64a83f6e50aedca7320c31e6a80612d12b3e65b1569324906ec1cc31f6"
},
{
"path": "assets/templates/README-SERVICES.md.optional",
"sha256": "20f1d7379ff9115b53187154b3afcab6dab2bc81811b5392a81c02a9cf6bbafa"
},
{
"path": "assets/templates/docker-compose.services.yaml.optional",
"sha256": "fd2a75d4b5c2861367dd0e63cf09e9be31a52f5c4990d38c21d6471bb3a44fe1"
},
{
"path": "assets/templates/docker-compose.services-redis.yaml.optional",
"sha256": "564fde7771013bc18808dde014e29621c68c826ef07f8957482ab6b1d31c0ccc"
},
{
"path": "assets/templates/web-build/install-cron.sh.optional",
"sha256": "ef1cba4123b9df86aedb15509c393e198300cf2ae92cb9aef4b5e3284af8ca00"
},
{
"path": "assets/templates/web-build/Dockerfile",
"sha256": "518c5065f73bdf796d412efd84db4192fe6c486c08741d576a144cc82755a436"
},
{
"path": "assets/templates/homeadditions/.bashrc_additions.optional",
"sha256": "5b8046dbf3974f89227b3f8d87bf4089183333a3c83f454925c5fdb340e8bbf9"
},
{
"path": "assets/templates/commands/install-v11",
"sha256": "6e80f13afd7b64883db9539c9d79d8443b0d134cf8bd7f78520a8f6cbf337689"
},
{
"path": "assets/templates/commands/install-v13",
"sha256": "f87b775f3822318876d0db63c78cbc8dad48e4e37f61d7958ae76ac90a81d9ce"
},
{
"path": "assets/templates/commands/install-v12",
"sha256": "f50abab5b2e0446d5a5da6dce3f4b6d801e9823773b435df19f17a349f8f3a7a"
},
{
"path": "assets/templates/commands/install-all",
"sha256": "2ba13bf400536925fc9e9faba5127031423e8ba32feed76a643c8343bb79e922"
},
{
"path": "assets/templates/commands/host/setup",
"sha256": "a4dfdd5540a4662e58f125e4ca72b685d783a50275971d23bbf5c95b1240038f"
},
{
"path": "assets/templates/commands/host/docs",
"sha256": "13545bb03d87dd11dba24131753b66db758862c96986df40f48555f7d4786908"
},
{
"path": "assets/templates/commands/host/pre-start-git-info",
"sha256": "1579befd98de8d00ad8d62b7d96b4ec36a0d7fe97084dc55761e100d56f876c2"
},
{
"path": "assets/templates/commands/web/generate-index",
"sha256": "3ad42122b0c027a1a9b028af3fda855518f15763c7aa5adfc6bc4d996f3b7bd6"
},
{
"path": "assets/templates/commands/web/configure-extension.optional",
"sha256": "400cdb85bf7ef285556e6d337e25e4636a8bb4dbb222fcb1672f3374f19e404e"
},
{
"path": "assets/templates/commands/web/generate-makefile",
"sha256": "8fee0d248e9b63e86a4a8fa29f0c5b121cd22ead08f12287e827a114d45fc664"
},
{
"path": "assets/templates/commands/web/install-introduction.optional",
"sha256": "3f2a8f3605795cdd69b52760a8c2c9952c38fcfcf267815490deb1b7c4bb58ed"
},
{
"path": "assets/templates/apache/apache-site.conf",
"sha256": "f40f09c69e02e8855fc30416a55bd3059ddedfbb2a727c853d7a89f00d5cbd60"
}
],
"dirSha256": "5b1240462b8a4ac69491bb70ff27942f81df756a2862bb5eb5430250c01419a7"
},
"security": {
"scannedAt": null,
"scannerVersion": null,
"flags": []
}
}

View File

@@ -0,0 +1,414 @@
# ADR 0001: Default to Valkey with Redis Alternative
**Status:** Accepted
**Date:** 2025-10-22
**Decision Makers:** TYPO3 DDEV Skill Maintainers
**Tags:** #caching #infrastructure #licensing #future-proofing
---
## Context
### The Redis Licensing Change (March 2024)
Redis changed its license from BSD-3-Clause (open source) to a dual RSALv2/SSPLv1 license, which is NOT OSI-approved open source. This change:
- Restricts commercial use of Redis as a managed service
- Creates legal compliance concerns for cloud providers and hosting companies
- Prevents offering Redis-as-a-service without Redis Ltd licensing agreements
### The Valkey Fork (March 2024)
In response, the Linux Foundation launched Valkey, a fork of Redis 7.2.4, with backing from:
- Amazon Web Services (AWS)
- Google Cloud
- Oracle Cloud
- Ericsson
- Snap Inc.
- 40+ additional companies
Valkey maintains BSD-3-Clause licensing (true open source) and wire-protocol compatibility with Redis.
### Cloud Provider Adoption
**AWS ElastiCache** (October 2024):
- Added Valkey 7.2 support
- Added Valkey 8.0 support (November 2024)
- Pricing: 20% lower for node-based, 33% lower for serverless vs Redis
- Performance: Claims 230% higher throughput, 70% better latency (Valkey 8.0 vs 7.2)
**Industry Trajectory:**
- AWS MemoryDB supports Valkey
- Google Cloud and Oracle are Valkey project sponsors
- Economic pressure (20-33% cost savings) will drive hosting provider migration
### TYPO3 Caching Requirements
TYPO3's Redis cache backend uses basic operations:
- `GET`, `SET`, `DEL`, `EXPIRE` - Key-value operations
- `FLUSHDB` - Cache clearing
- `KEYS` pattern matching - Cache inspection
These operations are **identical** in Redis and Valkey (wire-protocol compatible). TYPO3 does not use advanced Redis features (Streams, JSON, Search, etc.).
### DDEV Development Environment Context
The TYPO3 DDEV Skill provides a reference implementation for local development environments. Developers using this skill:
- Test TYPO3 extensions locally before production deployment
- Do not control production infrastructure (clients/hosting providers do)
- Need development environments that match future production reality
- Benefit from faster Docker image pulls (smaller images = faster `ddev start`)
---
## Decision
**Default to Valkey 8-alpine for new TYPO3 DDEV projects, with Redis 7-alpine as a documented alternative.**
### Implementation Details
#### Default Configuration
```yaml
# .ddev/docker-compose.services.yaml (new projects)
services:
valkey:
container_name: ddev-${DDEV_SITENAME}-valkey
image: valkey/valkey:8-alpine
restart: unless-stopped
ports:
- "6379"
volumes:
- valkey-data:/data
environment:
- VALKEY_MAXMEMORY=256mb
- VALKEY_MAXMEMORY_POLICY=allkeys-lru
command: valkey-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
valkey-data:
name: "${DDEV_SITENAME}-valkey-data"
```
#### Alternative: Redis 7-alpine
```yaml
# Alternative for legacy production parity
services:
redis:
container_name: ddev-${DDEV_SITENAME}-redis
image: redis:7-alpine
# ... same configuration structure
```
#### Auto-Detection Logic
For existing projects with `.ddev/docker-compose.services.yaml`:
- **Preserve existing choice**: If Redis is detected, keep Redis
- **Preserve existing choice**: If Valkey is detected, keep Valkey
- **Inform user**: Log which cache service was detected and preserved
For new projects:
- **Default to Valkey 8-alpine**
- **Document Redis alternative**: Show how to switch in generated README
- **Provide rationale**: Explain why Valkey is the forward-looking choice
---
## Consequences
### Positive
**Future-Proof Development Environments**
- Matches the production trajectory (AWS/Google/Oracle adoption)
- Prepares developers for 2025-2027 hosting landscape
- Reduces future migration friction when hosting providers switch
**Cost Awareness**
- Educates developers about cost-effective infrastructure choices
- Aligns with hosting provider economic incentives (20-33% savings)
- Demonstrates modern cloud architecture patterns
**True Open Source**
- BSD-3-Clause license with no commercial restrictions
- No legal compliance concerns for hosting providers
- Community-driven governance (Linux Foundation)
**Smaller Docker Images**
- Valkey 8-alpine: **69.7 MB**
- Redis 8-alpine: 100 MB (30% larger)
- Redis 7-alpine: 60.6 MB
- Faster `ddev start` cycles during development
**Drop-In Compatibility**
- Wire-protocol identical to Redis
- TYPO3's PHP redis extension works without modification
- Zero code changes required for TYPO3 extensions
- Easy rollback to Redis if needed (one-line change)
### Negative
⚠️ **Newer Codebase**
- Valkey fork is only 1 year old (since March 2024)
- Less Stack Overflow content compared to Redis
- Potential for undiscovered edge-case bugs
**Mitigation:**
- Based on Redis 7.2.4 (stable, battle-tested codebase)
- AWS/Google/Oracle using in production validates stability
- DDEV makes switching back to Redis trivial (one-line change)
- Redis documentation applies due to protocol compatibility
⚠️ **Learning Curve**
- Developers familiar with "Redis" terminology need to learn "Valkey"
- Some confusion about naming/branding
**Mitigation:**
- Comprehensive ADR and documentation explains context
- Clear instructions for both Valkey and Redis alternatives
- Educational opportunity to teach open source licensing issues
⚠️ **Current Production Mismatch**
- Some existing TYPO3 hosting environments still use Redis 7.x
- Development-production parity temporarily impacted
**Mitigation:**
- Redis 7-alpine documented as alternative for production parity
- Auto-detection preserves existing Redis choice in projects
- Easy to switch (one-line change in docker-compose)
- Trade-off: Match today's production vs prepare for tomorrow's
### Risks and Mitigations
| Risk | Severity | Likelihood | Mitigation |
|------|----------|------------|------------|
| Valkey compatibility issues with TYPO3 | Low | Very Low | Wire-protocol identical, PHP redis extension works transparently |
| Valkey bugs in production use | Medium | Low | AWS/Google production usage validates stability; easy rollback |
| Developer confusion/resistance | Low | Medium | Clear documentation, explain rationale, provide Redis alternative |
| Community backlash for being "too progressive" | Low | Low | Document decision thoroughly, auto-preserve existing choices |
---
## Alternatives Considered
### Alternative 1: Redis 7-alpine Default (Conservative)
**Reasoning:**
- Most existing TYPO3 hosting uses Redis 7.x
- Maximum development-production parity today
- Battle-tested, 15 years of production use
- Familiar to developers
**Rejected Because:**
- Optimizes for yesterday's production, not tomorrow's
- Ignores industry trajectory (AWS/Google/Oracle Valkey adoption)
- Creates educational debt (developers learn old patterns)
- Proprietary licensing creates compliance concerns
- Misses opportunity to lead the transition
### Alternative 2: Redis 8-alpine Default
**Reasoning:**
- Latest Redis version
- Performance improvements over Redis 7
**Rejected Because:**
- Proprietary licensing (same as Redis 7.4+)
- Larger image size (100 MB vs 69.7 MB Valkey)
- More expensive on cloud providers vs Valkey
- Not the strategic direction of major cloud platforms
### Alternative 3: No Caching Service by Default
**Reasoning:**
- Simpler default setup
- Developers add only if needed
**Rejected Because:**
- Redis/Valkey caching is common in TYPO3 production
- Reference implementation should include production-realistic services
- DDEV skill aims to provide complete development environment
- Adding later is more friction than having it by default
### Alternative 4: Offer Both Redis and Valkey as Equal Choices
**Reasoning:**
- Maximum flexibility
- No opinionated defaults
**Rejected Because:**
- Adds complexity to setup process
- Forces developers to make decision without context
- Reference implementations should have opinionated best practices
- Still need to pick ONE as default for generation
- Documentation burden increases (maintain two equal paths)
---
## References
### Technical Documentation
- [Valkey Official Site](https://valkey.io/)
- [Valkey GitHub Repository](https://github.com/valkey-io/valkey)
- [AWS ElastiCache for Valkey Announcement](https://aws.amazon.com/about-aws/whats-new/2024/10/amazon-elasticache-valkey/)
- [TYPO3 Redis Cache Backend Documentation](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/CachingFramework/Backends/Index.html)
### Benchmarks and Analysis
- AWS ElastiCache Valkey 8.0: 230% throughput improvement, 70% latency improvement vs Valkey 7.2
- AWS Cost Comparison: Valkey 20% cheaper (node-based), 33% cheaper (serverless) vs Redis
- Docker Image Sizes:
- `valkey/valkey:8-alpine` - 69.7 MB
- `redis:8-alpine` - 100 MB
- `redis:7-alpine` - 60.6 MB
### Licensing
- Redis License Change: [Redis Announcement (March 2024)](https://redis.io/blog/redis-adopts-dual-source-available-licensing/)
- Valkey License: BSD-3-Clause (OSI-approved open source)
- Linux Foundation Valkey Announcement: [TechCrunch Article](https://techcrunch.com/2024/03/31/why-aws-google-and-oracle-are-backing-the-valkey-redis-fork/)
---
## Decision Rationale Summary
This decision is **strategic and forward-looking** rather than purely technical:
1. **Technical Equivalence**: For TYPO3 use cases, Redis and Valkey are functionally identical
2. **Strategic Positioning**: Major cloud providers (AWS, Google, Oracle) are adopting Valkey
3. **Economic Reality**: 20-33% cost savings will drive hosting provider migration
4. **Licensing Safety**: True open source (BSD-3) vs proprietary licensing concerns
5. **Educational Leadership**: Skill should teach future patterns, not legacy patterns
6. **Risk Mitigation**: Easy rollback, auto-preservation of existing choices, clear documentation
**The default to Valkey is a bet on the industry trajectory being correct, backed by Linux Foundation + AWS + Google + Oracle. The risk is minimal (easy rollback), and the educational benefit is high (teaching developers about open source licensing, cost-effective infrastructure, and future-proof choices).**
---
## Valkey 9.0 Consideration (October 2025)
**Release Information:**
- **Valkey 9.0 GA:** Released October 21, 2025
- **Status:** Stable production release
- **Docker Image:** `valkey/valkey:9-alpine` available
### Performance Improvements
**Throughput:**
- **40% higher throughput** compared to Valkey 8.1
- Supports **over 1 billion requests per second** in cluster configurations
- Memory prefetching for pipelined commands
- Zero-copy responses for large requests
- SIMD optimizations (up to 200% faster BITCOUNT, hyperloglog)
- Multipath TCP support (up to 25% lower latency)
### Major New Features
**Hash Field Expiration:**
- TTL on individual fields within a hash
- Automatic expired data removal
- Improved memory efficiency
**Atomic Slot Migration:**
- Snapshot-based migration for horizontal scaling
- Zero-downtime scaling
- Source and target nodes remain active during transfer
**Multiple Databases in Cluster Mode:**
- Multiple logical namespaces on single cluster
- Better keyspace organization
- Reduced memory waste
### Production Adoption Status
**Cloud Provider Support (as of October 2025):**
-**AWS ElastiCache:** Not yet supported (latest: Valkey 8.1 - July 2025)
-**Google Cloud:** No announcement
-**Oracle Cloud:** No announcement
**Docker Hub:**
- ✅ Official images available: `valkey/valkey:9.0-alpine`
- ✅ Wire-protocol compatible with Valkey 8.x and Redis 7.x
### Decision: Stay with Valkey 8 for Now
**Rationale:**
This differs from the original Valkey vs Redis decision:
- **Valkey vs Redis (Original):** Industry was MIGRATING → Lead with Valkey 8
- **Valkey 8 vs 9 (Now):** Industry STABLE on 8 → Follow production
**Why wait for Valkey 9:**
1. **Production Parity:** AWS ElastiCache only supports up to Valkey 8.1
2. **Very New:** Released October 21, 2025 (1 day old at time of writing)
3. **Hosting Adoption:** No TYPO3 hosting providers using Valkey 9 yet
4. **Upgrade Urgency:** GitHub release notes state "LOW" urgency
5. **Battle-Testing:** Valkey 8.x more production-proven
**Benefits of Staying on Valkey 8:**
- ✅ Cloud provider support (AWS ElastiCache available)
- ✅ Production-aligned (matches hosting environments)
- ✅ Battle-tested (in production since November 2024)
- ✅ Conservative approach (let others find bugs first)
**When to Upgrade to Valkey 9:**
Monitor for these signals:
1. **AWS ElastiCache announces Valkey 9 support**
2. **3+ months of production stability reports**
3. **Major TYPO3 hosting providers adopt Valkey 9**
4. **Performance improvements become critical for use case**
### Upgrade Path
**Seamless Migration (when ready):**
Valkey 8 → 9 upgrade is simple (wire-compatible):
```yaml
# Change from:
image: valkey/valkey:8-alpine
# To:
image: valkey/valkey:9-alpine
```
No configuration changes required. No data migration needed. Restart container.
**Trade-offs:**
- **Wait:** Production parity, battle-tested, conservative (recommended)
- **Upgrade Now:** 40% faster, cutting-edge, slightly risky
**Recommendation:** Wait for AWS ElastiCache support before defaulting to Valkey 9 in skill templates.
---
## Review and Updates
**Next Review Date:** 2026-04-01 (6 months from October 2025)
**Trigger for Re-evaluation:**
- Major TYPO3 hosting providers publicly announce Redis-only support policies
- Valkey compatibility issues discovered affecting TYPO3
- Valkey project loses major sponsor backing
- Cloud provider pricing changes making Redis competitive again
**Success Metrics:**
- Developer feedback on Valkey default (GitHub issues, discussions)
- Number of projects switching from Valkey to Redis (indicates friction)
- Hosting provider announcements about Valkey adoption
- TYPO3 community discussion about cache backends
---
**Approved By:** TYPO3 DDEV Skill Project
**Implementation:** v2.0.0 (target release)

View File

@@ -0,0 +1,651 @@
# ADR 0002: Tiered Database Selection for TYPO3 Extension Development
**Status:** Accepted (Revised 2025-01-22)
**Date:** 2024-12-22 (Original), 2025-01-22 (Revision 1)
**Decision Makers:** TYPO3 DDEV Skill Maintainers
**Tags:** #database #mariadb #postgresql #mysql #sqlite #tiered-selection #development-optimization
---
## Context
### Production vs Development Requirements
**Critical Distinction:** This ADR addresses **DDEV extension development environments**, NOT production hosting.
**Development Context (DDEV):**
- Single developer on localhost
- Fast iteration cycles (code → ddev restart → test → repeat)
- Resource efficiency matters (RAM, disk, startup time)
- Perfect isolation for multi-version testing (v11, v12, v13)
- No public internet exposure, no security concerns
- Human actions are sequential (seconds/minutes apart)
**Production Context (Hosting):**
- Multi-user concurrent access
- Public internet exposure with security requirements
- Uptime and reliability critical
- Performance under load matters
- 95%+ TYPO3 hosting uses MariaDB
**Key Insight:** Development and production have DIFFERENT requirements. Production-parity is important for complex extensions with custom SQL, but OVERKILL for simple extensions using only TYPO3 Core APIs.
### TYPO3 13 Database Support
TYPO3 13 officially supports four database systems:
- **MariaDB** >= 10.4.3 <= 11.0.0
- **MySQL** >= 8.0.17
- **PostgreSQL** >= 10.0
- **SQLite** >= 3.8.3
While all four are technically supported, production deployment patterns and ecosystem alignment vary significantly.
### Production Hosting Landscape
**Research Finding:** "Most TYPO3 customers prefer to use the MySQL/MariaDB database"
**European TYPO3 Hosting Providers:**
- **jweiland.net**: MariaDB 10.11, MariaDB 10.3 (MySQL 5.6 outdated)
- **mittwald**: MariaDB (primary offering)
- **TYPO3 Agency**: MariaDB (standard configuration)
- **platform.sh**: Supports all, but MariaDB most common for TYPO3
**Estimated Distribution:**
- MariaDB: **95%+** of TYPO3 production installations
- MySQL 8: <10% (mostly cloud providers, corporate environments)
- PostgreSQL: <5% (specialized use cases: GIS, analytics, full-text search)
- SQLite: 0% production (demo/testing only)
### SQLite for Development (Revision 1 Analysis)
**SQLite Capabilities for DDEV Development:**
TYPO3 13 officially supports SQLite >= 3.8.3, and modern PHP containers (Ubuntu/Debian) include SQLite 3.40+.
**Development Benefits:**
- **Startup Speed**: Instant (no container startup) vs 5-10 seconds for MariaDB
- **Resource Usage**: ~20 MB RAM vs ~200 MB RAM for MariaDB container
- **Disk Space**: 0 MB (PHP extension) vs 744 MB MariaDB container image
- **Isolation**: Perfect separation for v11/v12/v13 (separate .sqlite files)
- **Simplicity**: No container orchestration, no health checks
**SQLite WAL Mode (Write-Ahead Logging):**
- Available since SQLite 3.7.0 (TYPO3 requires >= 3.8.3)
- Enables concurrent READS during WRITES
- Multiple WRITES serialize but with better concurrency than default mode
- Addresses concurrent write concerns for single-developer localhost usage
**When SQLite is SUFFICIENT for Development:**
- Extension uses only TYPO3 Core APIs (Extbase, FAL, DataHandler)
- No custom raw SQL queries
- No custom database tables
- Human actions sequential (save → upload → clear cache) not truly concurrent
- Single developer localhost environment
**When SQLite is INSUFFICIENT:**
- Extension has custom database tables (ext_tables.sql)
- Extension uses raw SQL queries (database-specific syntax)
- Performance-critical operations requiring production-realistic testing
- Testing multi-user concurrent scenarios
**Developer Workflow Impact:**
```
Daily Workflow: 10x ddev restarts
- MariaDB: 10 × 10 seconds = 100 seconds waiting
- SQLite: 10 × 2 seconds = 20 seconds waiting
- Time saved: 80 seconds per day = 400 seconds per week
```
### Performance Benchmarks (2024)
**MariaDB vs MySQL 8:**
According to 2024 Sysbench benchmarks:
- MariaDB 11.4 performance is **13-36% faster** than MySQL 8.0
- Modern MySQL 8.0.36 gets only 66-84% throughput relative to older MySQL 5.6.51
- MySQL suffers from CPU overhead **1.38X larger** than MariaDB
- MariaDB maintains **stable performance** across 10 years and 14 releases
**PostgreSQL vs MariaDB:**
OLTP Benchmarks (HammerDB TPROC-C):
- PostgreSQL: **84% more orders** processed than MariaDB in payments-per-second tests
- PostgreSQL excels at **complex analytical queries** and parallel execution
- MariaDB shows **15-25% better performance** for transactional applications
- TYPO3 workload is primarily transactional (CRUD operations on content) → MariaDB advantage
**Key Insight:** PostgreSQL is technically superior for analytics, but TYPO3 is a CMS (transactional workload), not an analytics platform.
### Docker Image Sizes
Surprisingly, PostgreSQL has a **smaller image**:
| Database | Image | Size |
|----------|-------|------|
| PostgreSQL 16 | `postgres:16-alpine` | **394 MB** |
| MariaDB latest | `mariadb:latest` | 456 MB |
| MySQL 8 | `mysql:8` | ~500 MB |
| DDEV MariaDB 10.11 | `ddev/ddev-dbserver-mariadb-10.11` | 744 MB* |
*DDEV image includes TYPO3-specific tooling and optimizations
### Extension Compatibility Concerns
**Doctrine DBAL Abstraction:**
TYPO3 uses Doctrine DBAL to abstract database differences. In theory, extensions should work across all supported databases.
**Reality:**
1. **Raw SQL Bypass**: Extensions using raw SQL (not via Doctrine QueryBuilder) may assume MySQL/MariaDB syntax
2. **Testing Coverage**: Extension developers test primarily on MariaDB (95% hosting uses it)
3. **Syntax Differences**:
- MySQL/MariaDB: `DATE_FORMAT()`, `LIMIT offset, count`, `AUTO_INCREMENT`
- PostgreSQL: `TO_CHAR()`, `LIMIT count OFFSET offset`, `SERIAL`
**Risk:** Extensions with raw SQL may break on PostgreSQL but work fine on MariaDB.
### DDEV Database Support
DDEV provides native database configuration via `.ddev/config.yaml`:
```yaml
database:
type: mariadb # or: mysql, postgres
version: "10.11" # version string
```
**Migration Support:**
- **MySQL ↔ MariaDB**: `ddev debug migrate-database` (seamless migration)
- **MariaDB/MySQL → PostgreSQL**: Manual export/import (schema differences)
- **PostgreSQL → MariaDB/MySQL**: Manual export/import (schema differences)
**Implication:** Starting with MariaDB and needing PostgreSQL later is painful (data migration). Starting with PostgreSQL and needing MariaDB is equally painful. Must choose wisely upfront.
---
## Decision
**Use tiered database selection based on extension complexity for TYPO3 DDEV development environments.**
### Tier 1: SQLite (Default for Simple Extensions)
**Recommended for extensions that:**
- ✅ Have no custom database tables (ext_tables.sql absent or empty)
- ✅ Use only TYPO3 Core APIs (Extbase, FAL, DataHandler, Doctrine DBAL)
- ✅ Have no raw SQL queries
- ✅ Category: plugin, fe, be, misc
- ✅ File size < 1 MB
**Benefits:**
-**Startup**: 5-10 seconds faster per ddev start
- 💾 **RAM**: 900 MB saved (no MariaDB container)
- 💿 **Disk**: 744 MB saved (no container image)
- 🔒 **Isolation**: Perfect separation for v11/v12/v13 databases
- 🎯 **Simplicity**: No container orchestration needed
**Critical Warnings:**
- ⚠️ **Development ONLY** - Never use SQLite in production
- ⚠️ **Switch to MariaDB** if you add custom SQL queries or tables
- ⚠️ **Final Testing** - Run compatibility tests on MariaDB before extension release
### Tier 2: MariaDB 10.11 (Default for Complex Extensions)
**Recommended for extensions that:**
- ❌ Have custom database tables (ext_tables.sql present)
- ❌ Use raw SQL queries (database-specific syntax)
- ❌ Performance-critical operations
- ❌ Category: services, module
- ❌ File size > 1 MB
**Benefits:**
- ✅ Production-realistic testing (95%+ TYPO3 hosting uses MariaDB)
- ✅ Better for concurrent operations
- ✅ Proper performance benchmarking
- ✅ Extension compatibility (99%+ extensions tested on MariaDB)
### Tier 3: PostgreSQL 16 (Explicit Requirements)
**Recommended for extensions that:**
- 🎯 Require GIS/spatial data (PostGIS)
- 🎯 Advanced analytics or complex queries
- 🎯 Extension explicitly requires PostgreSQL
### Tier 4: MySQL 8.0 (Corporate/Oracle Ecosystem)
**Recommended for:**
- 🏢 Corporate environments requiring Oracle ecosystem integration
- 🏢 Existing production environments using MySQL 8
**Implement auto-detection logic** to analyze extension complexity and suggest appropriate database tier.
### Implementation Details
#### Default Configuration Based on Extension Analysis
**For Simple Extensions (Tier 1):**
No `.ddev/config.yaml` database configuration needed (uses DDEV default PHP with SQLite)
TYPO3 installation command:
```bash
vendor/bin/typo3 setup \
--driver=pdo_sqlite \
--path=/var/www/html/v13/database.sqlite \
--admin-username=admin \
--admin-password='Password:joh316' \
--project-name="Extension Dev v13"
```
**For Complex Extensions (Tier 2):**
`.ddev/config.yaml`:
```yaml
database:
type: mariadb
version: "10.11"
```
TYPO3 installation command uses: `--driver=mysqli --host=db --dbname=v13`
#### Auto-Detection Logic
During extension metadata extraction:
```yaml
Extension Complexity Analysis:
1. SQLite Detection (Tier 1 - Simple Extension):
Checks:
✓ ext_tables.sql: Absent or empty
✓ Raw SQL patterns: None found (grep for executeQuery, $GLOBALS['TYPO3_DB'])
✓ File size: < 1 MB
✓ Category: plugin, fe, be, misc
→ Suggest SQLite (development-optimized)
2. MariaDB Detection (Tier 2 - Complex Extension):
Checks:
✗ ext_tables.sql: Present with table definitions
✗ Raw SQL patterns: Found
✗ File size: > 1 MB
✗ Category: services, module
→ Suggest MariaDB 10.11 (production-realistic)
3. PostgreSQL Detection (Tier 3 - Explicit Requirement):
Checks:
• Extension name: Contains "postgres", "pgsql", "pg_", "postgis"
• composer.json: Requires "typo3/cms-pgsql"
• Description: Keywords "GIS", "spatial", "analytics"
→ Suggest PostgreSQL 16 (specialized)
4. MySQL Detection (Tier 4 - Corporate):
Checks:
• composer.json: Requires "typo3/cms-mysql"
• Manual override only
→ Suggest MySQL 8.0 (corporate/Oracle ecosystem)
```
**User Confirmation (Simple Extension Example):**
```
Detected Database Configuration:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Database: SQLite (Tier 1)
Reason: Simple extension using only TYPO3 Core APIs
No custom tables, no raw SQL
Benefits:
⚡ Startup: 5-10 seconds faster per ddev start
💾 RAM: 900 MB saved
💿 Disk: 744 MB saved
🔒 Isolation: Perfect v11/v12/v13 separation
Warnings:
⚠️ Development ONLY (never production)
⚠️ Switch to MariaDB if adding custom SQL
⚠️ Run final tests on MariaDB before release
Alternatives:
• mariadb:10.11 - Production-realistic testing
• postgres:16 - GIS/analytics requirements
• mysql:8.0 - Oracle ecosystem
Proceed with SQLite? (y/n)
```
**User Confirmation (Complex Extension Example):**
```
Detected Database Configuration:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Database: MariaDB 10.11 (Tier 2)
Reason: Complex extension with custom tables
Found: ext_tables.sql with 3 custom tables
Benefits:
✅ Production-realistic (95%+ TYPO3 hosting)
✅ Extension compatibility (99%+ tested)
✅ Proper concurrent operation handling
Alternatives:
• sqlite - Faster development (not recommended for custom tables)
• postgres:16 - GIS/analytics requirements
• mysql:8.0 - Oracle ecosystem
Proceed with MariaDB 10.11? (y/n)
```
---
## Consequences
### Positive
**Production Parity**
- 95%+ TYPO3 hosting uses MariaDB
- Development environment matches production reality
- Reduces deployment surprises and compatibility issues
**Extension Compatibility**
- 99%+ TYPO3 extensions tested on MariaDB
- Minimizes risk of raw SQL incompatibilities
- Safer default for general extension development
**TYPO3 Ecosystem Alignment**
- TYPO3 documentation examples use MariaDB
- Community tutorials assume MariaDB
- Developer familiarity (most TYPO3 devs know MySQL/MariaDB)
**Performance for CMS Workload**
- MariaDB 13-36% faster than MySQL 8 for transactional operations
- TYPO3 workload is primarily CRUD (transactional), not analytical
- Optimal for typical CMS usage patterns
**DDEV Standard**
- DDEV defaults to MariaDB for TYPO3 projects
- Ecosystem-aligned with DDEV best practices
- Smooth migration within MySQL/MariaDB family
**Mature & Stable**
- MariaDB 10.11 is production-proven LTS release
- 15+ years of MySQL/MariaDB history
- Battle-tested with TYPO3 workloads
### Negative
⚠️ **Not Leveraging PostgreSQL Advantages**
- PostgreSQL has smaller image (394 MB vs 744 MB DDEV MariaDB)
- PostgreSQL superior for complex queries, analytics, GIS
- PostgreSQL has better ACID compliance and advanced features (JSONB, full-text, PostGIS)
- **Counter-argument:** TYPO3 extensions rarely need these features; production uses MariaDB anyway
⚠️ **MySQL 8 Performance Gap**
- MariaDB 13-36% faster than MySQL 8 in benchmarks
- MySQL 8 has CPU overhead issues
- Defaulting to MariaDB means MySQL users must explicitly switch
- **Counter-argument:** MySQL 8 only needed for Oracle ecosystem; MariaDB is better performer
⚠️ **Limited PostgreSQL Exposure**
- Developers don't experience PostgreSQL advantages
- PostgreSQL adoption in TYPO3 ecosystem remains low
- **Counter-argument:** Production reality dictates development choices; can't force ecosystem change from dev tools
### Risks and Mitigations
| Risk | Severity | Likelihood | Mitigation |
|------|----------|------------|------------|
| PostgreSQL-specific extension not detected | Medium | Low | Explicit naming conventions documented; manual override available |
| Extension breaks on PostgreSQL in production | High | Very Low | Production hosting uses MariaDB (95%+); PostgreSQL hosting rare |
| Developer unfamiliar with MariaDB | Low | Very Low | MySQL/MariaDB standard in web development; extensive documentation |
| MariaDB 10.x deprecated before TYPO3 14 | Low | Low | MariaDB 11 alternative documented; DDEV migration smooth |
| Missing out on PostgreSQL innovation | Low | Medium | PostgreSQL 16 documented and available; auto-detection suggests when appropriate |
---
## Alternatives Considered
### Alternative 1: PostgreSQL 16 Default
**Reasoning:**
- Technically superior database (ACID, advanced features)
- Smaller image size (394 MB vs 744 MB)
- Better for complex queries and analytics
- Future-proof with modern features
**Rejected Because:**
- ❌ Only ~5% of TYPO3 hosting uses PostgreSQL
- ❌ Extension compatibility risk (raw SQL, testing coverage)
- ❌ Development-production mismatch for 95% of deployments
- ❌ No industry migration trend (unlike Valkey case)
- ❌ TYPO3 workload is transactional, not analytical
- ❌ Higher learning curve for TYPO3 developers
- ❌ Counter to TYPO3 ecosystem standards
**Key Difference from Valkey Decision:**
- Valkey: Industry migrating TO new technology (AWS/Google/Oracle adopting)
- PostgreSQL: Industry STABLE on existing technology (95% MariaDB, no migration)
### Alternative 2: MySQL 8.0 Default
**Reasoning:**
- TYPO3 officially supports MySQL 8.0.17+
- Oracle corporate backing
- Window functions, CTEs, document store features
**Rejected Because:**
- ❌ MariaDB 13-36% faster in benchmarks
- ❌ MySQL 8 has CPU overhead issues (1.38X vs MariaDB)
- ❌ Less common than MariaDB in TYPO3 hosting
- ❌ Oracle licensing concerns (GPL but Oracle-controlled)
- ❌ MariaDB is better open-source governance (MariaDB Foundation)
- ❌ TYPO3 doesn't leverage MySQL 8 advanced features heavily
### Alternative 3: MariaDB 11.x Default
**Reasoning:**
- Performance improvements over MariaDB 10.x (+40% in benchmarks)
- TYPO3 13 supports up to MariaDB 11.0
- Forward-looking choice
**Rejected Because:**
- ⚠️ MariaDB 11.0 has breaking changes (removed features)
- ⚠️ Less production-proven than 10.11 LTS
- ⚠️ Most hosting still on MariaDB 10.x
- ⚠️ Higher risk of compatibility issues
- **Compromise:** Offer as documented alternative for forward-looking users
### Alternative 4: No Default (User Choice Required)
**Reasoning:**
- Maximum flexibility
- User decides based on production environment
- No opinionated stance
**Rejected Because:**
- ❌ Forces decision without context for new developers
- ❌ Increases setup friction and confusion
- ❌ Reference implementations should have best-practice defaults
- ❌ Most users (95%+) would choose MariaDB anyway
- ❌ Skill value proposition includes intelligent defaults
### Alternative 5: SQLite for Development (REVISED - Now ACCEPTED for Tier 1)
**Reasoning:**
- Minimal setup (no container overhead)
- Fast for development iteration cycles
- Perfect isolation for multi-version testing
- TYPO3 13 officially supports SQLite >= 3.8.3
- Single-developer DDEV localhost use case
**Originally Rejected Because (Revision 1 Analysis):**
- ❌ "Not production-viable (no concurrent writes)" → **OVERSTATED** for single-developer localhost
- Reality: Human actions are sequential (seconds/minutes apart)
- SQLite WAL mode handles concurrent reads during writes
- DDEV is single developer, not multi-user production
- ❌ "Security risk (web-downloadable database)" → **INVALID** for DDEV localhost
- Reality: Localhost (127.0.0.1), not exposed to public internet
- This is a production concern, not development concern
- ❌ "Not representative of production" → **OVER-APPLIED** for simple extensions
- Reality: For extensions using only Core APIs, database type doesn't matter
- Production parity important for custom SQL, overkill for simple extensions
**Now ACCEPTED for Tier 1 (Simple Extensions) Because:**
- ✅ Development and production have DIFFERENT requirements
- ✅ Significant developer experience improvements (5-10 sec startup, 900 MB RAM saved)
- ✅ Perfect for extensions using only TYPO3 Core APIs (Doctrine DBAL abstraction)
- ✅ Clear warnings prevent production misuse
- ✅ Easy migration to MariaDB if extension complexity increases
**Critical Success Factor:** Clear documentation that SQLite is **development ONLY**, with automated warnings and migration path to MariaDB for production testing.
---
## Database Selection Matrix
| Use Case | Recommended Database | Rationale |
|----------|---------------------|-----------|
| **Simple Plugin Extension (Core APIs only)** | **SQLite** (Tier 1) | Fast development, resource-efficient, perfect isolation |
| **Simple Frontend Extension** | **SQLite** (Tier 1) | No custom tables, uses FAL/Extbase/Doctrine DBAL |
| **Simple Backend Module (no custom SQL)** | **SQLite** (Tier 1) | TYPO3 core tables only, development-optimized |
| **RTE/CKEditor Plugin** | **SQLite** (Tier 1) | File operations via FAL, no database complexity |
| **Complex Extension (custom tables)** | **MariaDB 10.11** (Tier 2) | Production parity, custom database schema |
| **Extension with Raw SQL** | **MariaDB 10.11** (Tier 2) | Database-specific syntax, production testing needed |
| **Performance-Critical Extension** | **MariaDB 10.11** (Tier 2) | Production-realistic benchmarking required |
| **General TYPO3 Extension (unknown complexity)** | **MariaDB 10.11** (Tier 2) | Safe default, ecosystem standard, fallback choice |
| **GIS/Mapping Extension** | **PostgreSQL 16** (Tier 3) | PostGIS support, spatial queries |
| **Analytics/Reporting Extension** | **PostgreSQL 16** (Tier 3) | Complex queries, parallel execution, window functions |
| **Full-Text Search Extension** | **PostgreSQL 16** (Tier 3) | Superior full-text search capabilities |
| **Corporate/Oracle Ecosystem** | **MySQL 8.0** (Tier 4) | Oracle integration, enterprise requirements |
| **Forward-Looking Performance** | **MariaDB 11.4** | Latest features, performance improvements |
| **Production Uses PostgreSQL** | **PostgreSQL 16** (Tier 3) | Development-production parity |
| **Production Uses MySQL** | **MySQL 8.0** (Tier 4) | Development-production parity |
**Key Changes from Original Decision:**
- ✅ SQLite now RECOMMENDED for simple extensions (Tier 1)
- ✅ MariaDB remains default for complex extensions (Tier 2)
- ✅ Tiered approach based on extension complexity analysis
- ✅ Development efficiency prioritized for simple extensions
- ✅ Production parity prioritized for complex extensions
---
## Implementation Roadmap
### Phase 1: Documentation (Immediate)
1. **ADR Creation**: This document
2. **SKILL.md Update**: Database section explaining default and alternatives
3. **README.md Update**: Quick reference for database options
4. **Template Comments**: Explain database choice in config.yaml
### Phase 2: Auto-Detection (v2.1.0)
1. **Extension Metadata Parsing**: Detect PostgreSQL signals
2. **User Confirmation**: Present detected database with rationale
3. **Override Option**: Allow manual database selection
4. **Logging**: Explain why database was chosen
### Phase 3: Testing & Validation (Ongoing)
1. **MariaDB 10.11**: Validate default (already working)
2. **PostgreSQL 16**: Test TYPO3 13 installation
3. **MariaDB 11.4**: Validate forward-looking alternative
4. **MySQL 8.0**: Validate corporate alternative
---
## References
### Technical Documentation
- [TYPO3 13 System Requirements](https://get.typo3.org/version/13#system-requirements)
- [TYPO3 Database Configuration](https://docs.typo3.org/m/typo3/reference-coreapi/13.4/en-us/ApiOverview/Database/Configuration/Index.html)
- [DDEV Database Documentation](https://ddev.readthedocs.io/en/stable/users/extend/database-types/)
- [MariaDB vs MySQL Performance](https://mariadb.org/how-mariadb-and-mysql-performance-changed-over-releases/)
### Benchmarks
- **MariaDB vs MySQL**: 13-36% faster (Sysbench 2024)
- **PostgreSQL vs MariaDB**: +84% OLTP orders (HammerDB TPROC-C)
- **MySQL 8 Performance**: 66-84% throughput vs MySQL 5.6
- **Image Sizes**: PostgreSQL 394 MB, MariaDB 456 MB, DDEV MariaDB 744 MB
### TYPO3 Community
- **Hosting Research**: "Most TYPO3 customers prefer MySQL/MariaDB"
- **Production Distribution**: 95%+ MariaDB, <10% MySQL, <5% PostgreSQL
- **TYPO3 Forum**: [PostgreSQL discussions](https://www.typo3forum.net/discussion/82437/typo3-with-postgresql)
---
## Decision Rationale Summary (Revised)
### Tiered Database Selection Strategy
**SQLite (Tier 1) is OPTIMAL for simple extensions because:**
1. **Development Efficiency** (5-10 seconds faster startup, 900 MB RAM saved)
2. **Resource Optimization** (744 MB less disk, no container overhead)
3. **Perfect Isolation** (Separate .sqlite files for v11/v12/v13)
4. **Core API Sufficiency** (Extensions using only TYPO3 Core APIs work across databases)
5. **Developer Experience** (Faster iteration cycles, simpler architecture)
**Critical:** Development ONLY. Clear warnings prevent production misuse.
**MariaDB 10.11 (Tier 2) is NECESSARY for complex extensions because:**
1. **Production Reality** (95%+ TYPO3 hosting uses MariaDB)
2. **Custom SQL Requirements** (Database-specific syntax testing)
3. **Extension Compatibility** (99%+ extensions tested on MariaDB)
4. **Performance Testing** (Production-realistic benchmarking)
5. **Stability** (LTS release, production-proven, DDEV standard)
**PostgreSQL 16 (Tier 3) is REQUIRED for specialized extensions because:**
1. **GIS/Spatial Data** (PostGIS support, spatial queries)
2. **Analytics** (Complex queries, parallel execution)
3. **Technical Superiority** (Advanced features for specific use cases)
**MySQL 8.0 (Tier 4) is AVAILABLE for corporate environments because:**
1. **Oracle Ecosystem** (Corporate integration requirements)
2. **Existing Production** (Development-production parity)
### Key Insight: Context Matters
**This is NOT like Valkey** where industry was migrating. Database choice is stable at MariaDB for production.
**This IS like Valkey** in that we recognize DEVELOPMENT and PRODUCTION have DIFFERENT optimal choices.
**The tiered approach is intelligent and context-aware:**
- **Simple extensions** → Optimize for development efficiency (SQLite)
- **Complex extensions** → Optimize for production parity (MariaDB)
- **Specialized extensions** → Match technical requirements (PostgreSQL/MySQL)
**Revision 1 Learning:** Original ADR over-applied production concerns to development context. After user challenge, re-analysis showed SQLite is OPTIMAL for simple extension development with proper warnings and migration path.
---
## Review and Updates
**Next Review Date:** 2025-06-01 (6 months)
**Trigger for Re-evaluation:**
- TYPO3 14 changes database support or recommendations
- PostgreSQL adoption in TYPO3 hosting exceeds 25%
- MariaDB 10.x becomes unsupported by TYPO3
- Major performance regressions discovered in MariaDB
- TYPO3 officially recommends different default database
**Success Metrics:**
- Developer feedback on database default (GitHub issues)
- PostgreSQL adoption rate for auto-detected extensions
- Extension compatibility reports
- Production deployment success rate
---
**Approved By:** TYPO3 DDEV Skill Project
**Implementation:** v2.1.0 (target release)

View File

@@ -0,0 +1,288 @@
## Advanced Options
### Custom PHP Version
If extension requires different PHP version:
```yaml
# In .ddev/config.yaml
php_version: "8.1" # or "8.3"
```
### Database Selection (Tiered Approach)
The skill uses **intelligent database selection** based on extension complexity.
**🎯 Tier 1: SQLite (Simple Extensions - Development Optimized)**
**Recommended for:**
- ✅ Extensions using only TYPO3 Core APIs (Extbase, FAL, DataHandler)
- ✅ No custom database tables (ext_tables.sql absent/empty)
- ✅ No raw SQL queries
- ✅ Category: plugin, fe, be, misc
- ✅ Example: rte_ckeditor_image, simple content elements, frontend plugins
**Benefits:**
-**Startup**: 5-10 seconds faster per ddev start
- 💾 **RAM**: 900 MB saved (no MariaDB container)
- 💿 **Disk**: 744 MB saved (no container image)
- 🔒 **Isolation**: Perfect v11/v12/v13 separation (separate .sqlite files)
**Configuration:**
```yaml
# No .ddev/config.yaml database config needed
# TYPO3 installation uses SQLite automatically
```
**Critical Warnings:**
- ⚠️ **Development ONLY** - Never use SQLite in production
- ⚠️ **Switch to MariaDB** if you add custom SQL queries or tables
- ⚠️ **Final Testing** - Run compatibility tests on MariaDB before release
**🔧 Tier 2: MariaDB 10.11 (Complex Extensions - Production Parity)**
**Recommended for:**
- ❌ Extensions with custom database tables (ext_tables.sql present)
- ❌ Extensions using raw SQL queries
- ❌ Performance-critical operations
- ❌ Category: services, module
- ❌ Unknown complexity (safe default)
**Benefits:**
-**Production Standard**: 95%+ TYPO3 hosting uses MariaDB
-**Extension Compatibility**: 99%+ TYPO3 extensions tested on MariaDB
-**Performance**: 13-36% faster than MySQL 8 for transactional workloads
-**TYPO3 Ecosystem**: Documentation, tutorials, community standard
**Configuration:**
```yaml
# In .ddev/config.yaml
database:
type: mariadb
version: "10.11"
```
**🌐 Tier 3: PostgreSQL 16 (Specialized Requirements)**
**Recommended for:**
- 🎯 GIS/spatial data (PostGIS)
- 🎯 Advanced analytics or complex queries
- 🎯 Explicit PostgreSQL requirement
**Configuration:**
```yaml
# In .ddev/config.yaml
database:
type: postgres
version: "16"
```
**🏢 Tier 4: MySQL 8.0 (Corporate/Oracle Ecosystem)**
**Recommended for:**
- 🏢 Corporate environments requiring Oracle integration
- 🏢 Production specifically uses MySQL 8
**Configuration:**
```yaml
# In .ddev/config.yaml
database:
type: mysql
version: "8.0"
```
**Auto-Detection Logic:**
The skill will analyze your extension and suggest the appropriate tier:
```yaml
SQLite Detection (Tier 1):
✓ ext_tables.sql: Absent or empty
✓ Raw SQL patterns: None found
✓ File size: < 1 MB
✓ Category: plugin, fe, be, misc
→ Suggests: SQLite (development-optimized)
MariaDB Detection (Tier 2):
✗ ext_tables.sql: Present with custom tables
✗ Raw SQL patterns: Found
✗ File size: > 1 MB
✗ Category: services, module
→ Suggests: MariaDB 10.11 (production-realistic)
PostgreSQL Detection (Tier 3):
• Extension name: Contains "postgres", "pgsql", "postgis"
• composer.json: Requires "typo3/cms-pgsql"
• Keywords: "GIS", "spatial", "analytics"
→ Suggests: PostgreSQL 16 (specialized)
```
**Alternative Options:**
**MariaDB 11** - Forward-looking performance:
```yaml
database:
type: mariadb
version: "11.4"
```
- Latest features (+40% performance vs 10.11)
- Forward compatibility testing
**For detailed rationale**, see: `docs/adr/0002-mariadb-default-with-database-alternatives.md`
### XDebug Setup
Enable XDebug for debugging:
```bash
ddev xdebug on
```
### Customize TYPO3 Versions
Edit `.ddev/docker-compose.web.yaml` and installation scripts to add/remove versions.
### Database Access
```bash
# Direct database access
ddev mysql
# Export database
ddev export-db > backup.sql.gz
# Import database
ddev import-db --file=backup.sql.gz
```
### Optional Services
The skill includes optional service templates for enhanced TYPO3 development:
#### Valkey / Redis (Caching)
Add high-performance caching to TYPO3 using **Valkey** (default) or **Redis** (alternative).
**Default: Valkey 8** (Open Source, Future-Proof)
```bash
# Copy Valkey template (default)
cp .ddev/templates/docker-compose.services.yaml.optional .ddev/docker-compose.services.yaml
cp .ddev/templates/config.redis.php.example .ddev/config.redis.php.example
# Restart DDEV
ddev restart
# Test Valkey (wire-compatible with Redis)
ddev ssh
redis-cli -h valkey ping # Should return: PONG
```
**Alternative: Redis 7** (For Legacy Production Parity)
```bash
# Use Redis 7 alternative template
cp .ddev/templates/docker-compose.services-redis.yaml.optional .ddev/docker-compose.services.yaml
# Restart DDEV
ddev restart
# Test Redis
ddev ssh
redis-cli -h redis ping # Should return: PONG
```
**Why Valkey Default?**
Valkey is wire-protocol compatible with Redis but offers:
-**True Open Source**: BSD-3-Clause license (Redis 7.4+ is proprietary)
-**Industry Adoption**: AWS, Google Cloud, Oracle backing (Linux Foundation project)
-**Smaller Image**: 69.7 MB (vs 100 MB Redis 8, 60.6 MB Redis 7)
-**Cost-Effective**: 20-33% cheaper on AWS ElastiCache
-**Future-Proof**: Strategic direction for cloud/managed hosting
**When to Use Redis 7 Instead:**
- Your production environment explicitly uses Redis 7.x
- Corporate policy requires battle-tested technology only (Redis has 15 years vs Valkey 1 year)
- Exact production-development parity needed with existing infrastructure
**Technical Details:**
**Valkey**: `valkey/valkey:8-alpine` (69.7 MB)
**Redis**: `redis:7-alpine` (60.6 MB)
**Memory**: 256MB with LRU eviction policy
**Port**: 6379 (same for both)
**Configuration**: Both use identical TYPO3 configuration. Add cache backend to `AdditionalConfiguration.php` (see `.ddev/config.redis.php.example`)
**For detailed rationale**, see: `docs/adr/0001-valkey-default-with-redis-alternative.md`
#### MailPit (Email Testing)
Catch all emails sent by TYPO3 for testing:
```bash
# Already included in docker-compose.services.yaml.optional
# Access Web UI after ddev restart:
# http://{{DDEV_SITENAME}}.ddev.site:8025
```
**Image**: `axllent/mailpit:latest`
**SMTP**: `mailpit:1025` (automatically configured in docker-compose.web.yaml)
#### Ofelia (TYPO3 Scheduler Automation)
Automate TYPO3 scheduler tasks with **ghcr.io/netresearch/ofelia**:
```bash
# Copy Ofelia configuration
cp .ddev/templates/docker-compose.ofelia.yaml.optional .ddev/docker-compose.ofelia.yaml
# Restart DDEV
ddev restart
# View scheduler logs
docker logs -f ddev-{{DDEV_SITENAME}}-ofelia
```
**Image**: `ghcr.io/netresearch/ofelia:latest` (GitHub Container Registry - TYPO3-optimized fork)
**Default Schedule**: TYPO3 scheduler runs every 1 minute for all versions
**Cache Warmup**: Every 1 hour for v13
**DDEV Naming**: Uses `docker-compose.*.yaml` naming (DDEV v1.24.8 requirement, not Compose v2 standard)
**No Version Field**: All service files omit `version:` declaration per Compose v2 spec
#### Shell Aliases
Add convenient shortcuts:
```bash
# Copy bash additions
cp .ddev/templates/homeadditions/.bashrc_additions.optional .ddev/homeadditions/.bashrc_additions
# Restart DDEV to load aliases
ddev restart
# Available aliases:
ddev ssh
t3-scheduler-v11 # Run TYPO3 11 scheduler
t3-scheduler-v12 # Run TYPO3 12 scheduler
t3-scheduler-v13 # Run TYPO3 13 scheduler
t3-scheduler-all # Run scheduler on all versions
redis # Access Redis CLI
t3-cache-flush-v13 # Flush TYPO3 13 cache
```
#### Complete Services Documentation
For detailed service configuration, troubleshooting, and performance tuning:
```bash
# Copy services README
cp .ddev/templates/README-SERVICES.md.optional .ddev/README-SERVICES.md
```
**Important Notes**:
- DDEV v1.24.8 requires `docker-compose.*.yaml` naming (auto-loads from `.ddev/`)
- Ofelia image: `ghcr.io/netresearch/ofelia:latest` (not Docker Hub)
- Ofelia command: `daemon --docker-events` (not `--docker`)
- Redis config must NOT be `.yaml` (DDEV tries to parse it as config)

View File

@@ -0,0 +1,370 @@
# Index Page Generation for TYPO3 DDEV Projects
## Purpose
Generate a professional overview page (`index.html`) that serves as the main entry point for the DDEV development environment, providing quick access to all TYPO3 versions and development tools.
## Automatic Branding Detection
**The index page MUST automatically detect and apply appropriate branding:**
### Step 1: Detect Available Branding Skills
Check for branding skills in this priority order:
1. **Company-specific branding** (e.g., `netresearch-branding`, `company-branding`)
2. **TYPO3 branding** (fallback - use TYPO3 orange #FF8700)
3. **Generic clean design** (last resort - neutral colors)
**Detection Method:**
```bash
# Check if branding skill exists
list-skills | grep -i branding
```
### Step 2: Apply Branding Based on Detection
#### If Netresearch Branding Detected
**Invoke:** `netresearch-branding` skill
**Colors:**
- Primary: #2F99A4 (Turquoise)
- Accent: #FF4D00 (Orange)
- Text: #585961 (Anthracite grey)
- Background: #FFFFFF (White)
- Light grey: #CCCDCC
**Typography:**
- Headlines: `font-family: 'Raleway', sans-serif;` (600/700 weight)
- Body: `font-family: 'Open Sans', sans-serif;` (400 weight)
**Layout:**
- Compact header: 20px padding
- High white space: 40px container padding
- Card shadows: subtle with turquoise glow on hover
#### If TYPO3 Branding (Fallback)
**Colors:**
- Primary: #FF8700 (TYPO3 Orange)
- Secondary: #000000 (Black)
- Text: #333333 (Dark grey)
- Background: #F8F9FA (Light grey)
- Cards: #FFFFFF (White)
**Typography:**
- System fonts: `-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif`
- No external font imports
**Layout:**
- Standard header: 40px padding
- Moderate white space: 30px container padding
- Card shadows: standard grey shadows
#### If No Branding (Generic)
**Colors:**
- Primary: #0066CC (Professional blue)
- Text: #333333
- Background: #FFFFFF
- Cards: #F5F5F5
**Typography:**
- System fonts only
- Standard sizing
## HTML Template Structure
### Required Elements
1. **Header** - Compact bar with project title
2. **Info Box** - Backend credentials (username/password)
3. **Grid Layout** - 2-4 columns responsive
4. **Cards** - One per TYPO3 version + tools
5. **Links** - Frontend and Backend URLs
### Card Content Template
```html
<div class="card">
<div class="card-icon">[EMOJI]</div>
<h3>[VERSION NAME]</h3>
<p>[DESCRIPTION]</p>
<div class="card-links">
<a href="[FRONTEND_URL]">→ Frontend</a>
<a href="[BACKEND_URL]">→ Backend</a>
</div>
</div>
```
### Cards to Include
**Always include:**
1. TYPO3 12.4 LTS (🎯 emoji)
2. TYPO3 13.x (⚡ emoji)
3. Documentation (📚 emoji)
4. Development Tools (📧 emoji - Mailpit)
**Optional cards** (if applicable):
5. TYPO3 11.5 LTS (📦 emoji)
6. Redis/Valkey (🔄 emoji)
7. Custom tools
## Generation Workflow
### Step 1: Detect Branding
```
1. Check for branding skills
2. If netresearch-branding exists → Use Netresearch colors/fonts
3. Else if project has branding config → Use project branding
4. Else → Use TYPO3 branding (fallback)
```
### Step 2: Extract Project Metadata
```
- Project name (from .ddev/config.yaml or composer.json)
- DDEV sitename
- Configured TYPO3 versions (from docker-compose or config)
```
### Step 3: Generate HTML
**File location:** `.ddev/web-build/index.html`
**Template variables to replace:**
- `{{PROJECT_NAME}}` - Extension display name
- `{{DDEV_SITENAME}}` - DDEV project name
- `{{PRIMARY_COLOR}}` - Brand primary color
- `{{ACCENT_COLOR}}` - Brand accent color
- `{{TEXT_COLOR}}` - Body text color
- `{{FONT_HEADLINE}}` - Headline font family
- `{{FONT_BODY}}` - Body font family
### Step 4: Copy to Web Root
```bash
# After generation
ddev exec cp /var/www/hello_world/.ddev/web-build/index.html /var/www/html/
```
## Example: Netresearch-Branded Index
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{PROJECT_NAME}} - Development Environment</title>
<link href="https://fonts.googleapis.com/css2?family=Raleway:wght@600;700&family=Open+Sans:wght@400&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Open Sans', sans-serif;
background: #FFFFFF;
color: #585961;
}
.header {
background: #2F99A4;
padding: 20px;
}
.header h1 {
font-family: 'Raleway', sans-serif;
color: #FFFFFF;
font-size: 24px;
}
.card-links a:hover {
background: #2F99A4;
color: #FFFFFF;
}
</style>
</head>
<body>
<!-- Content here -->
</body>
</html>
```
## Example: TYPO3-Branded Index (Fallback)
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{PROJECT_NAME}} - Development Environment</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: #F8F9FA;
color: #333333;
}
.header {
background: #FF8700;
padding: 40px 20px;
}
.header h1 {
color: #FFFFFF;
font-size: 32px;
}
.card-links a {
color: #FF8700;
}
.card-links a:hover {
background: #FF8700;
color: #FFFFFF;
}
</style>
</head>
<body>
<!-- Content here -->
</body>
</html>
```
## Responsive Design Requirements
**Breakpoints:**
```css
/* Mobile: default (single column) */
.grid {
grid-template-columns: 1fr;
}
/* Tablet: 768px+ (2 columns) */
@media (min-width: 768px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* Desktop: 1024px+ (auto-fit) */
@media (min-width: 1024px) {
.grid {
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
}
```
## Accessibility Requirements
**WCAG AA Compliance:**
1. **Color Contrast**
- Text on background: minimum 4.5:1
- Large text (18px+): minimum 3:1
- Verify with: https://webaim.org/resources/contrastchecker/
2. **Keyboard Navigation**
- All links must be keyboard accessible
- Visible focus states
- Logical tab order
3. **Semantic HTML**
- Proper heading hierarchy (h1 → h2 → h3)
- Descriptive link text (not just "click here")
- Alt text for images (if any)
## Quality Checklist
Before finalizing the index page:
- [ ] Branding detection executed correctly
- [ ] Appropriate colors applied
- [ ] Proper fonts loaded (if external fonts used)
- [ ] All TYPO3 version links present
- [ ] Backend credentials displayed
- [ ] Responsive design works on mobile/tablet/desktop
- [ ] Color contrast passes WCAG AA
- [ ] No console errors
- [ ] File copied to /var/www/html/
- [ ] Accessible at https://{sitename}.ddev.site/
## Integration with SKILL.md
**In Step 8 of SKILL.md, replace the current text with:**
```markdown
### Step 8: Generate Project Overview Page
**Automatic branding detection:**
The overview page automatically detects and applies appropriate branding:
1. **Check for branding skills** (netresearch-branding, company-branding, etc.)
2. **Apply detected branding** (colors, fonts, layout)
3. **Fallback to TYPO3 branding** (orange #FF8700) if no branding detected
4. **Generate responsive HTML** with cards for each TYPO3 version
**Generation process:**
```bash
# Skill automatically:
# 1. Detects available branding (netresearch-branding skill if present)
# 2. Applies brand colors and fonts
# 3. Creates .ddev/web-build/index.html
# 4. Copies to /var/www/html/
# Manual copy if needed:
ddev exec cp /var/www/hello_world/.ddev/web-build/index.html /var/www/html/
```
**See:** `INDEX-PAGE-GENERATION.md` for complete branding detection logic
```
## Example Detection Logic (Pseudocode)
```python
def generate_index_page():
# Step 1: Detect branding
branding = detect_branding()
if branding == "netresearch":
colors = {
"primary": "#2F99A4",
"text": "#585961",
"background": "#FFFFFF"
}
fonts = {
"headline": "Raleway",
"body": "Open Sans"
}
header_padding = "20px"
elif branding == "company-specific":
# Load company branding
colors = load_company_colors()
fonts = load_company_fonts()
else: # TYPO3 fallback
colors = {
"primary": "#FF8700",
"text": "#333333",
"background": "#F8F9FA"
}
fonts = {
"headline": "system-ui",
"body": "system-ui"
}
header_padding = "40px"
# Step 2: Generate HTML
html = generate_html_template(colors, fonts, header_padding)
# Step 3: Write file
write_file(".ddev/web-build/index.html", html)
# Step 4: Copy to web root
copy_to_web_root()
```
---
**This approach ensures:**
- ✅ Automatic branding application
- ✅ Consistent professional appearance
- ✅ Graceful fallback to TYPO3 branding
- ✅ Company branding when available
- ✅ No manual branding decisions needed

View File

@@ -0,0 +1,242 @@
## Prerequisites Validation
Before proceeding with ANY DDEV commands, especially on first DDEV command during a session, perform comprehensive validation:
### 1. Docker Daemon Status
**Check if Docker daemon is running:**
```bash
docker info >/dev/null 2>&1
```
**If Docker daemon is NOT running:**
```
❌ Docker daemon is not running.
Start Docker daemon based on your platform:
🐧 Linux/WSL2:
sudo service docker start
# or
sudo systemctl start docker
# Verify:
sudo systemctl status docker
🍎 macOS:
- Open Docker Desktop application
- Wait for whale icon to show "Docker Desktop is running"
# Verify from terminal:
docker info
🪟 Windows:
- Open Docker Desktop application
- Wait for notification "Docker Desktop is running"
# Verify from PowerShell/CMD:
docker info
After starting Docker, please retry the command.
```
### 2. Docker CLI Version
**Check Docker version (minimum: 20.10):**
```bash
docker version --format '{{.Client.Version}}'
```
**Expected output:** Version >= 20.10 (e.g., `24.0.7`, `25.0.0`)
**If version is too old or missing:**
```
❌ Docker CLI is outdated or missing.
Minimum required version: 20.10
Current version: [detected or "not found"]
Update Docker:
🐧 Linux:
# Ubuntu/Debian
curl -fsSL https://get.docker.com | sh
# Or follow: https://docs.docker.com/engine/install/
🍎 macOS:
brew upgrade --cask docker
# Or download from: https://www.docker.com/products/docker-desktop/
🪟 Windows:
# Update via Docker Desktop app or download from:
https://www.docker.com/products/docker-desktop/
```
### 3. Docker Compose Version
**Check Docker Compose version (minimum: 2.0):**
```bash
docker compose version --short
```
**Expected output:** Version >= 2.0 (e.g., `2.23.3`, `2.24.0`)
**Note:** Modern Docker includes Compose v2 as `docker compose` (not `docker-compose`)
**If version is too old or missing:**
```
❌ Docker Compose is outdated or using legacy v1.
Minimum required version: 2.0
Current version: [detected or "not found"]
Docker Compose v2 is included with Docker Desktop 3.4+ and Docker CLI 20.10+
Solutions:
🐧 Linux:
# If using legacy docker-compose v1:
sudo apt remove docker-compose
# Compose v2 is included with Docker 20.10+
# Verify installation:
docker compose version
# If missing, install Docker CLI with Compose plugin:
sudo apt-get install docker-compose-plugin
🍎 macOS / 🪟 Windows:
# Included in Docker Desktop - update to latest:
brew upgrade --cask docker # macOS
# Or download latest Docker Desktop
```
### 4. DDEV Installation
**Check if DDEV is installed:**
```bash
ddev version
```
**If DDEV is not installed:**
```
❌ DDEV is not installed.
Install DDEV based on your platform:
🍎 macOS:
brew install ddev/ddev/ddev
🐧 Linux:
# Ubuntu/Debian
curl -fsSL https://raw.githubusercontent.com/ddev/ddev/master/scripts/install_ddev.sh | bash
# Or see: https://ddev.readthedocs.io/en/stable/users/install/ddev-installation/
🪟 Windows:
choco install ddev
# Or see: https://ddev.readthedocs.io/en/stable/users/install/ddev-installation/
```
### 5. TYPO3 Extension Project Validation
**Confirm current directory is a TYPO3 extension:**
- Check for `ext_emconf.php` file
- OR check `composer.json` has `type: "typo3-cms-extension"`
- Check for typical TYPO3 extension structure (Classes/, Configuration/, Resources/)
**If not a TYPO3 extension:**
```
❌ This doesn't appear to be a TYPO3 extension project.
Requirements:
- ext_emconf.php file present
OR
- composer.json with "type": "typo3-cms-extension"
Current directory: [show path]
```
### 6. Existing DDEV Setup Check
**Check if `.ddev/` directory already exists:**
```bash
test -d .ddev && echo "DDEV config exists" || echo "No DDEV config"
```
**If `.ddev/` exists:**
```
⚠️ DDEV configuration already exists.
Do you want to:
1. Keep existing configuration (skip setup)
2. Overwrite with new configuration
3. Backup existing and create new
Please choose: [1/2/3]
```
### Prerequisites Validation Summary
**Run ALL checks before proceeding:**
```bash
# Quick validation script
echo "🔍 Validating prerequisites..."
# 1. Docker daemon
if docker info >/dev/null 2>&1; then
echo "✅ Docker daemon: Running"
else
echo "❌ Docker daemon: Not running"
exit 1
fi
# 2. Docker version
DOCKER_VERSION=$(docker version --format '{{.Client.Version}}' 2>/dev/null | cut -d. -f1,2)
if [ -n "$DOCKER_VERSION" ] && [ "$(printf '%s\n' "20.10" "$DOCKER_VERSION" | sort -V | head -n1)" = "20.10" ]; then
echo "✅ Docker CLI: $DOCKER_VERSION (>= 20.10)"
else
echo "❌ Docker CLI: Version check failed (need >= 20.10)"
exit 1
fi
# 3. Docker Compose version
COMPOSE_VERSION=$(docker compose version --short 2>/dev/null | cut -d. -f1)
if [ -n "$COMPOSE_VERSION" ] && [ "$COMPOSE_VERSION" -ge 2 ]; then
echo "✅ Docker Compose: $(docker compose version --short) (>= 2.0)"
else
echo "❌ Docker Compose: Version check failed (need >= 2.0)"
exit 1
fi
# 4. DDEV
if command -v ddev >/dev/null 2>&1; then
echo "✅ DDEV: $(ddev version | head -n1)"
else
echo "❌ DDEV: Not installed"
exit 1
fi
# 5. TYPO3 Extension
if [ -f "ext_emconf.php" ] || grep -q '"type".*"typo3-cms-extension"' composer.json 2>/dev/null; then
echo "✅ TYPO3 Extension: Detected"
else
echo "❌ TYPO3 Extension: Not detected"
exit 1
fi
echo ""
echo "✅ All prerequisites validated successfully!"
```
**Critical:** Always run these checks on the FIRST DDEV command in a session to catch environment issues early.
If any prerequisite fails, provide clear instructions on how to resolve it before proceeding.

292
references/quickstart.md Normal file
View File

@@ -0,0 +1,292 @@
# Quick Start Guide
This guide walks you through setting up DDEV for your TYPO3 extension using this skill.
## Prerequisites Check
Before starting, verify:
```bash
# Check DDEV
ddev version
# Expected: DDEV version v1.22+
# Check Docker
docker ps
# Expected: List of containers or empty (no error)
# Check you're in a TYPO3 extension directory
ls ext_emconf.php
# Expected: ext_emconf.php file exists
```
## Step 1: Install the Skill
```bash
cd ~/.claude/skills/
git clone https://github.com/netresearch/typo3-ddev-skill.git
```
## Step 2: Navigate to Your Extension
```bash
cd ~/projects/my-typo3-extension
```
## Step 3: Invoke the Skill in Claude Code
Open Claude Code and type:
```
Set up DDEV for this TYPO3 extension
```
Or use the slash command (if configured):
```
/typo3-ddev
```
## Step 4: Follow the Prompts
The skill will:
1. **Detect** your extension:
```
✅ Found TYPO3 extension: my_ext
```
2. **Extract** metadata:
```
Extension Key: my_ext
Package Name: vendor/my-ext
DDEV Sitename: my-ext
Vendor Namespace: Vendor\MyExt
```
3. **Confirm** with you:
```
Is this correct? (y/n)
```
4. **Generate** .ddev configuration files
5. **Start** DDEV (if you approve)
## Step 5: Install TYPO3
Once DDEV is running:
```bash
# Install all versions (recommended for first time)
ddev install-all
# Or install specific version
ddev install-v13
```
Wait 2-5 minutes per version for installation.
## Step 6: Access Your Environment
Open in your browser:
- **Overview**: https://my-ext.ddev.site/
- **TYPO3 13 Backend**: https://v13.my-ext.ddev.site/typo3/
- Username: `admin`
- Password: `Password:joh316`
## Step 7: Start Developing
Your extension source code is in the project root. Any changes you make will immediately reflect in all TYPO3 versions because the code is bind-mounted.
### Typical Development Workflow
```bash
# 1. Make changes to your extension code
vim Classes/Controller/MyController.php
# 2. Clear TYPO3 cache
ddev exec -d /var/www/html/v13 vendor/bin/typo3 cache:flush
# 3. Test in browser
# Open https://v13.my-ext.ddev.site/
# 4. Check logs if needed
ddev logs
```
## Next Steps
### Enable XDebug
```bash
ddev xdebug on
# Configure your IDE to connect to localhost:9003
```
### Add Database Fixtures
```bash
# Import database
ddev import-db --file=fixtures/database.sql
# Export database
ddev export-db > backup.sql.gz
```
### Run Tests
```bash
# Unit tests
ddev exec vendor/bin/phpunit Tests/Unit/
# Functional tests
ddev exec vendor/bin/phpunit Tests/Functional/
```
### Access Database
```bash
# MySQL CLI
ddev mysql
# Or use a GUI tool:
# Host: 127.0.0.1
# Port: (run `ddev describe` to get the port)
# User: root
# Password: root
```
## Common Tasks
### Restart DDEV
```bash
ddev restart
```
### Stop DDEV
```bash
ddev stop
```
### Remove Environment (keeps volumes)
```bash
ddev delete
```
### Complete Cleanup (removes everything)
```bash
ddev delete --omit-snapshot --yes
docker volume rm my-ext-v11-data my-ext-v12-data my-ext-v13-data
```
### SSH into Container
```bash
ddev ssh
# You're now inside the container
cd /var/www/html/v13
# Do stuff
exit
```
## Troubleshooting
### Port Already in Use
```bash
# Edit .ddev/config.yaml
router_http_port: "8080"
router_https_port: "8443"
ddev restart
```
### Installation Hangs or Fails
```bash
# Check logs
ddev logs
# Retry installation
ddev ssh
rm -rf /var/www/html/v13/*
exit
ddev install-v13
```
### Extension Not Found
```bash
# Verify environment variables
ddev ssh
echo $EXTENSION_KEY
echo $PACKAGE_NAME
# Check Composer setup
cd /var/www/html/v13
composer show $PACKAGE_NAME
```
### Clear Everything and Start Over
```bash
ddev delete --omit-snapshot --yes
rm -rf .ddev/
# Then re-run the skill setup
```
## Example Project Structure
After setup, your project should look like:
```
my-typo3-extension/
├── .ddev/ # DDEV configuration (generated)
│ ├── config.yaml
│ ├── docker-compose.web.yaml
│ ├── apache/
│ ├── web-build/
│ └── commands/
├── Classes/ # Your extension PHP classes
├── Configuration/ # Your extension configuration
├── Resources/ # Your extension resources
├── Tests/ # Your extension tests
├── composer.json # Your extension composer config
├── ext_emconf.php # TYPO3 extension declaration
└── README.md # Your extension documentation
```
## Tips for Extension Development
1. **Use Multiple Terminals**:
- Terminal 1: Code editing
- Terminal 2: `ddev logs -f` (follow logs)
- Terminal 3: `ddev ssh` (run commands)
2. **Cache Management**:
- Development: Clear cache frequently
- Use `ddev exec -d /var/www/html/v13 vendor/bin/typo3 cache:flush`
3. **Version Testing**:
- Test critical changes across all versions
- Use `ddev install-all` to have all versions ready
4. **Backup Important Data**:
- Export databases before major changes
- Use `ddev export-db --gzip=false > backup.sql`
5. **Keep DDEV Updated**:
```bash
ddev version # Check current version
# Update via your package manager (brew, apt, etc.)
```
---
**Happy TYPO3 Extension Development! 🚀**

View File

@@ -0,0 +1,75 @@
## Error Handling
### Common Issues and Solutions
**1. Prerequisites Not Met**
```
❌ Prerequisites validation failed.
One or more requirements are not met:
- Docker daemon not running
- Docker CLI outdated (need >= 20.10)
- Docker Compose outdated (need >= 2.0)
- DDEV not installed
See "Prerequisites Validation" section above for detailed:
- Platform-specific installation instructions
- Version requirement details
- Validation script you can run
Run the validation script to identify which prerequisite is failing.
```
**2. Docker Daemon Not Running (Most Common)**
```
❌ Docker daemon is not running.
Quick fix for your platform:
🐧 Linux/WSL2:
sudo service docker start
🍎 macOS:
Open Docker Desktop application
🪟 Windows:
Open Docker Desktop application
For detailed instructions, see Prerequisites Validation section.
After starting Docker, run: docker info
```
**3. Not a TYPO3 Extension**
```
❌ This doesn't appear to be a TYPO3 extension project.
Requirements:
- ext_emconf.php file present
OR
- composer.json with "type": "typo3-cms-extension"
Current directory: /path/to/project
```
**4. Port Conflicts**
```
❌ DDEV failed to start (port 80/443 conflict)
Solutions:
- Stop other local web servers (Apache, Nginx, MAMP)
- Or use different ports in .ddev/config.yaml:
router_http_port: "8080"
router_https_port: "8443"
```
**5. Installation Failures**
```
❌ TYPO3 installation failed
Troubleshooting:
1. Check logs: ddev logs
2. SSH into container: ddev ssh
3. Check Composer: ddev composer diagnose
4. Try reinstalling: rm -rf /var/www/html/v13/* && ddev install-v13
```

297
references/windows-fixes.md Normal file
View File

@@ -0,0 +1,297 @@
# Windows-Specific DDEV Issues and Fixes
## Critical Issue: Health Check Failures
**Symptom:** `ddev start` hangs at "Waiting for containers to become ready" indefinitely
**Root Cause:** Custom Apache configurations override DDEV's default `/phpstatus` endpoint, causing health checks to fail
**Fix:** Always include PHP-FPM status endpoint in custom Apache configs
```apache
# CRITICAL: PHP-FPM status endpoint (required for DDEV health checks)
# Place this BEFORE any VirtualHost declarations
<Location /phpstatus>
SetHandler "proxy:unix:/run/php-fpm.sock|fcgi://localhost"
</Location>
```
**Correct Socket Path:** `/run/php-fpm.sock` (NOT `/run/php-fpm-socket/php-fpm.sock`)
**Verification:**
```bash
# After DDEV starts, verify health check passes:
ddev exec /healthcheck.sh
# Should output: /var/www/html:OK mailpit:OK phpstatus:OK
```
## Line Ending Issues
**Symptom:** `Command 'install-v12' contains CRLF, please convert to Linux-style linefeeds`
**Root Cause:** Files created on Windows have CRLF line endings; DDEV requires LF
**Fix:** Convert line endings after file creation **while preserving UTF-8 encoding for emojis**
```powershell
# PowerShell command to convert CRLF to LF (preserving UTF-8 for emojis)
# IMPORTANT: Must use -Raw flag, UTF-8 encoding, and proper replacement
foreach ($file in @('.ddev\commands\web\install-v12', '.ddev\commands\web\install-v13', '.ddev\commands\host\docs')) {
$content = Get-Content $file -Raw -Encoding UTF8
$content = $content -replace "`r`n", "`n"
[System.IO.File]::WriteAllText((Resolve-Path $file).Path, $content, [System.Text.UTF8Encoding]::new($false))
}
```
**Common Mistakes:**
- ❌ Using `(Get-Content $file)` without `-Raw` flag loses all line breaks
- ❌ Using `-Encoding ASCII` corrupts emojis (🚀 → ??)
- ✅ Must use UTF-8 encoding to preserve emoji characters
**Prevention:** Configure Git to handle line endings:
```bash
git config --global core.autocrlf input
```
## Router Not Starting Automatically
**Symptom:** Sites return 404, `docker ps | grep router` shows no router
**Root Cause:** On Windows, DDEV may fail to start the traefik router automatically
**Diagnostic:**
```bash
ddev describe
# If "SERVICE" table is empty, router didn't start
```
**Fix 1:** Restart DDEV after fixing health checks
```bash
ddev restart
# Router should start automatically if health checks pass
```
**Fix 2:** Check router status manually
```bash
docker ps -a | grep router
# If stopped, check logs:
docker logs ddev-router
```
## Mutagen Sync Issues
**Symptom:** `Mutagen Docker volume is not mounted. Please use 'ddev restart'`
**Root Cause:** Mutagen file sync can be problematic on Windows
**Fix:** Disable Mutagen and use direct bind mounts
```bash
ddev config --performance-mode=none
ddev restart
```
**Note:** Direct mounts may be slower but more reliable on Windows
## Docker Volume Permission Issues
**Symptom:** `Permission denied` when writing to `/var/www/html/vXX/composer.json`
**Root Cause:** Docker volumes on Windows are owned by root; web user can't write
**Solution:** Use `sudo chown` at the start of install scripts
```bash
#!/bin/bash
VERSION=v13
INSTALL_DIR=/var/www/html/$VERSION
# Fix permissions before writing (critical for Windows)
sudo rm -rf $INSTALL_DIR/*
sudo mkdir -p $INSTALL_DIR
sudo chown -R $(whoami):$(whoami) $INSTALL_DIR
# Now can write files
cd $INSTALL_DIR
echo "{}" > composer.json # Works!
```
**Why This Works:**
- Volumes are faster than bind mounts on Windows
- `sudo chown` fixes ownership without performance penalty
- Only needed once at the start of installation
**Bind Mounts Alternative (slower but simpler):**
```yaml
# In .ddev/docker-compose.web.yaml
volumes:
- type: bind
source: ./typo3-installations/v12
target: /var/www/html/v12
```
⚠️ Bind mounts are significantly slower on Windows
## Complete Apache Config Template (Windows-Safe)
```apache
# CRITICAL: PHP-FPM status endpoint (MUST be first)
<Location /phpstatus>
SetHandler "proxy:unix:/run/php-fpm.sock|fcgi://localhost"
</Location>
# Main project overview
<VirtualHost *:80>
ServerName {{DDEV_SITENAME}}.ddev.site
DocumentRoot /var/www/html
<Directory /var/www/html>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
# Additional VirtualHosts for multi-version setup
<VirtualHost *:80>
ServerName v12.{{DDEV_SITENAME}}.ddev.site
DocumentRoot /var/www/html/v12/public
<Directory /var/www/html/v12/public>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
# Add more VirtualHosts as needed...
```
## Debugging Steps
### 1. Check Container Health
```bash
docker inspect ddev-{{SITENAME}}-web --format='{{.State.Health.Status}}'
# Should be: healthy
```
### 2. Check Health Check Output
```bash
ddev exec /healthcheck.sh
# Should output: /var/www/html:OK mailpit:OK phpstatus:OK
```
### 3. Check PHP-FPM Socket
```bash
ddev exec ls -la /run/php-fpm.sock
# Should exist and be a socket
```
### 4. Test phpstatus Endpoint
```bash
ddev exec curl -f http://localhost/phpstatus
# Should return PHP-FPM status page
```
### 5. Check Router
```bash
docker ps | grep router
# Should show ddev-router container running and healthy
```
### 6. Check Traefik Logs
```bash
docker logs ddev-router --tail 50
# Look for routing errors
```
## Documentation Rendering (Host Commands)
**Symptom:** `ddev docs` command executes but produces no output, or Docker mount fails
**Root Cause:** Windows paths require special handling in DDEV host commands (Git Bash/WSL)
**Fix:** Use double-slash prefix for Docker volume mounts
```bash
#!/bin/bash
# For Windows compatibility - ensure path format works for Docker
if [[ "$OSTYPE" == "msys" ]]; then
# Git Bash on Windows - use double slash prefix
DOCKER_MOUNT="//$(pwd)"
else
DOCKER_MOUNT="$(pwd)"
fi
docker run --rm \
-v "$DOCKER_MOUNT:/project" \
ghcr.io/typo3-documentation/render-guides:latest \
--config=Documentation
```
**Path Transformation:**
- PowerShell: `C:\Users\live\project`
- Git Bash: `/c/Users/live/project`
- Docker (Windows): `//c/Users/live/project` (double slash prefix required)
## TYPO3 12 Database Setup Issue
**Symptom:** `install:setup` tries to create database repeatedly and fails
```
ERROR: Unable to create database
Database with name "v12" could not be created...
➤ Select database
```
**Root Cause:** TYPO3 12's `install:setup` tries to create the database itself
**Solution:** Use `--use-existing-database` flag
```bash
# Create database first
mysql -h db -u root -proot -e "CREATE DATABASE v12;"
# Then use existing database
vendor/bin/typo3 install:setup -n --database-name v12 --use-existing-database
```
**TYPO3 13 Comparison:**
TYPO3 13's `setup` command works differently and doesn't have this issue.
## Prevention Checklist
Before running `ddev start` on Windows:
- [ ] Apache config includes `/phpstatus` endpoint with correct socket path
- [ ] All script files in `.ddev/commands/` use LF line endings (with `-Raw` flag)
- [ ] Host commands use `//$(pwd)` for Docker mounts on Windows
- [ ] Git configured with `core.autocrlf=input`
- [ ] Mutagen disabled if experiencing sync issues
- [ ] Increased timeout: `ddev config --default-container-timeout=600`
## Quick Recovery
If DDEV is stuck or broken:
```bash
# 1. Stop everything
ddev poweroff
# 2. Remove any manual router
docker rm -f ddev-router
# 3. Fix Apache config (add phpstatus endpoint)
# 4. Fix line endings in command scripts
# 5. Disable Mutagen if needed
ddev config --performance-mode=none
# 6. Start with increased timeout
ddev config --default-container-timeout=600
ddev start
```
## Success Criteria
DDEV is properly working when:
1.`ddev start` completes without hanging
2.`ddev describe` shows all services with URLs
3.`ddev exec /healthcheck.sh` returns all OK
4. ✅ Browser can access `https://{{SITENAME}}.ddev.site`
5.`docker ps | grep router` shows healthy router

View File

@@ -0,0 +1,148 @@
# Windows Performance Optimizations
## Key Learnings
### 1. Use Docker Volumes (Not Bind Mounts)
**Performance Impact:** 3-5x faster installations
```yaml
# ✅ FAST: Docker volumes
volumes:
v12-data:/var/www/html/v12
v13-data:/var/www/html/v13
# ❌ SLOW: Bind mounts
volumes:
- type: bind
source: ./typo3-installations/v12
target: /var/www/html/v12
```
**Why:** Docker Desktop on Windows translates filesystem calls between Windows and Linux, making bind mounts significantly slower.
### 2. Fix Volume Permissions with sudo chown
```bash
# At start of install scripts
INSTALL_DIR=/var/www/html/v13
sudo rm -rf $INSTALL_DIR/*
sudo mkdir -p $INSTALL_DIR
sudo chown -R $(whoami):$(whoami) $INSTALL_DIR
```
This is the **critical Windows fix** that makes volumes work.
### 3. Preserve UTF-8 When Converting Line Endings
```powershell
# ✅ CORRECT: Preserves emojis
$content = Get-Content $file -Raw -Encoding UTF8
$content = $content -replace "`r`n", "`n"
[System.IO.File]::WriteAllText((Resolve-Path $file).Path, $content, [System.Text.UTF8Encoding]::new($false))
# ❌ WRONG: Corrupts emojis (🚀 → ??)
(Get-Content $file -Raw) -replace "`r`n", "`n" | Set-Content -NoNewline -Encoding ASCII $file
```
### 4. Install Commands: Use Shared Base Script
**DRY Principle:** Don't repeat 70+ lines of installation logic
```bash
# .ddev/commands/web/install-base (80 lines, shared)
install_typo3() {
# All common installation logic
}
# .ddev/commands/web/install-v13 (16 lines)
source /mnt/ddev_config/commands/web/install-base
SETUP_CMD="vendor/bin/typo3 setup -n ..."
install_typo3 "v13" "^13" "$SETUP_CMD"
# .ddev/commands/web/install-v12 (16 lines)
source /mnt/ddev_config/commands/web/install-base
SETUP_CMD="vendor/bin/typo3 install:setup -n --use-existing-database ..."
install_typo3 "v12" "^12" "$SETUP_CMD"
```
### 5. TYPO3 Version Differences
| Version | Setup Command | Database Creation | Extension Activation |
|---------|--------------|-------------------|---------------------|
| TYPO3 13 | `setup` | External (mysql) | `extension:setup` |
| TYPO3 12 | `install:setup --use-existing-database` | External (mysql) | Automatic |
## Installation Speed Comparison
| Method | v13 Install Time | Notes |
|--------|-----------------|-------|
| Bind mounts | ~10-15 min | ❌ Very slow on Windows |
| Volumes + sudo chown | ~3-5 min | ✅ Fast and working |
| Volumes (no chown) | N/A | ❌ Permission denied errors |
## Common Pitfalls
### ❌ Pitfall 1: Using Bind Mounts for Speed
```yaml
# Don't do this on Windows!
volumes:
- ./typo3-installations/v12:/var/www/html/v12
```
**Impact:** 3x slower installations
### ❌ Pitfall 2: Forgetting sudo chown
```bash
# This fails on Windows with volumes
echo "{}" > /var/www/html/v13/composer.json
# Permission denied!
```
### ❌ Pitfall 3: ASCII Encoding Corrupts Emojis
```powershell
# This breaks emojis in bash scripts
Set-Content -Encoding ASCII $file
```
### ❌ Pitfall 4: TYPO3 12 Database Creation
```bash
# This hangs/fails
vendor/bin/typo3 install:setup -n --database-name v12
# Missing: --use-existing-database
```
## Recommended Workflow
1. **Use skill templates** - They have the correct volume setup
2. **Add sudo chown** - Fix volume permissions (Windows-specific)
3. **Use UTF-8 encoding** - Preserve emojis when converting line endings
4. **Share install logic** - Use install-base for DRY principle
5. **Test both versions** - TYPO3 12 and 13 have different setup commands
## Windows-Specific .gitignore
```gitignore
# Don't commit these (Windows creates them)
.ddev/typo3-installations/
Thumbs.db
desktop.ini
```
## Quick Reference Commands
```powershell
# Convert to LF with UTF-8 (correct)
$file = '.ddev/commands/web/install-v13'
$content = Get-Content $file -Raw -Encoding UTF8
$content = $content -replace "`r`n", "`n"
[System.IO.File]::WriteAllText((Resolve-Path $file).Path, $content, [System.Text.UTF8Encoding]::new($false))
# Restart DDEV after config changes
ddev restart
# Check volume ownership
ddev exec ls -la /var/www/html/v13
# Fix permissions manually if needed
ddev exec sudo chown -R $(whoami):$(whoami) /var/www/html/v13
```

116
scripts/validate-prerequisites.sh Executable file
View File

@@ -0,0 +1,116 @@
#!/bin/bash
# TYPO3 DDEV Prerequisites Validation Script
# Auto-generated by enhanced typo3-ddev skill
#
# This script validates all prerequisites for DDEV TYPO3 development:
# - Docker daemon running
# - Docker CLI version >= 20.10
# - Docker Compose version >= 2.0
# - DDEV installed
# - TYPO3 extension project structure
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo "🔍 Validating TYPO3 DDEV Prerequisites..."
echo ""
FAILED=0
# 1. Docker daemon
echo -n "Checking Docker daemon... "
if docker info >/dev/null 2>&1; then
echo -e "${GREEN}✅ Running${NC}"
else
echo -e "${RED}❌ Not running${NC}"
echo ""
echo "Docker daemon is not running. Start it with:"
echo " Linux/WSL2: sudo service docker start"
echo " macOS: Open Docker Desktop"
echo " Windows: Open Docker Desktop"
FAILED=1
fi
# 2. Docker version
echo -n "Checking Docker CLI version... "
DOCKER_VERSION=$(docker version --format '{{.Client.Version}}' 2>/dev/null || echo "")
if [ -n "$DOCKER_VERSION" ]; then
MAJOR=$(echo "$DOCKER_VERSION" | cut -d. -f1)
MINOR=$(echo "$DOCKER_VERSION" | cut -d. -f2)
if [ "$MAJOR" -gt 20 ] || ([ "$MAJOR" -eq 20 ] && [ "$MINOR" -ge 10 ]); then
echo -e "${GREEN}$DOCKER_VERSION (>= 20.10)${NC}"
else
echo -e "${YELLOW}⚠️ $DOCKER_VERSION (need >= 20.10)${NC}"
echo " Update Docker to version 20.10 or newer"
FAILED=1
fi
else
echo -e "${RED}❌ Not installed${NC}"
FAILED=1
fi
# 3. Docker Compose version
echo -n "Checking Docker Compose version... "
COMPOSE_VERSION=$(docker compose version --short 2>/dev/null || echo "")
if [ -n "$COMPOSE_VERSION" ]; then
COMPOSE_MAJOR=$(echo "$COMPOSE_VERSION" | cut -d. -f1)
if [ "$COMPOSE_MAJOR" -ge 2 ]; then
echo -e "${GREEN}$COMPOSE_VERSION (>= 2.0)${NC}"
else
echo -e "${YELLOW}⚠️ $COMPOSE_VERSION (need >= 2.0)${NC}"
echo " Update to Docker Compose v2"
FAILED=1
fi
else
echo -e "${RED}❌ Not installed${NC}"
echo " Install Docker Compose v2 (included with Docker 20.10+)"
FAILED=1
fi
# 4. DDEV
echo -n "Checking DDEV installation... "
if command -v ddev >/dev/null 2>&1; then
DDEV_VERSION=$(ddev version 2>&1 | head -n1 | grep -oP 'v\K[0-9.]+' || echo "unknown")
echo -e "${GREEN}✅ v$DDEV_VERSION${NC}"
else
echo -e "${RED}❌ Not installed${NC}"
echo ""
echo "Install DDEV:"
echo " macOS: brew install ddev/ddev/ddev"
echo " Linux: curl -fsSL https://raw.githubusercontent.com/ddev/ddev/master/scripts/install_ddev.sh | bash"
echo " Windows: choco install ddev"
FAILED=1
fi
# 5. TYPO3 Extension (only check if in a directory, not fatal)
echo -n "Checking TYPO3 extension project... "
if [ -f "ext_emconf.php" ] || grep -q '"type".*"typo3-cms-extension"' composer.json 2>/dev/null; then
echo -e "${GREEN}✅ Detected${NC}"
else
echo -e "${YELLOW}⚠️ Not detected (optional check)${NC}"
echo " This check only matters if you're in an extension directory"
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if [ $FAILED -eq 0 ]; then
echo -e "${GREEN}✅ All prerequisites validated successfully!${NC}"
echo ""
echo "You can now run DDEV commands:"
echo " ddev start"
echo " ddev install-all"
exit 0
else
echo -e "${RED}❌ Prerequisites validation failed${NC}"
echo ""
echo "Please resolve the issues above before proceeding."
echo "For detailed instructions, see:"
echo " ~/.claude/plugins/marketplaces/netresearch-claude-code-marketplace/skills/typo3-ddev/SKILL.md"
exit 1
fi