У нас есть сервер, на котором лежит множество проектов на WordPress и Magento CMS. Мне как PHP-разработчику была поставлена задача внедрить Jenkins для этих проектов, чтобы публикация изменений исходного кода на сервер происходила быстрее.
К чему нам Continuous Integration?
Вопрос повышения эффективности разработки и сопровождения программных продуктов для меня, как для веб-разработчика, всегда был и остается актуальным и интересным. Процессы сборки проекта и публикации его на сервер являются тем звеном, которое может быть легко автоматизированно при помощи средств Continuous Integration (CI).
CI многими уже давно и успешно применяется. Использование этого метода разработки позволяет существенно сократить время на публикацию проекта на сервер, сводя эту работу к исполнению нескольких консольных команд. Кроме того, при применении CI имеется возможность в любое время оперативно вернуться к предыдущей версии проекта, благодаря тому, что Continuous Integration неразрывно связана с репозиторием системы контроля версий.
Принцип работы CI довольно прост. В моем случае участвовало 3 сервера:
- Сервер системы контроля версий (СКВ), где хранится репозиторий с рабочей версией проекта, в который разработчик сохраняет свои изменения.
- Сервер Continuous Integration, на котором установлена одна из систем управления CI.
- Сервер, где развернута рабочая версия проекта.
Сразу после изменения репозитория в системе контроля версий, сервер СКВ инициирует выполнение задачи на сервере CI (как правило, с помощью веб-хука). Эта задача выполняет сборку и развертывание исходного кода из репозитория СКВ на сервер рабочей версии проекта.
Более подробно о преимуществах, которые предоставляет использование Continuous Integration, можно почитать в этой статье.
Данное руководство собирает в себе информацию, достаточную для того, чтобы быстро сконфигурировать систему CI Jenkins и начать работу с ней. Также здесь представлена информация по настройке и организации взаимодействия такой популярной системы CI, как Jenkins и не менее известной системы контроля версий Git. В качестве веб-сервиса для git будем использовать GitHub.
Внимание, задача
Необходимо установить и настроить Jenkins таким образом, чтобы при push-е в репозиторий GitHub происходило обновление измененных файлов на сервере рабочей версии проекта. В наличии:
- Сервер Debian 8.2 x64.
- Система на локальной машине: Linux Mint 17.2.
Предварительным требованием является установленный git на обеих машинах. Про то, как его установить, можно прочитать здесь.
Решение
1. Установка Jenkins
Установку выполним на выделенном для CI сервере. Вводим следующие команды для добавления репозитория Jenkins в список репозиториев системы:
sudo wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | apt-key
add -
sudo echo deb http://pkg.jenkins-ci.org/debian binary/ >
/etc/apt/sources.list.d/jenkins.list
Обновим apt и установим Jenkins:
sudo apt-get update
sudo apt-get install jenkins
Перезапустим Jenkins: /etc/init.d/jenkins restart
Теперь порт 8080 сервера CI будет «прослушиваться» Jenkins. Это значит, что при переходе в браузере по адресу <ip CI сервера: >8080, пользователь попадет в панель управления Jenkins. Конечно, такой способ доступа является не очень удобным, поэтому на сервере CI можно настроить доступ к Jenkins с помощью виртуальных хостов в Apache или Nginx.
Следующим важным шагом является настройка прав доступа. Это очень важно, особенно если сервер доступен через Интернет. Без соответствующих настроек он будет открыт для всех.
2. Добавление администратора
Manage Jenkins → Configure Global Security (глобальная настройка безопасности).
1. Заполняем необходимую информацию:
- Enable security — true; //включить защиту;
- Jenkins’own user database — «Jenkins’ own user database»; //использовать для авторизации базу данных Jenkins;
- Authorization — «Matrix-based security»; //матричное распределение прав доступа (распределение прав на уровне проектов);
- User/group to add — «admin». //предоставляем пользователю «admin» право доступа в панель управления Jenkins.
2. Сохраняем настройки.
Теперь при попытке входа в панель управления Jenkins будет требовать от пользователя авторизоваться.
3. Создание пользователя для GitHub
Теперь необходимо создать учетные данные для доступа GitHub к серверу Jenkins.
В панели управления Jenkins переходим Manage Jenkins → Manage Users → Create User. Заполняем форму регистрации, идентичную той, которая была при регистрации администратора, нажимаем Sign Up.
После создания пользователя следует дать ему необходимые права. Для этого перейдем в Manage jenkins → Configure Global Security (настройка глобальной безопасности).
Из всех этих настроек нам необходима матрица безопасности.
Для начала добавим пользователя в эту матрицу. В поле «User/group to add» вводим имя созданного пользователя и нажимаем Add. Пользователь появится в матрице. Предоставим ему права на чтение и сборку. Для этого в подстолбцах Read и Build столбца «Job» напротив имени созданного пользователя устанавливаем чек-боксы и нажимаем Save.
4. Установка плагина для GitHub
Переходим в Manage Jenkins → Manage Plugins → Вкладка «Available». Выбираем для установки три плагина:
- Github Authentication plugin;
- GitHub plugin;
- GitHub API Plugin.
Нажимаем на кнопку «Download now and install after restart» и ожидаем завершения установки.
5. Настройка сервера для работы с Jenkins
На продукционном сервере проекта (куда будет производиться автодеплой) необходимо создать пользователя «jenkins»:
sudo adduser jenkins
Далее на сервере необходимо сгенерировать ssh ключи. От пользователя «jenkins» выполняем команду:
ssh-keygen
И вводим необходимую информацию.
Также для доступа необходимо добавить публичный ключ в файл... /jenkins/.ssh/authorized_keys (если файла нет, его необходимо создать)
Кроме этого требуется создать на GitHub открытый SSH ключ для данного сервера. О том, как это сделать, можно посмотреть здесь.
Данный этап завершен.
Если что-то по ssh-аутентификации является непонятным, рекомендую прочитать очень полезную статью на данную тему.
6. Настройка доступа к серверу
Для того чтобы Jenkins при автодеплое на сервере с рабочей версией проекта мог авторизовываться на нем, в панели управления требуется создать необходимые данные для аутентификации. Для этого в панели управления Jenkins переходим Credentials → Global credentials → Add Credentials и делаем следующее:
- В качестве Kind выбираем «SSH Username with private key»;
- Username — вводим имя созданного на сервере пользователя («jenkins») ;
- Private Key — «Enter directly», в текстовое поле копируем все содержимое файла приватного ключа jenkins-пользователя. («.../jenkins/.ssh/id_rsa»);
- Нажимаем «OK».
Теперь необходимо настроить подключение к серверу. Для этого в панели управления jenkins перейдем Manage Jenkins → Manage Nodes → New Node. Производим следующие действия:
- Вводим имя продукционного сервера (к примеру — «target»), устанавливаем «Dumb Slave», нажимаем «OK»;
- Вводим путь к корневой директории Jenkins на продукционном сервере. В качестве корневой директории на целевом сервере обычно выбирается директория пользователя jenkins («.../jenkins»);
- Вводим «Labels»; например — «target_server». Label — это метка, по которой задача будет привязываться к конкретному серверу;
- Host — вводим имя хоста, к которому будем обращаться;
- Credentials — выбираем ранее созданные данные для аутентификации;
- Нажимаем «Save».
Через некоторое время, подключение к серверу должно успешно установиться. Если все прошло успешно, в Manage Jenkins → Manage Nodes вы должны увидеть примерно следующую картину:
Если подключение не устанавливается, нажимаем на созданное подключение («target»), выбираем «Log» в левом навигационном меню и смотрим, что произошло не так.
Наиболее распространенными ошибками являются:
Первое решение — изменить в настройках подключения корневую директорию на домашнюю директорию пользователя Jenkins.
Второе решение — предоставить пользователю Jenkins права на запись и чтение указанной в настройках подключения директории.
7. Настройка хука GitHub
Для GitHub-репозитория, который будет использоваться, необходимо настроить веб-хук так, чтобы при обновлении репозитория, хук отсылал запрос на обновление Jenkins. Для этого:
- Переходим в созданный репозиторий на GitHub-е.
- «Settings» → «Webhooks & services».
- «Add webhook».
- Вводим «Payload URL» (куда будет обращаться GitHub). Он должен иметь следующий формат
<протокол>: //<имя пользователя для github в jenkins>: <пароль пользователя github в jenkins>@<домен>/github-webhook/
(например — http://github:123456@testingci.me:8080/github-webhook/). - «Content type» — «application/json».
- «Which events would you like to trigger this webhook?» — «Just the push event».
- «Active» — true.
- Нажимаем «Add webhook».
Веб-хук создан.
8. Создание задачи Jenkins
Теперь необходимо создать задачу, которая будет выполняться при обновлении репозитория. В панели администрирования Jenkins делаем следующее:
- Нажимаем «New Item».
- Вводим название задачи в поле «Item name».
- Выбираем «Freestyle project» и нажимаем «OK».
- «Restrict where this project can be run» — вводим имя метки, которое было выбрано при добавлении сервера (например — «target_server»).
- «Source Code Management» — выбираем «Git» и вводим адрес репозитория в поле «Repository URL» (например — «git@github.com: TestCi/Continuous-integration.git»).
- В поле «Credentials» выбираем ранее созданные учетные данные.
- «Build Triggers» — «Build when a change is pushed to GitHub».
- «Build» — «Execute shell» (shell-скрипт будет выполняться при каждом push-е на github):
sudo rsync -a —cvs-exclude —delete —omit-dir-times. / <директория проекта> sudo chown -R www-data: jenkins < директория проекта>
Первая строка производит синхронизацию на продукционном сервере рабочей директории Jenkins с целевой директорией проекта. Вторая строка —
-
установка владельца файлов проекта.
- Сохраняем.
Чтобы не возникло никаких проблем с правами при выполнении команд, необходимо в файл sudoers с помощью команды visudo дописать пару строчек:
jenkins ALL = NOPASSWD: /bin/chown
jenkins ALL = NOPASSWD: /usr/bin/rsync
Вот и все! Теперь, при push-e кода в GitHub репозиторий, происходит автодеплой кода на продукционный сервер проекта. Цель достигнута!
Список полезных ссылок
- habrahabr.ru — интересная статья по Continuous Integration;
- 8host.com — установка Jenkins;
- vds-admin.ru — статья по SSH-аутентификации;
- fourword.fourkitchens.com — настройка Jenkins для работы с GitHub;
- opennet.ru — статья по rsync;
- devacademy.ru — статья по настройке виртуальных хостов в Nginx;
- digitalocean.com — статья по настройке виртуальных хостов в Apache.