У меня давно вошло в привычку создавать репозитории на GitHub. Это куда эффективнее, чем держать все на Google Drive или, того хуже, на жестком диске. Но здесь сразу появляется вопрос: как выполнить деплой на рабочий сервер?

Большинство поисковых запросов выводили меня на Jenkins и другие средства непрерывного развертывания. Но мне хотелось найти иное решение. Так я вышел на бесплатный сервис Webhook.

Skillbox рекомендует: Практический курс «Мобильный разработчик PRO».

Напоминаем: для всех читателей «Хабра» — скидка 10 000 рублей при записи на любой курс Skillbox по промокоду «Хабр».

Техническая основа Webhook — свежий дроплет Digital Ocean с Ubuntu 16.04 в качестве рабочего сервера. Для снижения количества шагов, необходимых для реализации задуманного, все действия выполняются root-пользователем.

Начнем с GitHub


Если у вас есть репозиторий и вы хотите его использовать, можно пропустить этот шаг — просто воспользуйтесь SSH URI, и все. Если нет, то создайте его и тоже воспользуйтесь SSH URI.



Устанавливаем Go и Webhook (дроплет Digital Ocean).

Прежде чем начать, стоит выполнить быстрый апдейт и апгрейд со свежим установщиком Ubuntu 16.04.

sudo apt update -y && sudo apt upgrade -y

Теперь для установки WebHook нужно установить язык программирования Go. На время написания этой статьи была актуальна версия 1.11.4, так что если у вас иная версия, нужно внести правки.

wget https://dl.google.com/go/go1.11.4.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.11.4.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

Пора загрузить последнюю версию Webhook.

go get github.com/adnanh/webhook

В ходе загрузки нет прогресс-бара, так что нужно просто подождать. После завершения процесса выполните ~/go/bin/webhook.

Webhook установлен, но нужно создать структуру директорий и файлов, чтобы все работало как надо.

mkdir ~/webhooks
mkdir ~/webhooks/deployment-tutorial
touch ~/webhooks/hooks.json
touch ~/webhooks/deployment-tutorial/deploy.sh
chmod +x ~/webhooks/deployment-tutorial/deploy.sh

Файл hooks.json отвечает за конфигурацию и роутинг, а deploy.sh служит инструментом для выполнения команд, необходимых для обновлений с GitHub.

Первым делом стоит настроить hooks.json, открыв его в текстовом редакторе. Файл содержит конфигурацию для эндпоинтов, которые будут созданы после запуска Webhook, и представляет собой массив объектов, каждый из которых — уникальный эндпоинт.

[{
    "id": "deployment-tutorial",
    "execute-command": "/root/webhooks/deployment-tutorial/deploy.sh",
    "command-working-directory": "/root/deployed-site/",
    "response-message": "Executing deploy script...",
    "trigger-rule": {
        "match": {
            "type": "payload-hash-sha1",
            "secret": "The Returners",
            "parameter": {
                "source": "header",
                "name": "X-Hub-Signature"
            }
        }
    }
}]

Id — уникальное имя, которое будет использоваться для URL эндпоинта;
execute-command — скрипт, который будет выполняться при активации эндпоинта;
command-working-directory — директория, которая используется во время запуска execute-command;
trigger-rule — опция, которая будет использоваться в целях информационной безопасности, это секретная фраза для эндпоинтов.

Напомню, что все действия я выполняю от root, поэтому начальный адрес /root. Если логиниться под обычным пользователем, нужно прописать /home/username, где username, что логично, — имя этого пользователя. Не нужно использовать ~/, путь должен быть абсолютным, в противном случае вы получите ошибку.

Вы могли заметить, что мы настроили рабочую папку, которая пока еще не существует. Перед тем как создать ее, нужно закончить с deploy.sh.

Скрипт всегда должен начинаться с “shebang”. Перед открытием файла стоит выполнить which bash. Ну а дальше выполняются следующие команды в скрипте:

#!/bin/bash
 
git fetch --all
git checkout --force "origin/master"

Теперь и Go, и Webhook установлены, так что нужно настроить конфигурацию в hooks.json и написать скрипт, отвечающий за деплой. Он будет изменять каталог назначения, работая с главной веткой репозитория GitHub.

Наконец, пора привести Webhook в активный режим, заменив 000.000.000.000 рабочим IP-адресом Doplet.

/root/go/bin/webhook -hooks /root/webhooks/hooks.json -ip "000.000.000.000" -verbose

