- PVSM.RU - https://www.pvsm.ru -
Всем привет!
Сайты Alawar — это сайты для русского [1], американского [2], европейских и других рынков, отдельные сайты для mobile-устройств, сайты партнерских программ и др. Все они развернуты на одном инстансе Yii, о чем мы уже писали в нашем блоге на хабре [3].
Сегодня я расскажу, как мы организовали хранение, структуру и управление конфигами наших сайтов, какие при этом получили преимущества. А также поведаю, как осуществляется деплой нашего проекта в различных окружениях.
Для осуществления настройки сайтов мы применили следующую структуру конфигов в Yii:
protected/config
/console
/config.php
/import.php
/cache.php
/log.php
…
/mobile
/config.php
/import.php
/cache.php
/log.php
…
/sites
/alawar.ru.php
/iphone.alawar.ru.php
/ipad.alawar.ru.php
/site.php
…
/test
/config.php
/import.php
…
/web
/config.php
/import.php
/log.php
…
/~server
/amqp.php
/crontab.txt
/db.php
/eauth.php
/mongo.php
/redis.php
/smsgate.php
/services.php
/comment.php
…
Все конфигурационные файлы были разбиты на категории согласно их назначению:
<?php
return array(
'preload' => array( 'log' ),
//список подключаемых файлов
'import' => require(dirname(__FILE__) . '/import.php'),
'components' => array(
…
//параметры подключения к MySql
'db' => require(dirname(dirname(__FILE__)) . '/server/mysql.php'),
//параметры подключения к Redis
'redis' => require(dirname(dirname(__FILE__)) . '/server/redis.php'),
//параметры подключения к Mongo
'mongo' => require(dirname(dirname(__FILE__)) . '/server/mongo.php'),
//настройки логгирования
'log' => require(dirname(dirname(__FILE__)) . '/web/log.php'),
//настройки компонента комментариев
'comment' => require(dirname(dirname(__FILE__)) . '/server/comment.php'),
//настройки RabbitMQ
'amqp' => require(dirname(dirname(__FILE__)) . '/server/amqp.php'),
//настройки авторизации через соц. сети
'eauth' => require(dirname(dirname(__FILE__)) . '/server/eauth.php'),
…
),
'params' => array(
//параметры доступа к различным сторонним сервисам
'services' => require(dirname(dirname(__FILE__)) . '/server/services.php'),
//параметры доступа к смс-шлюзу
'smsgate' => require(dirname(dirname(__FILE__)) . '/server/smsgate.php'),
…
)
);
return CMap::mergeArray(
array(
'basePath' => dirname(__FILE__) . DIRECTORY_SEPARATOR . '..'. DIRECTORY_SEPARATOR . '..',
'name' => 'Site',
'theme' => 'site',
'host' => 'site.ru',
'language' => 'ru',
//модули site.ru
'modules' => array(
…
),
//модули site.ru
'controllerMap' => array(
…
),
//спецефичные компоненты для site.ru
'components' => array(
…
),
// application-level parameters that can be accessed
// using Yii::app()->params['paramName']
'params' => array(
//runtime параметры
//например:
//Yii::app()->params['runtimeData']['css'] - путь к минифицированному css сайта
//Yii::app()->params['runtimeData']['js'] - путь к минифицированному js сайта
'runtimeData' => @include(dirname(__FILE__).'/runtime/sites/site.ru.php'),
'adminEmail' => 'admin@site.ru',
),
), require(dirname(dirname(__FILE__)).'/web/config.php')
);
Такой подход к формированию итогового конфига сайта позволяет легко подключать новые сайты и достаточно гибко их настраивать.
Особенностью структуры конфигов является то, что в protected/~server сосредоточены «сереверозависимые» параметры и настройки, которые хранятся в отдельных репозиториях под каждый сервер(~server — это всего лишь симлинка на чекаут одного из репозиториев). Такая структура позволяет легко, быстро и без костылей разворачивать проект в различном окружении.
В данный момент у нас проект может быть развернут на 3-х серверах:
Соответственно, под каждый сервер заведен свой репозиторий с конфигами:
При развертывании проекта (мы это делаем средсвами jenkins [4] и phing [5]) мы просто указываем, какую ветку и какой репозиторий с конфигами поднять:
#развертывание ветки task-xx в dev-окружении
phing -Dbranch=task-xx -Dconfig=dev-config deploy
#развертывание проекта на продакшн сервере
phing -Dbranch=prod -Dconfig=prod-config deploy
Вот, что делает при этом phing:
<!-- Таск по развертыванию проекта -->
<target name="deploy" depends="-get-properties">
<!-- Путь к директроии, в которой развертывается проект -->
<mkdir dir="${deploy.path}" />
<!-- Путь к директроии, в которой будет расчекаучена ветка репозитория с кодом проекта -->
<mkdir dir="${deploy.path}/application" />
<!-- Путь к директроии, в которой будет расчекаучена репозиторий с конфигами -->
<mkdir dir="${deploy.path}/config" />
<echo msg="checkout application and config..." />
<!-- Чекаут ветки -->
<exec
command="bzr co ${bzr.branch.path} ./"
dir="${deploy.path}"
checkreturn="FALSE"
returnProperty="bzr.co.return"
outputProperty="bzr.co.out"
/>
<if>
<!-- Если ветки не существует, создаем её, пачкую от ветки транк -->
<equals arg1="${bzr.co.return}" arg2="3" />
<then>
<exec command="bzr co ${bzr.trunk.path} ./" dir="${deploy.path}/application" />
<exec command="bzr switch -b ${bzr.branch.path}" dir="${deploy.path}/application" />
</then>
</if>
<!-- Чекаут репозитория с конфигами -->
<exec command="bzr co ${bzr.config.path} ./" dir="${deploy.path}/config" />
<!-- Настройка прав доступа к папке runtime -->
<chmod file="${deploy.path}/application/protected/runtime" mode="0777" />
<!-- Создание симлинки на конфиги -->
<exec command="ln -s ${deploy.path}/config/server server" dir="${deploy.path}/application/protected/config/" level="info"/>
<!-- Создание симлинки на php error log -->
<exec command="ln -s ${php.error.log.path} phplog" dir="${deploy.path}/application/protected/runtime/" level="info"/>
<!-- Для каждого сайта генерация минифицированного css и js и прописывание путей к ним в protected/runtime/sites/{site.ru.php} -->
<exec command="php ${deploy.path}/application/protected/yiic deploy data=css" />
<exec command="php ${deploy.path}/application/protected/yiic deploy data=js" />
<!-- Генерация карты шардов redis и mysql -->
<exec command="php ${deploy.path}/application/protected/yiic deploy data=shardmap" />
</target>
Таким образом, после развертывания структура всего проекта становится следующей:
application/ #чекаут репозитория с кодом проекта
protected/
…
config/
…
~server/ #симлинка на config/server
…
…
public/
…
config/ #чекаут репозитория с конфигами
…
server/
…
Используемая нами структура конфигов позволила:
Однако, конечно у подхода с различными репозиториями под конфиги есть свои минусы, основной из них — это синхронизация изменений. Приходится руками переносить изменения в одном репозитории во все другие с учетом настроек окружения.
Автор: nasedkin
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/php-2/38586
Ссылки в тексте:
[1] русского: http://www.alawar.ru
[2] американского: http://www.alawar.com
[3] о чем мы уже писали в нашем блоге на хабре: http://habrahabr.ru/company/alawar/blog/157877/
[4] jenkins: http://jenkins-ci.org/
[5] phing: http://www.phing.info/
[6] Источник: http://habrahabr.ru/post/186458/
Нажмите здесь для печати.