Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:43:13 +08:00
commit f6d4a68978
178 changed files with 51030 additions and 0 deletions

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