Skip to content

Repository files navigation

Symfony Initializr

PHP Symfony FrankenPHP Bootstrap Docker

Live: symfony-init.dev

Язык / Language: Русский · English


Веб-сервис генерации Symfony-проектов с Docker

Выберите параметры проекта и получите ZIP с готовым Symfony-приложением под Docker. Запуск: docker compose up.

Скриншот интерфейса

Главная страница Symfony Initializr


Возможности

  • Параметры: имя проекта, PHP, сервер (PHP-FPM + Nginx или FrankenPHP), версия Symfony (LTS и текущие - с symfony.com).
  • База данных: без БД, PostgreSQL, MySQL, MariaDB, SQLite. Связка с чекбоксом Doctrine ORM: выбор БД включает ORM, выбор ORM подставляет PostgreSQL при "без БД". В Docker - образы на Alpine где есть (postgres, redis, memcached, rabbitmq).
  • Кеш: селект None / Redis / Memcached. В проект добавляются контейнер, PHP-расширение и CACHE_DSN в .env.
  • Расширения: Doctrine ORM, Security, Mailer, Messenger, Validator, Serializer, API Platform, HTTP Client, Nelmio API Doc. Зависимости подставляются автоматически (API Platform -> ORM + Serializer + Nelmio; RabbitMQ -> Messenger).
  • Message broker: опция RabbitMQ - контейнер RabbitMQ с management и MESSENGER_TRANSPORT_DSN в .env.
  • Генерация: скелет через composer create-project, подстановка Dockerfile, docker-compose, конфиг веб-сервера (Nginx / Caddyfile). Рецепты Flex не дублируют наши сервисы (SYMFONY_SKIP_DOCKER=1, очистка блоков рецептов в compose).
  • Скачивание: кнопка блокируется до ответа, архив через fetch. При лимите - сообщение и время повтора.
  • Асинхронная сборка: закэшированная конфигурация отдаётся сразу (200 с архивом). Иначе /generate возвращает 202 с job_id, сборкой занимается Messenger-воркер, фронт опрашивает /generate/status/{jobId} и скачивает /generate/download/{jobId}. HTTP-воркер не занят на время composer.
  • Кеширование: по комбинации параметров (PHP, сервер, Symfony, расширения, БД, кеш, RabbitMQ) плюс ревизия шаблонов генератора. Каталоги сборок и готовые ZIP - в var/share/, кеш пакетов Composer - в отдельном volume.
  • Очистка диска: app:gc удаляет сборки и архивы с истёкшим кешем и остатки прерванных сборок, а также вытесняет самые старые записи при превышении бюджета APP_CACHE_MAX_MB. Сервис maintenance в compose раз в час запускает очистку и прогрев.
  • Один composer за раз: глобальный лок в общем volume не даёт двум сборкам идти параллельно — на VPS с малым объёмом RAM это защита от OOM.
  • Совместимость версий: Symfony 8 требует PHP 8.4+, Symfony 7 — 8.2+, Symfony 6.4 — 8.1+. Несовместимые пары отклоняются с кодом 400, в форме такие версии Symfony блокируются, а в --all-base пропускаются. Результат сборки дополнительно проверяется: composer умеет завершаться с кодом 0, напечатав ошибки резолва, поэтому наличие vendor/symfony/framework-bundle проверяется явно.
  • Лимит: 30 запросов в час на IP (учитывается реальный IP клиента при настроенном TRUSTED_PROXIES).

Безопасность и прозрачность

Проект открыт: вы можете просмотреть исходный код генератора и логику сборки архива до использования. Сгенерированный ZIP содержит только стандартный скелет Symfony, зависимости из Packagist и добавленные Docker/конфиги - без скрытого кода. Перед развёртыванием рекомендуем просмотреть содержимое архива.


Запуск

docker compose up -d --build

Сервис будет доступен по адресу: http://localhost:8080

Войти в контейнер:

docker compose exec frankenphp bash

Разработка

Стиль кода проверяется и исправляется с помощью PHP CS Fixer (правила @Symfony). Конфигурация - app/.php-cs-fixer.dist.php. Запуск внутри контейнера (из каталога приложения):

docker compose exec frankenphp bash
./vendor/bin/php-cs-fixer fix src

Прогрев кеша версий PHP/Symfony и сгенерированных проектов (по желанию):

# только популярные конфигурации (по умолчанию)
php bin/console app:warm-cache
php bin/console app:warm-cache --popular-only

# все базовые комбинации PHP × Symfony × сервер, без расширений/БД (дольше)
php bin/console app:warm-cache --all-base

