Githubizer: автодеплой с Гитхаба на сервер

    Интересно, скольким из вас приходилось хотя бы иногда, но повторять рутиные действия для настройки автодеплоя с гитхаба на сервер: создать ssh-ключ, добавить его для репозтория проекта на Гитхабе, создать скрипт, который будет слушать какой-то адрес, добавить вебхук в интерфейсе гитхаба, который будет дергать этот скрипт… Уфф… А что, если я скажу вам, что автоматизировал все эти действия по-максимуму? Да, теперь вам нужно выполнить всего пару команд и автодеплой запущен и работает! И все это благодаря Гитхабайзеру.

    Итак, адрес репозитория github.com/chvanikoff/githubizer
    Как этим пользоваться:

    Теперь детальнее:
    1. Клонируем репозиторий Гитхабайзера
    $> git clone github.com/chvanikoff/githubizer
    2. переходим в директорию репозитория и правим конфиг под себя
    $> cd githubizer && vim priv/application.config
    3. Компилируем и запускаем Гитхабайзер:
    $> make all run

    Подробнее о конфиге (в нем есть комментарии на английском, здесь напишу на русском):
    {http_server, [
            %% количество неблокирующих акцепторов для обработки запросов от Гитхаба. Сомневаюсь, что придется когда-нибудь менять, но возможность есть
    	{nba, 10},
            %% порт, который будет слушать сервер, обрабатывающий запросы от Гитхаба
    	{port, 8989},
            %% URL, который будет запрашивать Гитхаб при пуше в него
    	{url, ["/secret/hook/url"]}
    ]}.
    
    {github, [
            %% Логин пользователя на Гитхабе
    	{username, "login"},
            %% Email пользователя на Гитхабе
    	{email, "email"},
            %% Пароль пользователя, опять же на Гитхабе
    	{password, "m3g1p1$$w0rd"},
            %% Имя репозитория (например - githubizer)
    	{repository, "repo_name, not url!"}
    ]}.
    
    {server, [
            %% Директория на сервере, в которой будет лежать ваш проект (должна быть пустой). Скоро добавлю замену {REPO} на имя репозитория, но пока этого нет
    	{docroot, "/home/chvanikoff/erlang/{REPO}"},
            %% Адрес сервера (в виде домена, или IP-адреса)
    	{domain, "http://site.com"}
    ]}.
    


    Что произойдет после совершения вышеописанных действий:
    1. Будут созданы, если не существовали ранее, ssh-ключи ~/.ssh/githubizer и ~/.ssh/githubizer.pub
    2. Они будут добавлены для репозитория на Гитхабе
    3. Репозиторий будет склонирован локально (если директория, указанная в конфиге server.docroot, пустая — иначе считается, что нужный репозиторий уже склонирован туда)
    4. Будет запущен маленький веб-сервер (Cowboy) c 2 http-хендлерами, который будет слушать указанный в конфиге порт и обрабатывать 2 типа запросов: запросы к адресу из конфига (напр. «secret/hook/url») и все остальные. Отвечать будет 404 на все запросы, однако на запросы первого типа будет производиться git pull из директории репозитория
    5. ...
    6. «Вот и все, ребята» (с)


    P.S.: код может быть местами грязным — не пинайте, я все еще учусь.
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 15

      +1
      Или проще — ssh server.hostname /srv/deployscript.sh
        +1
        А как же пункт «написать deployscript.sh, который умеет все вышеперечисленное»? =)
          +4
          Так там простой git pull. По сути, должно быть два скрипта:
          на локальной машине что-то вроде
          #!/bin/sh
          echo "--- Indexing changes"
          git add -A
          echo "--- Making commit"
          git commit -m'deploy $1'
          echo "--- Pushing to master"
          git push origin master
          echo "--- Executing remote pull"
          ssh server.hostname /srv/deployscript.sh
          

          И на сервере примерно так:
          #!/bin/bash
          
          cd /srv/project_path
          git pull
          


          Само собой, если надо раскатывать по серверу конфиги nginx или выполнять миграции, таким велосипедом не обойтись.
            0
            Само собой, если надо раскатывать по серверу конфиги nginx или выполнять миграции, таким велосипедом не обойтись.

            В этом случае следующее звено — Fabric :)
              –1
              А также
              — Создать ssh-ключ для сервера
              — Добавить его на сервере
              — Поправить ~/.ssh/config, если хочется использовать не стандартный id_rsa
              — Вводить при каждом пуше команду запуска скрипта (ключевой, пожалуй, момент)

              Понятно, что это все мелочи, но именно эта рутина и заставила меня написать Гитхабайзер (ну и желание попрактиковаться с Эрлангом, да). Так-то можно и вообще обойтись
              $> git push
              $> ssh -f server 'cd /path/to/app && git pull'
              
                +1
                Если такие манипуляции приходится выполнять часто, конечно будет нужна автоматизация.
          +3
          Скажите, уважаемые, а кто-нибудь пользуется таким способом?

          git push prod-server -f
          ssh prod-server 'git reset --hard'

          Смысл в том, что серверу не дается доступ ни в какие гитхабы. Он обновляется пассивно.
            0
            Весьма интересно.
            А если на push сервера поставить хук для git reset?
              0
              Я это выдумывал с точки зрения минимальных модификаций сервера, собственно, там только надо вписать ignore в [receive]. чтобы push -f не ругался на currentBranch. Подразумевается, что всякие ssh ключи туда уже настроены. Идея в том, чтобы не размазывать всякие неявные зависимости по хукам, а иметь всю последовательность в одном скрипте.

              Способ хорош для тех случаев, когда один человк деплоит один реп в проект. Если человек больше или зависимости какие-то более сложные, то тогда что-то другое надо.
                0
                Зачем ssh ключи? Мы же прямо на prod пушим.
                  0
                  Чтобы аутентифицироваться.
                  Можно и логин-пароль вводить, конечно, но это лениво каждый раз.
            +1
            а почему не hook'ом post-receive с
            git checkout -f
            
            внутри?
              0
              У меня небольшой скриптик на node.js следит за файлом в директории /tmp. Если кто-то сделает на файле touch, скрипт делает git pull и перезапускает приложение. Картину дополняет CI Jenkins, который после удачного прогона всех тестов делает touch. Таким образом на девелоперском серваке всегда крутится свежая и рабочая версия приложения, можно тестить ручками.
                +1
                Использую для таких целей capistrano.
                Возможности большие: разные стратегии деплоя (например скопировать директорию проекта с локальной машины, вытянуть сервером определенную ветку репозитория), хранит нужную глубину версий для отката изменений, умеет использовать gateway для подключения к серверу.
                Деплою так java-приложения, статику и рельсы. В случае последних возможностей ещё больше (e. g. zero-downtime deploy при использовании unicorn или rainbow).

                У пайтонистов, вроде было что-то аналогичное capistrano.

                И можно, конечно, предложить SCM (chef, puppet, cfengine, bcfg2), которые ещё более гибкие, чем просто тулзы для деплоя.
                  0
                  Есть еще хороший и бесплатный сервис
                  https://deploybutton.com/.

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

                  Самое читаемое