Caution: You are browsing the legacy symfony 1.x part of this website.

День 22: Развертывание приложения (deployment)

1.4 / Propel
Symfony version
1.2
Language ORM

После конфигурирования системы кэширования вчера, сайт Jobeet готов к тому, чтобы быть развернутым на промышленных серверах.

В течение 22 дней мы разрабатывали Jobeet на машине для разработки, что для большинства из вас, возможно, означает Ваш локальный компьютер; за исключением случая, когда Вы разрабатываете сразу на промышленном сервере, что, конечно, является очень плохой идеей. Теперь настало время перенести сайт на промышленный сервер.

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

Подготовка промышленного сервера

Прежде чем развертывать наше приложения на промышленном сервере, мы должны убедиться, что сервер настроен правильно. Можете перечитать урок 1, где объяснялось, как настраивать веб-сервер.

В этой главе мы предполагаем, что Вы уже установили веб-сервер, сервер базы данных и PHP 5.2.4 или более поздний.

note

Если Вы не имеете доступа к веб-серверу по SSH, пропустите ту часть, где Вам нужно иметь доступ к командной строке.

Конфигурация сервера

Сначала Вы должны убедиться, что PHP установлено со всеми необходимыми расширениями и правильно настроено. Так же, как в уроке 1, мы будем использовать скрипт check_configuration.php, предоставляемый Symfony. Так как мы не будем устанавливать Symfony на промышленном сервере, скачайте файл напрямую с сайта Symfony:

http://trac.symfony-project.org/browser/branches/1.4/data/bin/check_configuration.php?format=raw

Скопируйте файл в корневую директорию веб-сервера и запустите его и в браузере, и из командной строки:

$ php check_configuration.php

Исправьте все фатальные ошибки, которые обнаружил скрипт, и повторите процесс, пока все не будет работать хорошо в обеих средах.

PHP ускоритель (Accelerator)

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

note

Из Википедии: PHP ускоритель кэширует скомпилированный байт-код PHP скриптов, чтобы избежать интерпретации и компиляции исходного кода на каждый запрос.

APC - один из самых популярных ускорителей, который очень просто установить:

$ pecl install APC

В зависимости от Вашей операционной системы, Вам возможно также придется установить его при помощи ОС-зависимого менеджера пакетов.

note

Потратьте некоторое время, чтобы изучить, как настроить APC.

Библиотеки Symfony

Встраивание Symfony

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

Единственный абсолютный путь, который, возможно, существует, может быть найден в файле config/ProjectConfiguration.class.php; но мы избавились от него в течение урока 1. Проверьте, что файл действительно содержит относительный путь к загрузчику ядра Symfony:

// config/ProjectConfiguration.class.php
require_once dirname(__FILE__).'/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php';

Обновление Symfony

Даже если все сосредоточено в одной директории проекта, обновление Symfony на более новый релиз тем не менее очень просто.

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

Для обновления Symfony достаточно просто сменить содержимое директории lib/vendor/symfony/. Если Вы установили Symfony из архива, удалите старые файлы и замените их новыми.

Если Вы используете Subversion для своего проекта, Вы также можете использовать внешнюю ссылку на последний тэг Symfony 1.4:

$ svn propedit svn:externals lib/vendor/
  # symfony http://svn.symfony-project.com/tags/RELEASE_1_4_1/

Обновление Symfony заключается в простом обновлении ссылки на последнюю версию Symfony.

Вы также можете использовать ветку (branch) 1.4, чтобы получать все исправления быстрее:

$ svn propedit svn:externals lib/vendor/
  # symfony http://svn.symfony-project.com/branches/1.4/

Теперь, каждый раз, когда Вы будете использовать svn up, Вы будете получать последнюю версию symfony 1.4.

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

$ php symfony cc

tip

Если Вы имеете также и FTP доступ на промышленный сервер, Вы можете эмулировать результат задачи symfony cc, просто удалив все содержимое директории cache/.

Вы даже можете протестировать новую версию Symfony, не заменяя существующую. Если Вы просто хотите проверить новый релиз, не теряя возможности простого отката обратно, установите Symfony в другую директорию (например, lib/vendor/symfony_test), измените путь в классе ProjectConfiguration на новую директорию, очистите кэш, и все готово к тесту. Для отката на предыдущую версию просто удалите новую директорию и восстановите старый путь в классе ProjectConfiguration.

