Pull to refresh

Comments 62

Я бы не сказал что это перевод. Я прочитал данный пост Фабьена, и на его основе написал этот материал.

И, если бы вы поставили в статье ссылку на пост — вас не в чем было бы упрекнуть :)

Да, конечно. Я описал инструменты которые мне использовать удобнее. Дело вкуса.
Уже перевёл основные проекты на Symfony 4 like index.php и %env()%. Заметил, что чистый index.php плохо работает с APP_ENV=prod и, главное, с env параметрами в route — они разрешаются в compile-time (прогрева кеша), а не в рантайме. Пришлось переносить прогрев кэша в рантайм докер-контейнера из билд. Хотелось бы пофиксить, может есть идеи?
Мне кажется, что рановато вы решили переводить проекты под Symfony 4 style. С APP_ENV=prod на скелетном Hello world с включенными аннотациями для роутинга проблем не было. Можно по подробнее что означает index.php плохо работает с APP_ENV=prod?
рановато вы решили

symfony 3.3 вышел, а значит не рано. У меня схожие подходы уже больше года используются на проектах и я доволен.

Да по сути перевод давно начался, с релизом 3.2 примерно, если не раньше. parameters.yml очень неудобен для автоматического развертывания, а разные точки входа для прод и дев окружения очень неудобны при тестировании клиентов сервиса с симфони слабо связанными: задать через переменные окружения всё — идея, лежащая на поверхности.


У меня для для конструкций типа Route ("host": "sub.{domain}", "defaults": {"domain": "%env(DOMAIN)%"}, "requirements": {"domain": "%env(DOMAIN)%"}}) всё разрешалось в момент прогрева кэша, а не в рантайме.


Не эквивалентны по поведению неуказанная среда и APP_ENV=prod.

они разрешаются в compile-time (прогрева кеша), а не в рантайме.

как раз таки Cache Warmup это не совсем compile time, а скорее рантайм. То есть на момент компиляции роутов контейнер зависимостей уже скомпилен.


Хотелось бы пофиксить, может есть идеи?

У меня не вышло. Как минимум потому что часть того что прогревается все же требует рантайма. Есть как бы варианты… Например — отказаться от Dockerfile, то есть собрать контейнер, прогреть кэши и уже потом сделать docker commit и уже этот образ дистрибьютить. Но хз.

С Докером есть некоторые не решенные моменты. Можно почитать дискуссию на эту тему тут.

Если под нерешенными моментами имеется ввиду желание "а давайте flex будет патчить мои compose файлики" — то нет, это мне не нужно. Да и выглядит это странно, или flex будет pecl пакеты сам ставить тоже?


Других моментов с docker нет.

как раз таки Cache Warmup это не совсем compile time, а скорее рантайм. То есть на момент компиляции роутов контейнер зависимостей уже скомпилен.

Всё равно это компиляция, а не обработка запроса. Ну, если кэш в проде прогревать до начала поступления запросов.


Например — отказаться от Dockerfile, то есть собрать контейнер, прогреть кэши и уже потом сделать docker commit и уже этот образ дистрибьютить. Но хз.

Не имеет значения. Зафиксируются значения на момент прогрева, что нарушит концепцию "строим образ и деплоим в разных окружениях". Работает только прогрев кеша на момент запуска контейнера из образа в ENTRYPOINT и(или) CMD.

Как в том же fos user bundle я переопределю шаблоны, если мой бандл унаследован, а папка для всех общая. Только переписыванием контроллеров?
Если вы наследуетесь от бандла, то ничего переписывать не нужно. Вы по прежнему можете иметь бандлы в src/, просто теперь это не обязательно. Не забудьте прописать свой бандл в etc/bundles.php. Если же вы определяете только шаблоны в app/resources, то возможно стоит подумать о переносе в src/.
С .env файлами не все так просто ввиду того, что ENV переменные это всегда строки. Часто параметры должны быть четко типизированы, например, тот же параметр disable_delivery (swift mailer) ожидает строго тип bool, и передать в него ENV переменную напрямую не удается. Поэтому полный переход на .env файлы весьма затруднителен.
Согласен. Но на то оно и альфа, чтобы получить фидбэк. Дискуссии по этому вопросу еще ведутся. Вполне возможно, что мы увидим какой-то гибридный механизм или останемся в файлах в плане настроек окружения.
Поэтому полный переход на .env файлы весьма затруднителен.