В процессе выполнения можно заметить вывод URL с {id} на конце. Это будет id объекта, который уже создан в файле hooks.json: deployment-tutorial.

Настройка Git (Digital Ocean Droplet)


Настройка сервера еще не закончена. Для ее завершения нужно открыть новое окно терминала и снова аутентифицироваться на сервере, в то время как в первом окне идет выполнение Webhook. В самом начале мы задавали URI репозитория, теперь его нужно использовать.

Для этого требуется перейти в рабочую директорию, заданную в hooks.json, и прописать следующее:

git init
git remote add origin git@github.com:jhsu98/deployment-tutorial.git

При этом нужно заменить URI на свой собственный вместо того, что указал я.

Финальным шагом будет генерация ключей SSH для того, чтобы с их помощью подключаться к GitHub. В окне терминала набираем ssh-keygen и подтверждаем, нажимая Enter, пока генерируются ключи. Затем нужно вывести публичные ключи, набрав cat ~/.ssh/id_rsa.pub. Получится нечто вроде этого:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCyzJrPVOJqsTqD2R3xirTp3VNMwpmJMyLklzJg4sRQyslTUmbNNmDVO573EbXQQf2PqPQljqKDDlSaELdav4OTi1gPCoDary300yUqC/efLGHflZ6pMNuGsP2zTzerD/TMjzl1FXF1wOGTXqcC4TvGBS1bFyUY5n8wSOJ8ntZ6bBNv0zA2t7X1vH8ahIBJLKCayq9ipobKlHPYqxBt6zAoeh/ILQ0PWhGkmbGqqzqN1jcVWOefLgj4Dl8bZWORS1nkqrVg2wFC2nnibH97kZLsNrdQaeK8jUrkUWkJcUELI02mkkqh2RtBx9EwQEvsm9YuDBD9xF+HyuWoAeqcKerb root@github-webhook-tutorial

Ну а теперь все, что осталось, — настроить репозиторий GitHub и протестировать деплой.

Настройка ключа деплоя и Webhook (GitHub)


В браузере переходим в настройки для репозитория. Сначала нужно добавить Deployment Key.



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



Трем полям в этом разделе нужно уделить особенное внимание. Это payload URL, content type и secret. Payload URL — эндпоинт, который прослушивается Webhook, content type — формат данных, secret — кастомная строка из файла hooks.json. В нашем случае это “The Returners”.



После создания Webhook должна появиться соответствующая отметка в настройках, которая показывает, что сервер доступен. Если проверить терминал с работающим Webhook, можно видеть, что репозиторий уже в работе.

Для проверки рабочего процесса копируем репозиторий на локальную машину, если это еще не сделано, и вносим изменения в главную ветку. После этого они должны отобразиться и на сервере. Готово.

Разработчик, который уже выполнял все это несколько раз, тратит на настройку около 10 минут. Но это после того, как на метод проб и ошибок потрачены часы. Помните про эти четыре важных особенности настройки:

  • Обязательно используйте абсолютный путь для hooks.json.
  • Не делайте deploy.sh исполняемым файлом.
  • Подтверждайте SSH-соединения в ходе первого “контакта” GitHub и рабочего сервера.
  • Не используйте ошибочное “shebang” в баш-скрипте.

Skillbox рекомендует:

Комментарии (2)


  1. TheGodfather
    13.06.2019 21:46

    Вроде, должна была получиться хорошая статья для новичков, но что-то пошло не так…

    что все действия я выполняю от root,


    … ну, вы поняли?

    /root/go/bin/webhook -hooks /root/webhooks/hooks.json -ip «000.000.000.000» -verbose


    Это вы в терминале запустили? А как бедному новичку сделать так, чтобы эти вебхуки постоянно висели запущенными, в т.ч. перезапускались, когда вы перезагружаете сервер?

    Настройка Git (Digital Ocean Droplet)

    Причем тут DO вообще? Кроме постоянного упоминания баззворда.

    Не делайте deploy.sh исполняемым файлом.

    Добавили бы объяснение, почему.

    Для более современных сервисов, которые деплоятся чуть интереснее, чем просто «git pull && apply-migrations» было бы неплохо добавить пример, например, с перезапуском докер контейнера.


  1. alexesDev
    13.06.2019 22:01

    go тем и отличается от остальных, что для деплоя обычно хватает scp на бинарник. Не нужно, в общем, ставить go на сервер. Просто wget https://github.com/adnanh/webhook/releases/download/2.6.9/webhook-linux-386.tar.gz (ссылка со страницы releases) и распаковать.