Continuous delivery на примере bitbucket pipeline в PHP проекте на базе Yii2

Continuous delivery (непрерывная поставка) - это подход к разработки программного обеспечения при котором гарантируется быстрое и безопасное равзертывание системы на продакшен сервер поставляя тем самым каждое изменение в окружение подобное продакшену. Зачастую путают 2 подхода "Continuous delivery" и "Continuous Deployment", но на самом деле это 2 разные вещи.
  • Continuous delivery лишь позволяет убедиться в том, что система исправна и готова к развертыванию на боевом сервере
  • Continuous Deployment - это следующий шаг после Continuous delivery
Как только система была протестирована в окружении идентичному продакшену (Continuous delivery), код автоматически развертывается на боевом сервере (Continuous Deployment)

Далее будет реализована модель Continuous delivery на примере PHP проекта в Bitbucket при помощи инструмента Bitbucket Pipeline
Bitbucket Pipeline - инструмент для быстрой и безопасной поставки вашего ПО в окружение подобное продакшен серверу. Pipeline - это облачный инструмент, интегрированный в Bitbucket

Задача

  1. PHP проект на базе Yii2 фреймоврка будет лежать в репозитории Bitbucket
  2. При любом изменении в репозитории или при пулреквесте, автоматически будет развернуто окружение, установленны все необходимые для работы системы зависимости через менеджер пакетов, запустятся миграции и произведется модульное, функциональное и приемочное тестирование
Инструменты которые понадобятся для реализации задуманного
  1. Bitbucket репозиторий
  2. Встроенный в Bitbucket интсрумент для реализации Continuous delivery - Pipeline
  3. Проект на Yii2 фреймворке
  4. Фреймворк для тестирования Codeception
  5. Docker для создания образа с нужным окружением
  6. Система контроля версий Git
Поскольку в задачу также входит прогон приемочных тестов, нам необходим довольно объемный инструментарий в окружении. Минимальный набор для работы:
  1. Ubuntu - образ будет строится на базе ОС Linux
  2. curl - требуется фреймворком для тестирования
  3. php7.0 php7.0-zip php7.0-mbstring php7.0-gd php7.0-curl php7.0-pgsql php7.0-mysql php7.0-pdo - PHP и ряд расширений
  4. default-jdk - Java для selenium server
  5. phpunit - фреймворк для тестирования
  6. nginx - веб сервер
  7. xvfb - сервер виртуального экрана для прогона приемочных тестов
  8. firefox - веб браузер
  9. postgresql - СУБД
  10. selenium server - сервер для тестирования веб приложений
  11. geckodriver - драйвер для firefox
  12. codeception - фреймворк для тестирования поверх phpunit
  13. composer - менеджер пакетов
Этот минимальный набор инструментов позволит запустить стандартный набор тестов, предоставляемых Yii2 фреймворком в нашем будущем окружении. При необходимости вы можете дополнить набор инструментов нужными программами и утилитами. Первое, что нужно сделать, это создать образ с будущим окружением при помощи Docker. Создадим директорию, которая будет содержать исходники образа:
  1. codecept.phar - http://codeception.com/quickstart
  2. composer.phar - https://getcomposer.org/download/
  3. geckodriver - https://github.com/mozilla/geckodriver/releases
  4. selenium-server-standalone.jar - http://www.seleniumhq.org/download/
  5. pg_hba.conf - конфигурационный файл postgresql для проброса в образ, настроенный так, чтобы не требовалось вводить пароль при соединении с сервером СУБД
  6. test - виртуальный хост для nginx, настроенный под yii2 приложение - https://github.com/yiisoft/yii2/blob/master/docs/guide/start-installation.md#recommended-nginx-configuration-
  7. Dockerfile - файл с перечнем инструкций для сборки образа docker демоном - https://docs.docker.com/engine/reference/builder/
Исходники проекта можно найти в моем репозитории на github: https://github.com/spider4216/docker-ts-pipeline/tree/master/bitbucket_pipeline

DockerFile

FROM ubuntu
LABEL Description="This image is used to run unit, acceptance and functional tests under codeception framework" Version="1.0"
RUN apt-get update
RUN apt-get install curl -y
RUN apt-get install php7.0 php7.0-zip php7.0-mbstring php7.0-gd php7.0-curl php7.0-pgsql php7.0-mysql php7.0-pdo -y
RUN apt-get install default-jdk -y
RUN apt-get install phpunit -y
RUN apt-get install nginx -y
RUN apt-get install xvfb -y
RUN apt-get install firefox -y
COPY test /etc/nginx/sites-available/
RUN ln -s /etc/nginx/sites-available/test /etc/nginx/sites-enabled/
RUN apt-get install postgresql -y
COPY selenium-server-standalone-3.3.0.jar /usr/local/src
COPY geckodriver /usr/local/src
COPY codecept.phar /usr/local/bin/codecept
COPY pg_hba.conf /etc/postgresql/9.5/main/
COPY composer.phar /usr/local/bin/composer
RUN chmod a+x /usr/local/bin/codecept
RUN chmod a+x /usr/local/bin/composer
RUN mkdir project
WORKDIR /project
RUN service postgresql start && su postgres --command 'createuser -w -d -r -s docker' && su postgres --command 'createdb -O docker docker' && service postgresql stop
Последней командой создается база данных docker с полными правами для созданного пользователя docker Совет: После старта postgresql и создания пользователя и базы данных, незабудьте остановить сервис во избежании проблем в перспективе. Проблема заключалась в довольно продолжительном старте сервиса в контейнере, после сборке образа при его использовании: "the database system is starting up", технические детали истинной причины такого явления к сожалению не были выяснены