посмотрите на это с другой стороны — как насчет минимизировать различия между окружением? Что бы у вас параметры вроде disable_delivery просто лежали себе в yaml файлике для определенного окружения и все, а подменялось только то что реально должно подменяться. Какой энвайрмент. креденшелы, токены и т.д.

На эту тему есть дискуссия. Кстати никто не запрещает вам как и ранее использовать некоторые специфичные параметры в parameters.yaml. Если ваш проект не может обслуживаться исключительно переменными окружения, пожалуйста, используйте конфигурационные файлы. Я думаю будет еще много разговоров на эту тему. Меня тоже в некоторых моментах смущает использование переменных окружения.
Да, тоже находил подобную дискуссию, где Фабьен сказал, что .env файл полностью не заменяют параметры.
А я всего лишь хотел уйти от поддержки parameters.yml.dist -> parameters.yml и остаться только на .env.dist -> .env файле. Но пока приходится поддерживать оба механизма конфигурации.
некоторые специфичные параметры в parameters.yam

он не нужен. Я предлагаю все различия окружения выносить в конфигурацию именно окружения (config_prod.yml к примеру). А parameters.yml — он не нужен.


К этому приходят почти все кто держит свое приложение в каком-либо контейнере.

Согласен. Переменные окружения по сути будут задавать только два параметра APP_ENV и APP_DEBUG,
все остальное можно разнести.
только два параметра