Тонкая настройка конфигурации

Конфигурация базы данных

В большинстве случаев промышленная база данных имеет другие параметры соединения, чем локальная. Благодаря окружениям Symfony, очень просто установить другие настройки для промышленной базы данных:

$ php symfony configure:database "mysql:host=localhost;dbname=prod_dbname" prod_user prod_pass

Вы также можете вручную отредактировать конфигурационный файл databases.yml.

Стили, Javascript-ы и прочие компоненты страниц (assets)

Поскольку Jobeet использует плагины, которые содержат собственные стили, Javascript-ы и т.д., Symfony создает символические ссылки в директории web/. Задача plugin:publish-assets перезаписывает или создает их, если Вы установили плагин без использования задачи plugin:install:

$ php symfony plugin:publish-assets

Настройка страниц ошибок

Прежде, чем переводить приложение на промышленный сервер, было бы неплохо переопределить страницы ошибок Symfony, используемые по умолчанию, такие как "Page Not Found (ошибка 404)" или страница показа информации об исключении.

Мы уже настроили страницу ошибок для YAML в течение дня 16, создав файлы error.yaml.php и exception.yaml.php в директории config/error/. Файл error.yaml.php используется Symfony в окружении prod, в то время как файл exception.yaml.php используется в окружении dev.

Чтобы создать собственные страницы отображения информации об исключении для HTML-формата, создайте два файла: config/error/error.html.php и config/error/exception.html.php.

Страница для ошибки 404 (страница не найдена) может быть настроена с использованием параметров error_404_module и error_404_action:

# apps/frontend/config/settings.yml
all:
  .actions:
    error_404_module: default
    error_404_action: error404

Настройка структуры директорий

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

Настройка имен директорий может быть сделана в классе config/ProjectConfiguration.class.php.

Корневая веб-директория

На некоторых веб-серверах Вы не можете менять имя корневой веб-директории. Скажем, пусть на Вашем сервере она называется public_html/ вместо web/:

// config/ProjectConfiguration.class.php
class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    $this->setWebDir($this->getRootDir().'/public_html');
  }
}

Метод setWebDir() принимает в качестве параметра абсолютный путь корневой веб-директории Вашего сервера. Если Вы к тому же переместили всю директорию проекта в другое место, не забудьте проверить контроллеры, чтобы убедиться, что путь к файлу config/ProjectConfiguration.class.php по-прежнему верен:

require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');

Директории для кэша и логов

Фреймворк Symfony осуществляет запись только в две директории: cache/ и log/. Из соображений безопасности, некоторые веб-сервера не дают прав записи в главную веб-директорию. Если это Ваш случай, Вы можете переместить директории для кэша и логов в любое место в файловой системе:

// config/ProjectConfiguration.class.php
class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    $this->setCacheDir('/tmp/symfony_cache');
    $this->setLogDir('/tmp/symfony_logs');
  }
}

Так же, как и метод setWebDir(), методы setCacheDir() и setLogDir() принимают абсолютные пути к cache/ и log/ директориям.

Настройка объектов ядра Symfony (фабрики)

В течение дня 16, мы немного говорили о фабриках в symfony. Возможность настройки фабрик означает, что Вы можете использовать собственные классы для объектов ядра Symfony вместо заданных по умолчанию. Вы также можете изменить стандартное поведение этих объектов, изменяя их параметры.

Давайте взглянем на несколько классических замен, которые Вы можете захотеть сделать.

Имена куки-объектов (cookies)

Для хранения информации о сессии пользователя, Symfony использует куки. Эти куки имеют имя по умолчанию symfony, которое может быть изменено в файле factories.yml. После ключа all добавьте следующую конфигурацию, чтобы сменить имя куки на jobeet:

# apps/frontend/config/factories.yml
storage:
  class: sfSessionStorage
  param:
    session_name: jobeet

Хранение сессии

По умолчанию для хранения сессий используется класс sfSessionStorage. Он использует файловую систему для хранения информации о сессиях. Если у Вас несколько веб-серверов, Вы можете захотеть хранить информацию о сессии в централизованном хранилище, таком, как таблица базы данных:

# apps/frontend/config/factories.yml
storage:
  class: sfPDOSessionStorage
  param:
    session_name: jobeet
    db_table:     session
    database:     propel
    db_id_col:    id
    db_data_col:  data
    db_time_col:  time