Сборка образа и Push в DockerHub

Написав инструкции по инсталяции необходимых инструментов и на проброс нужных файлы из директории с исходниками в будущий контейнер, необходимо собрать образ и загрузить его в репозиторий на Docker Hub
docker build -t codecept-app .
docker login
docker push <username>/<rep_name>

Bitbucket Pipeline

Когда образ будет загружен на Docker Hub, можно пойти в bitbucket и создать репозиторий для PHP проекта. Протолкните ваш yii2 проект в репозиторий. Следующим этапом является создание конфигурационного файла для инструмента bitbucket pipeline. Можно воспользоваться предложенным генератором, перейдя в раздел меню "pipeline" в bitbucket

Или просто создать в корне проекта файл "bitbucket-pipelines.yml"
image: YOUR_IMAGE_IN_DOCKERHUB

pipelines:
  default:
    - step:
        script: # Modify the commands below to build your repository.
          - echo '127.0.0.1      test.loc' >> /etc/hosts
          - service nginx start
          - service postgresql start
          - service php7.0-fpm start
          - DISPLAY=:99 xvfb-run -a -n 1 -l -s "-screen 0, 1024x768x8" java -Dwebdriver.gecko.driver="/usr/local/src/geckodriver" -jar /usr/local/src/selenium-server-standalone-3.3.0.jar &
          - composer global require "fxp/composer-asset-plugin:^1.2.0"
          - composer config -g github-oauth.github.com <YOUR_TOKEN>
          - composer update
          - ./yii migrate --interactive=0
          - codecept run
В yml конфигурации мы проделываем некоторые действия перед тем, как запустить тесты
  1. Указываем собранный и загруженный Docker образ из репозитория Docker Hub
  2. Добавляем хост для домена test.loc в hosts (Этот этап необходимо проделать в самом docker образе, описав инструкцию в Dockerfile)
  3. Запускаем nginx
  4. Запускаем postgresql
  5. Запускаем PHP-FPM
  6. Запусускаем сервер виртуального экрана и поднимаем в нем Selenium сервер
  7. Устанавливаем необходимый плагин для композера (Это этап лучше проделать в самом docker образе, описав инструкцию в Dockerfile)
  8. Добавляем в глобальный конфиг менеджера пакетов информацию о токене на случай того, если gitgub его потребует в связи с частыми запросами на веб сервис (Если docker образ является приватным, то лучше этот этап проделать непосредственно в docker контейне, описав инструкцию в Dockerfile)
  9. Устанавливаем необходимые для работы проекта зависимости из менеджера пакетов
  10. Запускаем миграции в интерактивном режиме
  11. Запускаем полный набор тестов
Все эти действия можно описать в shell скрипте и пробросить в образ, а затем описать запуск скрипта в bitbucket-pipelines.yml

Советы для Yii2 проекта

Миграции

Хорошей практикой является использование выделенного конфигурационного файла для миграции на этапе непрерывной поставки, чтобы можно было указать специальную базу и, возможно, другие настройки:
./yii migrate --appconfig=config/сontinuous_delivery_console.php --interactive=0

Тестирование

Для тестов использовать свой конфигурационный файл

RBAC

Если в проекте используется RBAC модель через DbManager, помните, что компонент DbManager в Yii 2.0.11.2, использует стандартное соединение "db". Если вы запускаете миграцию, указав "--db" соединение в команде, DbManager ее проигнорирует и будет использовать соединение по умолчанию. Чтобы использовать другое соединение в DbManager, необходимо либо переопределить свойство "db" компонента DbManager в самой миграции либо, как было описано ранее, использовать специальный конфигурационный файл, где будет настроен данный компонент на соединение, которое вам необходимо
return \yii\helpers\ArrayHelper::merge($consoleConfig, [
    'id' => 'basic-tests',
    'components' => [
        'db' => $dbParams,
        'authManager' => [
            'class' => 'yii\rbac\DbManager',
            'db' => $dbParams,
        ],
    ],
]);

Итоги

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

Дополнительные материалы

Информация

Автор конспекта


Дата создания: 01.01.2019
Категория: Веб-разработка