Наш гость, создатель инструментов для разработчиков из Pantheon, рассказывает, как автоматизировать деплои WordPress с помощью GitLab CI/CD.
В Pantheon я занимаюсь связями с разработчиками, поэтому всегда ищу новые способы помочь разработчикам WordPress и Drupal решать проблемы с автоматизацией в рабочих процессах. Для этого я люблю экспериментировать с новыми инструментами и сочетать их друг с другом для эффективной работы.
Я часто вижу, как разработчики мучаются с одним сервером для разработки.
Так себе удовольствие — ждать своей очереди использовать сервер или отправлять клиентам URL с пометкой: «Вот здесь смотреть, а здесь пока не смотреть».
Среды multidev — один из крутых инструментов Pantheon — решают эту проблему, ведь с ними можно по запросу создавать среды под ветки Git. У каждой среды multidev свой URL и база данных, поэтому разработчики спокойно работают, проверяют качество и получают одобрение, не наступая друг другу на пятки.
Но в Pantheon нет инструментов для контроля версий или непрерывной интеграции и деплоя (CI/CD). Зато это гибкая платформа, с которой можно интегрировать любые инструменты.
Еще я заметил, что для разработки команды используют одни инструменты, а для сборки и деплоя — другие.
Например, у них разные инструменты для контроля версий и CI/CD. Приходится возиться и переключаться между инструментами, чтобы редактировать код и диагностировать проблемы.
На GitLab есть полноценный набор инструментов для разработки: для контроля версий, тикетов, мерж-реквестов, лучший в классе пайплайн CI/CD, реестр контейнеров и все в таком духе. Мне пока не попадалось приложений, в которых было бы столько всего для управления рабочим процессом разработки.
Я обожаю автоматизацию, поэтому я изучил, как подключить Pantheon к GitLab, чтобы коммиты в главную ветку на GitLab деплоились в главной среде разработки в Pantheon. А еще мерж-реквесты на GitLab могут создавать и деплоить код в среды multidev в Pantheon.
В этом руководстве я расскажу, как настроить соединение между GitLab и Pantheon и оптимизировать рабочий процесс WordPress и Drupal.
Можно, конечно, отзеркалить репозиторий GitLab, но мы все будем делать ручками, чтобы покопаться в GitLab CI и в будущем использовать этот инструмент не только для деплоя.
Введение
Для этого поста нужно понимать, что Pantheon разбивает каждый сайт на три элемента: код, база данных и файлы.
В код входят файлы CMS, например ядро, плагины и темы WordPress. Эти файлы управляются в репозитории Git, размещенном Pantheon, то есть мы можем деплоить код из GitLab в Pantheon с Git.
Файлами в Pantheon называются медиафайлы, то есть картинки для сайта. Обычно они загружаются пользователями, и Git их игнорирует.
Создайте бесплатный аккаунт, узнайте больше о рабочем процессе Pantheon или запишитесь на демо на pantheon.io.
Предположения
Мой проект на Pantheon и GitLab называется pantheon-gitlab-blog-demo
. Имя проекта должно быть уникальным. Тут мы будем работать с сайтом WordPress. Можно взять и Drupal, но нужно будет кое-что изменить.
Я буду использовать командную строку Git, а вы можете работать в графическом интерфейсе, если хотите.
Создаем проект
Для начала создаем проект GitLab (к этому мы еще вернемся).
Теперь создаем сайт WordPress на Pantheon. Потом устанавливаем WordPress для дашборда сайта.
Если руки чешутся что-то изменить, например, плагины поудалять и подабавлять, потерпите. Сайт еще не подключен к GitLab, а мы хотим, чтобы все изменения кода проходили через GitLab.
Когда установим WordPress, возвращаемся на дашборд сайта Pantheon и меняем режим разработки на Git.
Начальный коммит на GitLab
Теперь нужно перекинуть начальный код WordPress с сайта Pantheon на GitLab. Для этого клонируем код из репозитория Git сайта Pantheon локально, а потом отправляем в репозиторий GitLab.
Чтобы было проще и безопаснее, добавим SSH-ключ в Pantheon и не будем каждый раз вводить пароль, когда клонируем репозиторий Pantheon Git. Заодно уже добавим SSH-ключ на GitLab.
Для этого клонируем сайт Pantheon локально, скопировав команду из поля Clone with Git на дашборде сайта.
Если нужна помощь, читайте документацию по началу работы с Git для Pantheon.
Теперь изменим git remote origin
, чтобы указать на GitLab вместо Pantheon. Это можно сделать командой git remote
.
Перейдем в проект GitLab и скопируем URL репозитория из выпадающего списка Clone на странице деталей проекта. Выберем вариант Clone with SSH, ведь мы уже настроили SSH-ключ.
По умолчанию git remote
для локальной копии репозитория кода — origin
. Это можно поменять c git remote set-url origin [URL репозитория GitLab]
, где вместо скобок вводим фактический URL.
Наконец, запускаем git push origin master --force
, чтобы отправить код WordPress с сайта Pantheon на GitLab.
Параметр –force нужен только один раз. Потом в командах git push
на GitLab его не будет.
Настраиваем учетные данные и переменные
Помните, как мы локально добавили SSH-ключ, чтобы авторизоваться в Pantheon и GitLab? SSH-токен можно использовать для авторизации GitLab и Pantheon.
В GitLab есть отличная документация. Давайте посмотрим раздел об SSH-ключах при использовании Docker-экзекьютора в документе об использовании SSH-ключей с GitLab CI/CD.
Сейчас мы выполним первые два шага: создадим новую пару SSH-ключей локально с ssh-keygen и добавим закрытый ключ как переменную в проект.
Потом зададим SSH_PRIVATE_KEY
как переменную среды GitLab CI/CD в параметрах проекта.
На третьем и четвертом шагах создадим файл .gitlab-ci.yml
с таким содержимым:
before_script:
# See https://docs.gitlab.com/ee/ci/ssh_keys/README.html
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p $HOME/.ssh && echo "StrictHostKeyChecking no" >> "$HOME/.ssh/config"
- git config --global user.email "$GITLAB_USER_EMAIL"
- git config --global user.name "Gitlab CI"
Пока не будем коммитить файл .gitlab-ci.yml
, потом к нему нужно будет еще кое-что добавить.
Теперь выполняем пятый шаг и добавляем открытый ключ, который создали в первом шаге, к сервисам, к которым вам нужен доступ в среде сборки.
В нашем случае мы хотим из GitLab получать доступ к Pantheon. Следуем инструкциям в документе Pantheon по добавлению SSH-ключа в Pantheon и выполняем этот шаг.
Помним: закрытый SSH — в GitLab, открытый — в Pantheon.
Настроим еще несколько переменных среды. Первая называется PANTHEON_SITE. Ее значение — имя сайта Pantheon у вас на машине.
Имя на машине указано в конце команды Clone with Git. Вы уже клонировали сайт локально, так что это будет имя каталога локального репозитория.
Дальше настроим переменную среду PANTHEON_GIT_URL
. Это URL репозитория Git для сайта Pantheon, который мы уже использовали.
Вводим только URL SSH репозитория, без git clone
и имени сайта на машине в конце.
Фух. Это сделали, теперь можем закончить наш файл .gitlab-ci.yml
.
Создаем задачу деплоя
То, что мы поначалу будем делать с GitLab CI, очень похоже на то, что мы делали с репозиториями Git раньше. Но на этот раз добавим репозиторий Pantheon как второй удаленный источник Git, а потом отправим код из GitLab в Pantheon.
Для этого настроим этап deploy
и задачу deploy:dev
, ведь мы будем деплоить в среду разработки на Pantheon. В результате файл .gitlab-ci.yml
будет выглядеть так:
stages:
- deploy
before_script:
# See https://docs.gitlab.com/ee/ci/ssh_keys/README.html
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p $HOME/.ssh && echo "StrictHostKeyChecking no" >> "$HOME/.ssh/config"
- git config --global user.email "$GITLAB_USER_EMAIL"
- git config --global user.name "Gitlab CI"
deploy:dev:
stage: deploy
environment:
name: dev
url: https://dev-$PANTHEON_SITE.pantheonsite.io/
script:
- git remote add pantheon $PANTHEON_GIT_URL
- git push pantheon master --force
only:
- master
Переменные SSH_PRIVATE_KEY, PANTHEON_SITE
и PANTHEON_GIT_URL
должны выглядеть знакомо — мы настроили эти переменные среды раньше. С этими переменными мы сможем использовать значения в файле .gitlab-ci.yml
много раз, а обновлять их нужно будет только в одном месте.
Наконец, добавим, закоммитим и отправим файл .gitlab-ci.yml
на GitLab.
Проверяем деплой
Если мы все сделали правильно, задание deploy:dev
успешно выполнится в GitLab CI/CD и отправит коммит .gitlab-ci.yml
в Pantheon. Давайте посмотрим.
Отправляем ветки мерж-реквестов в Pantheon
Здесь мы будем использовать мою любимую функцию Pantheon — multidev, где можно по запросу создавать дополнительные среды Pantheon для веток Git.
Доступ к multidev ограничен, так что этот раздел можно не выполнять. Но если у вас есть доступ, можно серьезно увеличить производительность, настроив автоматическое создание сред multidev на Pantheon из мерж-реквестов GitLab.
Сначала сделаем новую ветку Git локально с помощью git checkout -b multidev-support
. Теперь снова кое-что изменим в .gitlab-ci.yml
.
Мне нравится указывать номер мерж-реквеста в имени среды Pantheon. Например, первый мерж-реквест — mr-1
, второй — mr-2
и т. д.
Мерж-реквест меняется, так что нам нужно динамически определять имена веток Pantheon. На GitLab это просто — нужно использовать предопределенные переменные среды.
Мы можем взять $CI_MERGE_REQUEST_IID
, чтобы указать номер мерж-реквеста. Давайте применим все это вместе с глобальными переменными среды, которые указали раньше, и добавим новую задачу deploy:multidev в конце файла .gitlab-ci.yml
.
deploy:multidev:
stage: deploy
environment:
name: multidev/mr-$CI_MERGE_REQUEST_IID
url: https://mr-$CI_MERGE_REQUEST_IID-$PANTHEON_SITE.pantheonsite.io/
script:
# Checkout the merge request source branch
- git checkout $CI_COMMIT_REF_NAME
# Add the Pantheon git repository as an additional remote
- git remote add pantheon $PANTHEON_GIT_URL
# Push the merge request source branch to Pantheon
- git push pantheon $CI_COMMIT_REF_NAME:mr-$CI_MERGE_REQUEST_IID --force
only:
- merge_requests
Будет похоже на нашу задачу deploy:dev
, только ветка отправляется в Pantheon, а не в master
.
Мы добавили и закоммитили обновленный файл .gitlab-ci.yml
, а теперь отправим новую ветку в GitLab с git push -u origin multidev-support
.
Теперь создадим новый мерж-реквест из ветки multidev-support
, нажав Create merge request.
Создав мерж-реквест, смотрим, как выполняется задача CI/CD deploy:multidev
.
Смотрите — в Pantheon отправлена новая ветка. Но если перейдем в раздел multidev на дашборде сайта на Pantheon, не увидим там новую среду
Посмотрим раздел Git Branches.
В итоге наша ветка mr-1
добралась до Pantheon. Создадим среду из ветки mr-1
.
Мы создали среду multidev, а теперь вернемся в GitLab и заглянем в раздел Operations > Environments. Мы увидим записи для dev
и mr-1
.
Это потому, что мы добавили запись environment
с именем name
и url
в задачи CI/CD. Если нажать значок открытой среды, мы перейдем по URL среды multidev на Pantheon.
Автоматизируем создание multidev
В принципе, на этом можно остановиться и просто не забывать создавать среду multidev под каждый мерж-реквест, но этот процесс можно автоматизировать.
В Pantheon есть инструмент командной строки Terminus, где можно работать с платформой автоматически. В Terminus можно создавать среды multidev из командной строки — идеально для GitLab CI.
Нам нужен новый мерж-реквест, чтобы это потестить. Создадим новую ветку с помощью git checkout -b auto-multidev-creation
.
Чтобы использовать Terminus в задачах GitLab CI/CD, нужен токен машины для аутентификации в Terminus и образ контейнера с Terminus.
Создаем токен машины Pantheon, сохраняем его в безопасном месте и добавляем как глобальную переменную среды в GitLab с именем PANTHEON_MACHINE_TOKEN
.
Если забыли, как добавлять переменные среды GitLab, вернитесь туда, где мы определяли PANTHEON_SITE
.
Создаем Dockerfile с Terminus
Если вы не используете Docker или недолюбливаете файлы Dockerfile
, возьмите мой образ registry.gitlab.com/ataylorme/pantheon-gitlab-blog-demo:latest
и пропустите этот раздел.
В GitLab есть реестр контейнеров, где можно собрать и разместить Dockerfile для нашего проекта. Давайте создадим файл Dockerfile с Terminus, чтобы работать с Pantheon.
Terminus — это инструмент командной строки на PHP, так что начнем с образа PHP. Я устанавливаю Terminus через Composer, поэтому за основу возьму официальный образ Docker Composer. Создаем Dockerfile
в каталоге локального репозитория с таким содержимым:
# Use the official Composer image as a parent image
FROM composer:1.8
# Update/upgrade apk
RUN apk update
RUN apk upgrade
# Make the Terminus directory
RUN mkdir -p /usr/local/share/terminus
# Install Terminus 2.x with Composer
RUN /usr/bin/env COMPOSER_BIN_DIR=/usr/local/bin composer -n --working-dir=/usr/local/share/terminus require pantheon-systems/terminus:"^2"
Следуем инструкциям по сборке и отправке образов из раздела Build and push images в документации реестра контейнеров, чтобы собрать образ из Dockerfile
и отправить его в GitLab.
Открываем раздел Registry в проекте GitLab. Если все пошло по плану, там будет наш образ. Запишите ссылку на тег образа — она нужна нам для файла .gitlab-ci.yml
.
Раздел script
в задаче deploy:multidev
начинает разрастаться, так что давайте перенесем его в отдельный файл. Создаем новый файл private/multidev-deploy.sh:
#!/bin/bash
# Store the mr- environment name
export PANTHEON_ENV=mr-$CI_MERGE_REQUEST_IID
# Authenticate with Terminus
terminus auth:login --machine-token=$PANTHEON_MACHINE_TOKEN
# Checkout the merge request source branch
git checkout $CI_COMMIT_REF_NAME
# Add the Pantheon Git repository as an additional remote
git remote add pantheon $PANTHEON_GIT_URL
# Push the merge request source branch to Pantheon
git push pantheon $CI_COMMIT_REF_NAME:$PANTHEON_ENV --force
# Create a function for determining if a multidev exists
TERMINUS_DOES_MULTIDEV_EXIST()
{
# Stash a list of Pantheon multidev environments
PANTHEON_MULTIDEV_LIST="$(terminus multidev:list ${PANTHEON_SITE} --format=list --field=id)"
while read -r multiDev; do
if [[ "${multiDev}" == "$1" ]]
then
return 0;
fi
done <<< "$PANTHEON_MULTIDEV_LIST"
return 1;
}
# If the mutltidev doesn't exist
if ! TERMINUS_DOES_MULTIDEV_EXIST $PANTHEON_ENV
then
# Create it with Terminus
echo "No multidev for $PANTHEON_ENV found, creating one..."
terminus multidev:create $PANTHEON_SITE.dev $PANTHEON_ENV
else
echo "The multidev $PANTHEON_ENV already exists, skipping creating it..."
fi
Скрипт лежит в приватном каталоге и не дает веб-доступ на Pantheon. У нас есть скрипт для нашей логики multidev. Давайте теперь обновим раздел deploy:multidev
файла .gitlab-ci.yml
, чтобы получилось так:
deploy:multidev:
stage: deploy
environment:
name: multidev/mr-$CI_MERGE_REQUEST_IID
url: https://mr-$CI_MERGE_REQUEST_IID-$PANTHEON_SITE.pantheonsite.io/
script:
# Run the multidev deploy script
- "/bin/bash ./private/multidev-deploy.sh"
only:
- merge_requests
Надо убедиться, что наши задачи выполняются в созданном кастомном образе, так что добавим определение image
с URL реестра в .gitlab-ci.yml
. В итоге у нас получился такой файл .gitlab-ci.yml
:
image: registry.gitlab.com/ataylorme/pantheon-gitlab-blog-demo:latest
stages:
- deploy
before_script:
# See https://docs.gitlab.com/ee/ci/ssh_keys/README.html
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p $HOME/.ssh && echo "StrictHostKeyChecking no" >> "$HOME/.ssh/config"
- git config --global user.email "$GITLAB_USER_EMAIL"
- git config --global user.name "Gitlab CI"
deploy:dev:
stage: deploy
environment:
name: dev
url: https://dev-$PANTHEON_SITE.pantheonsite.io/
script:
- git remote add pantheon $PANTHEON_GIT_URL
- git push pantheon master --force
only:
- master
deploy:multidev:
stage: deploy
environment:
name: multidev/mr-$CI_MERGE_REQUEST_IID
url: https://mr-$CI_MERGE_REQUEST_IID-$PANTHEON_SITE.pantheonsite.io/
script:
# Run the multidev deploy script
- "/bin/bash ./private/multidev-deploy.sh"
only:
- merge_requests
Добавляем, коммитим и отправляем private/multidev-deploy.sh
и .gitlab-ci.yml
. Теперь возвращаемся в GitLab и ждем, пока выполнится задача CI/CD. Потерпите: multidev может создаваться несколько минут.
Потом идем смотреть список multidev на Pantheon. О чудо! Среда multidev mr-2
уже тут.
Заключение
Моя команда заработала гораздо веселее, когда мы стали открывать мерж-реквесты и создавать среды автоматически.
С мощными инструментами GitLab и Pantheon можно подключить GitLab к Pantheon автоматически.
Раз мы используем GitLab CI/CD, нашему рабочему процессу будет куда расти. Вот пара идей, чтобы приступить к работе:
- Добавьте шаг сборки.
- Добавьте автоматизированное тестирование.
- Добавьте задачу, чтобы гарантировать соблюдение стандартов кода.
- Добавьте динамическое тестирование безопасности приложений.
Напишите, что вы думаете о GitLab, Pantheon и автоматизации.
P.S. А вы знали, что Terminus, инструмент командной строки Pantheon, можно расширять через плагины?
Мы в Pantheon неплохо потрудились над версией 2 нашего плагина для инструментов сборки Terminus с поддержкой GitLab. Если вы не хотите возиться с настройкой для каждого проекта, попробуйте этот плагин и помогите нам потестить бету v2. Для команды Terminus build:project:create
нужен только токен Pantheon и токен GitLab. Она развернет один из примеров проекта с Composer и автоматическим тестированием, создаст новый проект в GitLab, новый сайт Pantheon, и соединит их с помощью переменных среды и SSH-ключей.
Об авторе
Эндрю Тейлор (Andrew Taylor) создает инструменты для разработчиков в Pantheon.
SlavikF
Это правда, что по русски staging environment называют «промежуточный сервер»?
nAbdullin Автор
Спасибо, что заметили! Разобрались: правка ускользнула при вычитке.