# непрерывное обновление кеша циклами (так работает сервис maintenance)
php bin/console app:warm-cache --loop --interval=900

Полный перебор всех вариантов бессмысленен: расширения дают 512 подмножеств, вместе с PHP × Symfony × сервером × БД × кешем × RabbitMQ это ~370 000 комбинаций, то есть терабайты диска. Прогревать стоит базовую матрицу (24 комбинации, ~600 МБ) и популярные наборы.

Деплой на прод

Prod-конфигурация больше не монтирует исходники в контейнер: зависимости и прогретый кеш Symfony лежат в образе, поэтому после каждого git pull образ нужно пересобрать. Секреты передаются через файл .env рядом с compose-файлом (см. .env.example), потому что .env.local внутрь образа не попадает.

cp .env.example .env   # один раз: APP_SECRET, TRUSTED_PROXIES, APP_CACHE_MAX_MB
git pull
docker compose -f docker-compose.prod.yml up -d --build --remove-orphans
docker compose -f docker-compose.prod.yml exec frankenphp php bin/console app:gc
docker compose -f docker-compose.prod.yml exec frankenphp php bin/console app:warm-cache

Появились новые сервисы worker и maintenance — без них сборка проектов работать не будет, поэтому --remove-orphans и полный up, а не только перезапуск веб-контейнера.

Слабый VPS (512 МБ RAM, 10 ГБ диска)

  • Пик памяти сборки — около 210 МБ на воркер (самая тяжёлая конфигурация с API Platform), поэтому одновременная сборка разрешена только одна.
  • Стоит выделить 1-2 ГБ swap: composer при резолве зависимостей кратковременно требует много памяти.
  • APP_CACHE_MAX_MB в prod-compose выставлен в 1024 — кеш не съест диск под образы Docker.
  • В Caddyfile.prod число потоков FrankenPHP ограничено (num_threads 2), так как каждый поток держит собственный интерпретатор PHP.

Полный сброс кеша сгенерированных проектов: метаданные лежат в пуле cache.projects, а сами сборки и архивы — в var/share, поэтому чистить нужно и то, и другое.

