Use when creating a new Symfony project, scaffolding a Symfony application, or setting up the project skeleton - covers directory structure, bundles, services config, Vite/pentatrion, DDEV, PHPUnit, base template, i18n, CAPTCHA, and deployment.
التثبيت
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
Use when creating a new Symfony project, scaffolding a Symfony application, or setting up the project skeleton - covers directory structure, bundles, services config, Vite/pentatrion, DDEV, PHPUnit, base template, i18n, CAPTCHA, and deployment.
Symfony Project Setup Blueprint
Related Skills
Need
Skill
Symfony framework components reference
symfony
Svelte 5 + TypeScript components (frontend)
svelte
DDEV configuration and commands
ddev-development
Overview
Standard blueprint for new Symfony 6/7 projects. Derived from production projects: consistent stack of DDEV + Vite (pentatrion) + Bootstrap 5 + TypeScript + Doctrine ORM + bilingual i18n.
{# Map current route to its counterpart in other locale #}
{% set route = app.request.attributes.get('_route') %}
{% set languageMapping = {
'app_index_de': 'app_index_en',
'app_index_en': 'app_index_de',
'app_imprint_de': 'app_imprint_en',
'app_imprint_en': 'app_imprint_de',
} %}
{% if languageMapping[route] is defined %}
<a href="{{ path(languageMapping[route]) }}" hreflang="{{ app.request.locale == 'de' ? 'en' : 'de' }}">
{{ app.request.locale == 'de' ? 'EN' : 'DE' }}
</a>
{% endif %}
Translation Files
# translations/messages.de.yamlsite:title:'Mein Projekt'description:'Projektbeschreibung auf Deutsch'nav:home:'Startseite'contact:'Kontakt'imprint:'Impressum'privacy:'Datenschutz'contact:form:name:'Ihr Name'email:'E-Mail-Adresse'message:'Ihre Nachricht'submit:'Absenden'success:'Vielen Dank! Ihre Nachricht wurde gesendet.'
# translations/messages.en.yamlsite:title:'My Project'description:'Project description in English'nav:home:'Home'contact:'Contact'imprint:'Imprint'privacy:'Privacy Policy'contact:form:name:'Your name'email:'Email address'message:'Your message'submit:'Send'success:'Thank you! Your message has been sent.'
8. Altcha CAPTCHA Integration
Standard CAPTCHA pattern used across all projects (privacy-friendly alternative to reCAPTCHA):
ddev start
ddev composer install
ddev exec bin/console doctrine:migrations:migrate
ddev exec bin/console cache:clear
ddev npm install
ddev npm run build # Vite production build
ddev npm run dev # Vite dev server
ddev exec vendor/bin/phpunit # Run tests
10. PHPUnit Configuration
phpunit.xml.dist
<?xml version="1.0" encoding="UTF-8"?><phpunitxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"bootstrap="tests/bootstrap.php"colors="true"failOnRisky="true"failOnWarning="true"><php><ininame="display_errors"value="1"/><ininame="error_reporting"value="-1"/><servername="APP_ENV"value="test"force="true"/><servername="SHELL_VERBOSITY"value="-1"/><servername="SYMFONY_PHPUNIT_REMOVE"value=""/><servername="SYMFONY_PHPUNIT_VERSION"value="10"/></php><testsuites><testsuitename="Project Test Suite"><directory>tests</directory></testsuite></testsuites><source><include><directorysuffix=".php">src</directory></include></source><extensions><bootstrapclass="Symfony\Bridge\PhpUnit\SymfonyTestsListener"/></extensions></phpunit>
All Symfony projects follow the same deployment pattern: local pre-flight checks, local asset build, local composer prod install, rsync to server, remote cache/migration, restore local dev state.
Pipeline Overview
1. Pre-Deploy Gates (abort on failure)
├── PHPUnit
├── lint:twig
├── lint:yaml
└── lint:container
2. Asset Build + Verification
3. Composer install --no-dev (local, inside DDEV)
4. rsync to production server
5. Remote: cache:clear (triggers CacheWarmers)
6. Remote: doctrine:migrations:migrate
7. Remote: messenger:stop-workers (if applicable)
8. Restore local dev dependencies
deploy-prod.sh (Template)
#!/usr/bin/env bashset -euo pipefail
# ── Configuration ────────────────────────────────────────────────
TARGET_DIR="/srv/www/vhosts/example.com/httpdocs/"
SERVER="suse16"
OWNER_USER="nginx"
OWNER_GROUP="nginx"echo"🚀 Starte Deployment..."# ── Pre-Deploy Gates ─────────────────────────────────────────────# All gates run inside DDEV. Any failure aborts the deploy (set -e).echo"🔍 Pre-Deploy-Prüfungen..."echo" ▸ PHPUnit..."
ddev exec vendor/bin/phpunit
echo" ▸ Twig-Lint..."
ddev exec bin/console lint:twig templates/
echo" ▸ YAML-Lint..."
ddev exec bin/console lint:yaml translations/ config/
echo" ▸ Container-Lint..."
ddev exec bin/console lint:container
echo"✅ Alle Pre-Deploy-Prüfungen bestanden."# ── Asset Build + Verification ───────────────────────────────────
ddev exec npm run build
for asset in public/assets/css/all.css public/assets/js/app.js; doif [ ! -s "$asset" ]; thenecho"❌ Kritisches Asset fehlt oder ist leer: $asset"exit 1
fidoneecho"🏗️ Assets erfolgreich gebaut und verifiziert."# ── Composer: Strip Dev Dependencies ─────────────────────────────# Install production-only deps locally so rsync sends a clean vendor/.
ddev exec composer install --no-dev --classmap-authoritative --no-scripts --no-interaction
echo"📦 Composer-Dependencies (ohne Dev) lokal installiert."# ── Rsync ────────────────────────────────────────────────────────# --chown sets ownership on the remote side (requires rsync 3.1+).# --delete removes files on remote that no longer exist locally.
rsync -av -zz --delete --stats \
--chown="$OWNER_USER:$OWNER_GROUP" \
--exclude=".ddev" --exclude=".idea" --exclude="/var/" \
--exclude=".env" --exclude=".env.*" --exclude="node_modules" \
--exclude=".git" --exclude=".gitignore" --exclude=".editorconfig" \
--exclude=".claude" --exclude=".ralph" --exclude=".ralphrc" \
--exclude="CLAUDE.md" --exclude="code-conventions.md" \
--exclude="templates/assets/node" --exclude="templates/assets/ts" \
--exclude="templates/assets/js" --exclude="templates/assets/scss" \
--exclude="vite.config.js" --exclude="tsconfig.json" \
--exclude="package.json" --exclude="package-lock.json" \
--exclude="deploy-prod.sh" --exclude="deploy-stage.sh" \
--exclude="phpunit.xml.dist" --exclude="tests/" --exclude="e2e/" \
--exclude="playwright.config.*" \
--exclude=".htmlvalidate.json" \
/path/to/project/ "$SERVER:$TARGET_DIR"echo"✅ Dateien erfolgreich synchronisiert (Owner: $OWNER_USER:$OWNER_GROUP)."# ── Remote: Cache Clear ──────────────────────────────────────────# Runs as web server user. Triggers all CacheWarmerInterface implementations.
ssh "$SERVER""cd $TARGET_DIR && sudo -u $OWNER_USER ./bin/console cache:clear"echo"🧹 Symfony Cache wurde erfolgreich geleert!"# ── Remote: Doctrine Migrations ──────────────────────────────────
ssh "$SERVER""cd $TARGET_DIR && sudo -u $OWNER_USER ./bin/console doctrine:migrations:migrate --no-interaction"echo"📦 Datenbank-Migration erfolgreich durchgeführt."# ── Remote: Restart Messenger Workers (if applicable) ────────────# Uncomment if the project uses Symfony Messenger:# ssh "$SERVER" "cd $TARGET_DIR && sudo -u $OWNER_USER ./bin/console messenger:stop-workers" || true# ── Restore Local Dev Dependencies ───────────────────────────────
ddev exec composer install --no-interaction
echo"🔄 Composer Dev-Dependencies lokal wiederhergestellt."echo"🎉 Deployment erfolgreich abgeschlossen."
Key Design Decisions
Decision
Rationale
Pre-deploy gates run in DDEV
Tests use the same PHP/DB as dev — no "works on my machine"
set -euo pipefail
Any failing gate aborts the entire deploy
Asset verification loop
Catches silent build failures (empty CSS/JS)
Composer --no-dev locally
rsync sends a clean vendor/ without dev packages — no composer needed on server
--chown in rsync
Sets ownership atomically during transfer — no separate chown -R ssh call needed
--delete in rsync
Removes orphaned files on remote (clean deploys)
cache:clear via sudo -u nginx
Web server user must own the generated cache files
Restore dev deps at end
Local dev environment stays functional after deploy
Rsync Excludes (Standard Set)
These excludes apply to all projects. Add project-specific excludes as needed.