ну у меня еще есть всякие DB_HOST, DB_PASS, REDIS_HOST, ELASTICSEARCH_URL` и прочие штуки.

Вот по поводу DB_PASS у меня почему-то легкий холодок пробегает по спине когда я думаю о том чтобы такие данные прописывать в окружении. Пока не могу определить для себя позицию по этому вопросу.

если это докеры и иже с ним, то это ок, т.к приложение одно и оно и так имеет доступ к этим параметрам. если на площадке несколько сервисов, тогда боязно, да

но эти несколько сервисов могут быть в своих окружениях и не иметь к параметрам друг друга доступа.

А могут и иметь, мы же рассмативаем не идеальный сферический мир, не так ли? Конечно можно распихать все приложения в индивидуальные контейнеры, я с этого и начал свой тезис.

А что делать, если у нас три десятка разработчиков с разными параметрами (персональные окружения)?

У каждого разработчика свое окружение и настройки. При разработке используется компонент symfony/dotenv для эмуляции переменных окружения из файла .env.
Реальные переменные окружения предполагается использовать на stage, prod и т.п. серверах.

выше уже написали, что дотенв — не панацея

три десятка разработчиков с разными параметрами

Избавиться от "персонального окружения"? Если у вас 30 человек и у каждого свое окружение, которое отличается от продакшена — у меня возникают большие вопросы.

Вы меня опередили. Как раз хотел тоже самое сказать. На самом деле нет ничего плохого если у каждого разработчика значения параметров окружения отличаются, для того оно собственно и предназначено. Но если у разработчиков одного проекта разные параметры окружения, то вам не помогут и любые другие решения. В переменных окружения нормально задать порт мемкеша, если у кого-то он отличается от стандартного, но совсем не правильно задавать параметры от которых зависит приложение и которых нет в продакшене или у других разработчиков. По-моему это более чем очевидно.

у нас есть, например, дебаг тулбар, который управляется через параметры, т.к не всем разработчикам (фронтам, например) он нужен. да и вообще окружение по умолчанию отличается тем, что в разработке используется dev режим по умолчанию, на контурах дальше — прод. но мне казалось, что это логичная разница с продом, иначе зачем вообще тогда dev режим

т.к не всем разработчикам (фронтам, например) он нужен.

export SYMFONY_ENV=stage


например. У меня к примеру фронтэндеры работают на своих стэйджинг серверах (не хотят они себе докер). Деплоят туда что им нам надо, и норм. Я там отключенным держу дебаг панель, но профайлер доступен на всякий случай.

Я правильно понимаю, что на каждую группу разработки (бэки, фронты, итд) у вас есть отдельный env в symfony? Сколько у вас их всего, если не секрет? Мы просто используем классический dev,test,prod набор, а кастомизируем именно параметрами.
у вас есть отдельный env в symfony?

Ну давайте думать какие окружения нам нужны:


  • prod — продакшен.
  • stage — сервера которые используют QA, фронтэнды, мобильщики, в том числе для e2e тестов. Они же используются для demo внутренних к примеру (а тут уже дизайнеры, аналитики и все желающие). Тут отличие от продакшена только в том что мы врубаем профайлер и частенько используем всякие мэйлкэтчеры. Но это как раз таки через env разруливается на уровне настроек SMTP сервера. А так различия с продакшеном минимальны.
  • dev — локальная разработка, много всего накручено поверх stage. И для более удобной отладки, и в целом в силу ограничений инфраструктуры и работы с third-party сервисами.
  • test — очень похоже на dev но ориентируется на приемочные тесты.

Как-то так. По итогу с таким подходом можно намного более уверенно говорить фразы вроде "локально работает".


На парочке проектов есть ситуации когда в конфиг заносятся например фича тоглы, которые не привязаны к окружению, это скорее просто часть конфигурации.

test — очень похоже на dev но ориентируется на приемочные тесты.


А отдельного env для юнитов нет? С моками и пр.

stage — сервера которые используют QA, фронтэнды, мобильщики, в том числе для e2e тестов.


Про фронтов — я правильно понял, что у вас бэк — это чистое API и фронты пишут отдельное приложение, поэтому им не нужны всякие тормозящие фичи типа автоматических перегенераций кэша, статики приложения и пр? Если так, то ваша позиция понятна, у вас немного другой кейс.

У нас более «классическое» приложение с рендером на стороне твига, и фронты технически пишут то же самое приложение что и бэки, поэтому в нашем случае вот такой выделенный stage env не нужен (точней может и нужен, но не в таком варианте). QA, мобильщики и пр. используют просто prod вариант развернутый на внутренних контурах
А отдельного env для юнитов нет? С моками и пр.

А с каких пор юнит тесты хоть как-то привязаны к окружению? Они на то и юнит что тестируют юниты изолировано от любой инфраструктуры. И как раз таки то что проходит границу модуля и предоставляет доступ к инфраструктуре мы и мокаем.


То есть нам не нужен ни контейнер, ни кернел. А вот интеграционные/приемочные тесты — тут уже нужно.


у вас бэк — это чистое API

именно так.

На одном проекте мы юнит тесты в продакшене пускаем после деплоя. Никаких проблем с окружением не испытываем.

было бы еще неплохо если бы юнит тесты запускались ДО деплоя.

Ну конечно :) Было бы глупо пускать тесты только на проде при развороте. Я имел ввиду что на проде тоже пускаются после деплоя.

вот в этом месте я для себя пока не решил для себя. после того, как вы замокали инфраструктуру — ваши тесты не стали изолированными?


я пишу тесты так, чтобы мокать, но именно эти моки и определены в тестовом енве. эти же тесты без проблем запускаются и в dev, но они попытаются сходить в реальные сервисы, а не в замоканные

после того, как вы замокали инфраструктуру — ваши тесты не стали изолированными?

ну типа да. Вы как бы тестировать юнит тестами должны контракты объектов, а контракты зависимостей вы подменяете на требуемое от них поведение. Соответственно если ваши зависимости стабильнее тестируемого кода, и контракты хорошо протещены, то все хорошо.


и определены в тестовом енве.

если вы контейнер зависимостей юзаете — то это не юнит тесты. Это интеграционные тесты. А интеграционные тесты — это обман (то это не значит что они не нужны).

А на каком из ваших env вы производите интеграционное тестирование?
В списке вы упомянули только приемочные, но при этом делите эти тесты, так что я решил уточнить на всякий случай. Спасибо за объяснение.

test — очень похоже на dev но ориентируется на приемочные тесты.

А вот интеграционные/приемочные тесты — ...

любое окружение, которое не продакшен отличается от него по определению. не все параметры, как уже сказано выше, можно переопределить через dotenv, так что parameters.yml остается необходимым инструментом в конфигурировании площадки.


понятно что структура самих конфигов совпадает, вопрос именно в безаппеляционом тезисе "parameters.yml — он не нужен"

остается необходимым инструментом

я бы сказал не "необходимым" а опциональным. Сам по себе parameters.yml это не отдельный механизм, это часть механизма импортов конфигов который никто не собирается выпиливать.


он не нужен

по умолчанию — не нужен. Но абсолютных правил нет и есть исключения.

«необходимым» в некоторых кейсах, давайте так. Т.е. есть такие случаи, когда без него не обойтись, в таких случаях его сложно назвать «опциональным»

по умолчанию — не нужен.


Вот с такой формулировкой я соглашусь, можно без него.
Есть и критика новой структуры директорий в Symfony 4: http://paul-m-jones.com/archives/6564
Инициатива по стандартизации структуры PHP пакетов: https://github.com/php-pds/skeleton
Да, критика вполне справедлива я считаю. По поводу конфига в /config, очень поддерживаю как в прочем и другие доводы.

навязывать папку src — это имхо что выкидывать psr-4. плохо ложится на концепцию монорепозиториев, которые потом делят на пакеты через subtree. при том, что у нас есть такая крутая вещь, как композер — описывать структуры файлов можно и в нем (где конфиги лежат, где сурсы итд)

Тут получается неоднозначность. С одной стороны мы можем изменить в composer.json каталог с сорцами на любой, который нам нужен. С другой, все рецепты основываются на предложенной структуре и будут копировать необходимые файлы в строго заданные места. Таким образом при установке каких-то бандлов мы все равно получим что-то в /src
Стоп, стоп. Фиксированная (каноничная, если угодно) структура приложения — это нормально, приложение не подразумевает быть встроенным в другие пакеты. Предложенный же скелетон хочет, чтобы данная структура была у любых пакетов, что на мой взгляд, весьма неудобно.

Я согласен, что предложенная флексом структура весьма нелогичная, но она навязана рецепту, который будет встраиваться в ваше прилложение, но структура вашего пакета остается полностью произвольной. Т.е. рецепт — это в некотором смысле адаптер между пакетом и флексом
Как раз таки рецепт — это адаптер между пакетом и вашим приложением, а не флексом. Флекс лишь инструмент который выполняет рецепты. Если вы пишете рецепт сами, то можете написать его конкретно под вашу структуру. Большинство же рецептов написанные core-team Symfony будут следовать структуре о которой написано в статье. Поэтому либо выбирать предложенную структуру, либо писать рецепты под все пакеты, которые собираетесь использовать и отказываться от официального репозитория рецептов.

P.S. Тема очень глубокая с множеством точек зрения. Я согласен с вашими мыслями и сам пока еще не определился с какой я стороны.
ну да, под флексом я именно понимал приложение, использующее флекс в качестве инструмента конфигурации.

я лично буду просто ждать релиза, т.к. не имею пока проблем с конфигурацией зависимостей в приложении, мы все таки не веб студия, штампующая проекты десятками

Как вариант, в composer.json можно указывать переменные, переопределяющие стандартные пути, а в рецептах использовать плэйсхолдеры в путях "%app_src% и т. п.

Как я понимаю, основная проблема в web и etc вместо public и config? Вообще, посмотрев на начальные данные, сложилось впечатление, что Symfony очень сильно влияет на тренды именования и потому посое релиза в текущем виде тренды могут измениться.
А я бы вообще выбрал etc и www

Sign up to leave a comment.

Articles