php bin/console cache:pool:clear cache.projects
rm -rf var/share/projects/* var/share/zips/* var/generator/*

Освобождение диска (истёкшие сборки, архивы, остатки прерванных сборок):

php bin/console app:gc --dry-run
php bin/console app:gc

Тесты

php vendor/bin/phpunit --configuration phpunit.dist.xml

Покрыты юнит-тестами:

  • ProjectConfigFactory - бизнес-правила (ORM <-> БД, RabbitMQ -> Messenger, нормализация имени проекта)
  • ValidGeneratorOptionValidator - кастомный constraint для доменной валидации параметров запроса

Участие в разработке

Исправления, идеи и доработки приветствуются: Issues и Pull Request в репозитории проекта.


Web Service for Generating Symfony Projects with Docker

Pick project options and get a ZIP with a ready-to-run Symfony app for Docker. Run with docker compose up.

Interface screenshot

Symfony Initializr main page


Features

  • Parameters: project name, PHP version, server (PHP-FPM + Nginx or FrankenPHP), Symfony version (LTS and current, from symfony.com).
  • Database: none, PostgreSQL, MySQL, MariaDB, SQLite. UI syncs with Doctrine ORM: choosing a DB checks ORM; checking ORM selects PostgreSQL when DB is none. Docker uses Alpine-based images where available (postgres, redis, memcached, rabbitmq).
  • Cache: selector None / Redis / Memcached. Adds the container, PHP extension, and CACHE_DSN in .env.
  • Extensions: Doctrine ORM, Security, Mailer, Messenger, Validator, Serializer, API Platform, HTTP Client, Nelmio API Doc. Dependencies are auto-selected (API Platform -> ORM + Serializer + Nelmio; RabbitMQ -> Messenger).
  • Message broker: RabbitMQ option adds the RabbitMQ container with management UI and MESSENGER_TRANSPORT_DSN in .env.
  • Generation: skeleton via composer create-project, Dockerfile and docker-compose injection, web server config (Nginx / Caddyfile). Flex recipes do not duplicate our services (SYMFONY_SKIP_DOCKER=1, recipe blocks stripped from compose).
  • Download: button disabled until response; archive via fetch. Rate limit shows message and retry time.
  • Asynchronous builds: a cached configuration is served inline (200 with the archive). Otherwise /generate answers 202 with a job_id, a Messenger worker performs the build, and the frontend polls /generate/status/{jobId} before downloading /generate/download/{jobId}. No HTTP worker is held for the duration of composer.
  • Caching: by parameter set (PHP, server, Symfony, extensions, database, cache, RabbitMQ) plus the generator template revision. Build directories and ready-made ZIPs live in var/share/; the Composer download cache has its own volume.
  • Disk reclamation: app:gc removes builds and archives whose cache entries expired plus leftovers from interrupted builds, and evicts the least recently used entries once APP_CACHE_MAX_MB is exceeded. The compose maintenance service runs cleanup and warmup hourly.
  • One Composer at a time: a global lock in the shared volume prevents concurrent builds, which is what keeps a low-RAM VPS from being OOM-killed.
  • Version compatibility: Symfony 8 requires PHP 8.4+, Symfony 7 requires 8.2+, Symfony 6.4 requires 8.1+. Incompatible pairs are rejected with a 400, disabled in the form, and skipped by --all-base. The build result is verified explicitly, because Composer can exit with code 0 after printing resolution errors, so the presence of vendor/symfony/framework-bundle is checked.
  • Rate limit: 30 requests per hour per IP (real client IP is used once TRUSTED_PROXIES is configured).

Trust & transparency

The project is open source: you can inspect the generator source code and how the archive is built before using it. The generated ZIP contains only the standard Symfony skeleton, dependencies from Packagist, and the added Docker/config files - no hidden code. We recommend reviewing the archive contents before deploying.


Running

docker compose up -d --build

The service will be available at: http://localhost:8080

Enter the container:

docker compose exec frankenphp bash

Development

Code style is enforced with PHP CS Fixer using the @Symfony rule set. Config: app/.php-cs-fixer.dist.php. Run inside the container (from the app directory):

docker compose exec frankenphp bash
./vendor/bin/php-cs-fixer fix src

To warm the PHP/Symfony version cache and generated project cache (optional):

# popular configurations only (default)
php bin/console app:warm-cache
php bin/console app:warm-cache --popular-only

# all base PHP × Symfony × server combinations, no extensions/DB (slower)
php bin/console app:warm-cache --all-base

# keep refreshing the cache in cycles (this is what the maintenance service runs)
php bin/console app:warm-cache --loop --interval=900

Warming every possible variant is pointless: the extensions alone give 512 subsets, which combined with PHP × Symfony × server × database × cache × RabbitMQ is roughly 370,000 combinations and terabytes of disk. Warm the base matrix (24 combinations, ~600 MB) and the popular sets instead.

Deploying to production

The production configuration no longer mounts the source tree: dependencies and the warmed Symfony cache live in the image, so the image must be rebuilt after every git pull. Secrets are passed through a .env file next to the compose file (see .env.example), since .env.local never reaches the image.

cp .env.example .env   # once: APP_SECRET, TRUSTED_PROXIES, APP_CACHE_MAX_MB
git pull
docker compose -f docker-compose.prod.yml up -d --build --remove-orphans
docker compose -f docker-compose.prod.yml exec frankenphp php bin/console app:gc
docker compose -f docker-compose.prod.yml exec frankenphp php bin/console app:warm-cache

The worker and maintenance services are new and builds will not run without them, hence the full up with --remove-orphans rather than restarting only the web container.

Small VPS (512 MB RAM, 10 GB disk)

  • Peak build memory is around 210 MB for the heaviest configuration (API Platform), which is why only one build runs at a time.
  • Add 1-2 GB of swap: Composer's dependency resolution needs a short memory burst.
  • APP_CACHE_MAX_MB is set to 1024 in the prod compose file so the cache cannot crowd out Docker images.
  • Caddyfile.prod caps FrankenPHP at num_threads 2, since every thread holds its own PHP interpreter.

To fully clear the generated project cache: metadata lives in the cache.projects pool while the builds and archives live in var/share, so both have to go.

php bin/console cache:pool:clear cache.projects
rm -rf var/share/projects/* var/share/zips/* var/generator/*

To reclaim disk space (expired builds, archives, interrupted build leftovers):

php bin/console app:gc --dry-run
php bin/console app:gc

Tests

php vendor/bin/phpunit --configuration phpunit.dist.xml

Unit tests cover:

  • ProjectConfigFactory - business rules (ORM <-> DB, RabbitMQ -> Messenger, project name normalization)
  • ValidGeneratorOptionValidator - custom constraint for domain validation of request parameters

Contributing

Fixes, ideas and improvements are welcome via Issues and Pull Requests in the project repository.

About

Web Service for Generating Symfony Projects with Docker

Resources

Stars

8 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages