Инженер-программист
0,0
рейтинг
7 мая 2013 в 09:42

Разработка → Git как удобная и простая альтернатива rsync и ftp для деплоя простых сайтов tutorial

Git*
С того самого момента, когда я начал изучать Git, меня волновали методы практического применения этой DCVS, делающие работу с использованием этой DCVS удобней и проще, в частности, когда нет необходимости, возможности и желания взаимодействовать с какими-то удаленными сервисами вроде GitHub или Beanstalk, и, в целом, делиться кодом с посторонними людьми. Так как большую часть времени я использую Git при разработке различных веб-ориентированных систем, первым рецептом, которым я хочу сегодня с вами поделиться, будет по-настоящему удобный и простой способ выгрузки исходных кодов и ресурсов сайта на любой сервер, на котором установлен Git.

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

На целевом сервере


Первым делом на целевом сервере в корне или, лучше, на уровень ниже корня сайта, создадим пустой репозитарий:

~/www$ git init
Initialized empty Git repository in /home/example.com/www/.git/

Так как мы работаем не с голым (bare) репозитарием, обязательно разрешим перезапись текущей ветки:

~/www$ git config receive.denyCurrentBranch ignore

Наконец, создадим хук .git/hooks/post-receive, который и будет делать всю работу:

#!/bin/sh
cd ..
GIT_DIR='.git'
git reset --hard

Разрешим выполнение для этого хука:

~/www$ chmod +x .git/hooks/post-receive

Локально у разработчика


Затем расскажем локальному репозитарию о том, куда следует делать выгрузку:

$ git remote add --track master origin ssh://server.example.net/~/www/

И загрузим основную ветку на целевой сервер:

$ git push --set-upstream origin master

Вот и всё!

Что дальше?


В дальнейшем, для выгрузки основной ветки на сервер когда нам это будет нужно, вам достаточно будет делать:

$  git add htdocs/index.html
$  git commit -m "Ещё один коммит"
$  git push

Этот удаленный репозитарий можно использовать и для любых других целей коллективной разработки, для которых обычно используют Git, например, выгружать другие ветки в целях обмена между разработчиками. Также можно по-умолчанию выгружать на сервере не master-ветку, а, например, release-ветку:

~/www$ git checkout release

А что если я изменю файлы прямо на сервере...


В представленном выше варианте все незакоммиченные изменения, которые были внесены напрямую на сервере, будут удалены при очередном git push, что, если вам достаточно не повезло, может быть неприемлемо. Если вам совершенно необходимо дать кому-то возможность менять файлы прямо на сервере, например, через FTP, вместо представленного выше хука post-receive используйте следующий .git/hooks/pre-receive:

#!/bin/sh
cd ..
GIT_DIR='.git'
git stash save --quiet
git stash show || true

Вместе с этим .git/hooks/post-receive:

#!/bin/sh
cd ..
GIT_DIR='.git'
git reset --hard
git stash pop --quiet || git reset --hard

В этой усложнённой схеме, в случае конфликтов при git push, вам нужно будет вручную сделать git stash pop на сервере и разрешить конфликты.

Что ещё нужно знать?


Убедитесь, что посторонние не могут прочитать файлы в каталоге .git в корне вашего сайта, либо размещайте корень репозитария на уровень ниже корня веб-сайта.
Алексей @alexkbs
карма
81,0
рейтинг 0,0
Инженер-программист
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

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

  • НЛО прилетело и опубликовало эту надпись здесь
  • +6
    Честно говоря такой подход актуален только для самых небольших «домашних» проектиков, да и то не во всех случаях. Существует огромное множество инструментов для деплоя проекта. А git, хоть его и можно использовать в этом ключе, не самый удобный вариант.

    Почему? Что делать, например, с зависимостями? А с миграциями? А если нужны какие-то «post-install» скрипты? Таких вопросов еще много. Всех их можно, конечно, как то решить и с git, но зачем, если есть готовые работающие альтернативы.

    Я бы посоветовал таким образом деплоить разве что статику. В этом случае действительно удобно.
    • +1
      Здравствуйте! Благодарю вас за комментарий. Совершенно с вами согласен. Во втором абзаце я пишу о том что этот подход будет удобен для небольших проектов. Для больших проектов, естественно, удобней будет использовать более подходящие решения.
    • +1
      Зато эти самые остальные способы, довольно не удобны как раз таки для небольших проектов.
      А этот вариант для меня то, что надо. Есть несколько проектов, в которых код пишу я один, но VCS естественно очень полезна, и нужен был простой способ деплоя. Под убунтой я нашел гит фтп, а под виндой вот, такого красивого решения не находил до этого дня.
    • 0
      Можно список альтернатив?
  • 0
    Не бросайте гит в корень рута сайта, иначе mySite.ru/.git/ будет доступен, ну и вся писанина тоже, главное знать где искать =)
    • –2
      О настройках доступа к файлам и каталогам посредством веб-сервера Вы, конечно, не слышали.
      Развивая Ваше замечание: а если не в корень, а глубже? Например, mySite.ru/somefolder/.git/? Или это так глубоко, что никто не найдет? :)
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Это не «step-by-step tutorial» по настройке всех возможных существующих веб-серверов и всех видов раздачи прав на чтение директорий и файлов, потому, пожалуйста, извините, но такие детали читателю придётся выяснить самостоятельно, прочитав документацию к Apache/nginx/Varnish или чему-то другому, которым уважаемый читатель пользуется.
    • 0
      скрытые файлы, как правило так даже подефолту, можно сделать недоступными.
  • 0
    capistrano?
    • 0
      Здравствуйте! Благодарю вас за комментарий. Во втором абзаце я пишу о том что этот подход будет удобен для небольших проектов. Для больших проектов, естественно, удобней будет использовать более подходящие решения.
      • 0
        Нууу… понятие небольшой-большой проект у разных людей может отличаться. Если уж и использовать git при диплойменте, то уж лучше сразу привыкать к хорошему (-:
      • 0
        настраивать капу не дольше, чем шаманить с гитом.
  • +2
    Не нужно учить людей плохому. Ведь кто-то может прочитать и использовать этот подход…
    • 0
      Расскажите о лучшем или покажите почему этот подход плохой.
      • 0
        Этот подход подойдет для внутренних сайтиков, но для чего-то более серьезного он не подойдет.
        Например, во время деплоя у вас поведение сайта будет непредсказуемым (потому что в некоторый момент времени у вас будет не полный каталог файлов).
        Вам надо дополнительно папку .git скрывать через настройки сервера. И файлы .gitignore. Это хорошо если у вас нет субмодулей, а вот когда они появятся, нужно по крайней мере об этом не забыть.
        Ну и кроме того, конкретно эта реализация может просто зависнуть, если git что-нибудь спросит.
        Есть хорошие реализации git-деплоя в виде сторонних скриптов, можно их поискать (типа git-export, но не он).

        • –2
          В вашем комментарии содержатся противоречия тут и там. Вы пишите что для чего-то серьезного этот подход не подойдет. Потом вы пишете что во время деплоя у сайта будет неполный каталог файлов.

          Эти два положения противоречат друг другу потому что у серьёзных сайтов нет проблемы неполного каталога сайтов. Для сайтов на Ruby и Python лекарство от неполной копии присутствует штатно. Для серьёзных сайтов на PHP, которые, как минимум, располагаются на собственном сервере, тоже есть очень простое и красивое решение этой проблемы. Таким образом, проблема «неполного каталога» есть только у несерьёзных сайтов, а значит ваш аргумент о неполном каталоге здесь не подходит.

          Точно такое же противоречие касается скрытия каталога .git: даже несерьёзные проекты на современных серьёзных фреймворках по-умолчанию имеют каталог под корень сайта и статические файлы. Таким образом, проблема «скрытия каталога» есть только у несерьёзных сайтов, а значит ваш аргумент о том, что в скрытии этого каталога есть проблема, здесь не подходит.

          Пожалуйста, расскажите, при каких условиях в этой реализации git может что-то спросить?.. Если не сможете найти, то это означает что ни один аргумент в вашем комментарии не выдержал критики.
          • 0
            Ну ок. Не буду спорить, такой критики ни один аргумент не выдержит. Желаю вам удачи в использовании git reset для деплоя серьезных сайтов.
            • 0
              Если бы вы читали пост, вы бы прочитали что во втором абзаце я пишу о том что этот подход будет удобен для небольших проектов. Для больших проектов, естественно, удобней будет использовать более подходящие решения. Таким образом, ваши пожелания удачи мне не нужны. Спасибо большое.
          • 0
            Для сайтов на Ruby и Python лекарство от неполной копии присутствует штатно. Для серьёзных сайтов на PHP, которые, как минимум, располагаются на собственном сервере, тоже есть очень простое и красивое решение этой проблемы.

            Не поясните, о чём именно Вы тут писали?
  • 0
    Можно разнести репозиторий на сервере и собственно файлы продакшна и использовать в хуке git archive
    • 0
      А зачем git archive?

      А — про разнести вот тут написано так: «Одно из основных правил при работе с Git — никогда не делайте push в репозтирий, у которого есть рабочая копия. Мы следуем этому правилу и создали репозиторий «Hub». Вместо того, чтобы делать push из Hub, который никак не повлияет на рабочую копию, мы будем использовать хук, который заставит Prime выполнить pull из Hub-репозитория.»

      UPD: О. там в комментах приводят пример предлагаемого вами хука для выкладки через архиватор, вместо pull в втором репозитории.
      • +1
        Ничего не понял, простите.
        Сделать push в репозиторий с рабочей копией весьма проблематично, для этого bare репозитории и придуманы.

        Моя идея такова: Есть bare-репозиторий, При пуше в этот репозиторий хук выгружает данные в директорию для вебсервера.
        Git archive мне кажется безопаснее: git pull может обломиться из-за например конфликтов.
  • 0
    Я предпочитаю хранить git-репозитории в отдельной папке вне виртуального хоста, указав дополнительно путь к папке с файлами: git config core.worktree /path/to/site/folder

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