Таймаут сессии

По умолчанию время жизни пользовательской сессии 1800 секунд. Этот параметр может быть изменен в секции user:

# apps/frontend/config/factories.yml
user:
  class: myUser
  param:
    timeout: 1800

Логгирование

По умолчанию в окружении prod логгирование выключено, поскольку
имя класса логгера sfNoLogger:

# apps/frontend/config/factories.yml
prod:
  logger:
    class:   sfNoLogger
    param:
      level:   err
      loggers: ~

Вы можете, к примеру, разрешить логгирование в файловой системе, изменив имя класса логгера на sfFileLogger:

# apps/frontend/config/factories.yml
logger:
  class: sfFileLogger
  param:
    level: error
    file:  %SF_LOG_DIR%/%SF_APP%_%SF_ENVIRONMENT%.log

note

В конфигурационном файле factories.yml, строки вида %XXX% заменяются соответствующими значениями из объекта sfConfig. Так, %SF_APP% в файле конфигурации эквивалентно sfConfig::get('sf_app') в коде PHP. Эта нотация также может быть использована в файле app.yml. Это очень удобно, когда Вам нужно использовать путь в конфигурационном файле без жесткого кодирования пути (SF_ROOT_DIR, SF_WEB_DIR, ...).

Развертывание

Что надо развертывать?

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

В Symfony-проекте, три директории должны быть исключены из процесса переноса: cache/, log/, и web/uploads/. Все остальное должно быть скопировано, как есть.

По соображениям безопасности, Вы также не должны копировать "непромышленные" фронт-контроллеры, т.е. файлы frontend_dev.php, backend_dev.php и frontend_cache.php.

Стратегии развертывания

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

Простейший способ развернуть Ваш веб-сайт - это использование встроенной задачи project:deploy. Она использует SSH и rsync, чтобы установить соединение с сервером и передать все файлы с одного компьютера на другой.

Сервера для задачи project:deploy могут быть настроены в конфигурационном файле config/properties.ini:

# config/properties.ini
[production]
  host=www.jobeet.org
  port=22
  user=jobeet
  dir=/var/www/jobeet/

Чтобы развернуть приложение на вновь настроенном сервере production, используйте задачу project:deploy:

$ php symfony project:deploy production

note

Перед первым запуском задачи project:deploy, Вам нужно подсоединиться к серверу вручную, чтобы добавить ключ в файл с доверенными хостами.

tip

Если команда не работает так, как ожидалось, Вы можете использовать опцию -t, чтобы видеть вывод команды rsync в реальном времени.

Если Вы выполните эту команду, Symfony будет только симулировать передачу данных. Чтобы действительно развернуть веб-сайт, добавьте опцию --go:

$ php symfony project:deploy production --go

note

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

По умолчанию Symfony не будет передавать ни директории, о которых мы говорили в предыдущей секции, ни dev фронт-контроллер. Это происходит потому, что задача project:deploy игнорирует файлы и директории, которые перечислены в файле config/rsync_exclude.txt:

# config/rsync_exclude.txt
.svn
/web/uploads/*
/cache/*
/log/*
/web/*_dev.php

Для Jobeet нам нужно добавить еще файл frontend_cache.php:

# config/rsync_exclude.txt
.svn
/web/uploads/*
/cache/*
/log/*
/web/*_dev.php
/web/frontend_cache.php

tip

Вы можете также создать файл config/rsync_include.txt, чтобы принудительно отправить на сервер некоторые файлы и директории.

Даже насмотря на то, что задача project:deploy очень гибкая, Вы можете захотеть еще доработать ее. Поскольку развертывание может выполняться очень по-разному, в зависимости от конфигурации Вашего сервера и топологии, не стесняйтесь расширять исходную задачу.

Каждый раз, когда Вы разворачиваете сайт на промышленный сервер, не забудьте по крайней мере очистить конфигурационный кэш на сервере:

$ php symfony cc --type=config

Если Вы изменили несколько маршрутов, Вам также нужно очистить кэш маршрутизации:

$ php symfony cc --type=routing

note

Выборочная очистка кэша позволяет сохранить некоторые его части, такие как кэш шаблонов.

Увидимся завтра

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

Завтра - последний день учебника Jobeet. Это будет время для того, чтобы оглянуться назад и окинуть взглядом то, что мы уже изучили за 23 дня работы над Jobeet.