Разверните проект, используя Git push

Возможно ли развертывание веб-сайта с помощью git push? У меня есть подозрение, что это связано с использованием git hooks для выполнения git reset --hard на стороне сервера, но как бы я пошел об этом?

Ответ 1

Я нашел этот script на этот сайт, и, похоже, он работают неплохо.

  • Скопируйте ваш каталог .git на свой веб-сервер.
  • В вашей локальной копии измените файл .git/config и добавьте веб-сервер в качестве удаленного:

    [remote "production"]
        url = [email protected]:/path/to/htdocs/.git
    
  • На сервере замените .git/hooks/post-update на этот файл (в ответе ниже)

  • Добавить выполнение доступа к файлу (опять же, на сервере):

    chmod +x .git/hooks/post-update
    
  • Теперь просто локально нажмите на свой веб-сервер и он должен автоматически обновить рабочую копию:

    git push production
    

Ответ 2

Используя пост-обновленный файл ниже:

  • Скопируйте ваш каталог .git на свой веб-сервер.
  • В вашей локальной копии измените файл .git/config и добавьте веб-сервер в качестве удаленного:

    [remote "production"]
        url = [email protected]:/path/to/htdocs/.git
    
  • На сервере замените .git/hooks/post-update файлом ниже

  • Добавить выполнение доступа к файлу (опять же, на сервере):

    chmod +x .git/hooks/post-update
    
  • Теперь просто локально нажмите на свой веб-сервер и он должен автоматически обновить рабочую копию:

    git push production
    
#!/bin/sh
#
# This hook does two things:
#
#  1. update the "info" files that allow the list of references to be
#     queries over dumb transports such as http
#
#  2. if this repository looks like it is a non-bare repository, and
#     the checked-out branch is pushed to, then update the working copy.
#     This makes "push" function somewhat similarly to darcs and bzr.
#
# To enable this hook, make this file executable by "chmod +x post-update". 
git-update-server-info 
is_bare=$(git-config --get --bool core.bare) 
if [ -z "$is_bare" ]
then
      # for compatibility sake, guess
      git_dir_full=$(cd $GIT_DIR; pwd)
      case $git_dir_full in */.git) is_bare=false;; *) is_bare=true;; esac
fi 
update_wc() {
      ref=$1
      echo "Push to checked out branch $ref" >&2
      if [ ! -f $GIT_DIR/logs/HEAD ]
      then
             echo "E:push to non-bare repository requires a HEAD reflog" >&2
             exit 1
      fi
      if (cd $GIT_WORK_TREE; git-diff-files -q --exit-code >/dev/null)
      then
             wc_dirty=0
      else
             echo "W:unstaged changes found in working copy" >&2
             wc_dirty=1
             desc="working copy"
      fi
      if git diff-index --cached [email protected]{1} >/dev/null
      then
             index_dirty=0
      else
             echo "W:uncommitted, staged changes found" >&2
             index_dirty=1
             if [ -n "$desc" ]
             then
                   desc="$desc and index"
             else
                   desc="index"
             fi
      fi
      if [ "$wc_dirty" -ne 0 -o "$index_dirty" -ne 0 ]
      then
             new=$(git rev-parse HEAD)
             echo "W:stashing dirty $desc - see git-stash(1)" >&2
             ( trap 'echo trapped $$; git symbolic-ref HEAD "'"$ref"'"' 2 3 13 15 ERR EXIT
             git-update-ref --no-deref HEAD [email protected]{1}
             cd $GIT_WORK_TREE
             git stash save "dirty $desc before update to $new";
             git-symbolic-ref HEAD "$ref"
             )
      fi 
      # eye candy - show the WC updates :)
      echo "Updating working copy" >&2
      (cd $GIT_WORK_TREE
      git-diff-index -R --name-status HEAD >&2
      git-reset --hard HEAD)
} 
if [ "$is_bare" = "false" ]
then
      active_branch=`git-symbolic-ref HEAD`
      export GIT_DIR=$(cd $GIT_DIR; pwd)
      GIT_WORK_TREE=${GIT_WORK_TREE-..}
      for ref
      do
             if [ "$ref" = "$active_branch" ]
             then
                   update_wc $ref
             fi
      done
fi

Ответ 3

После многих ложных запусков и тупиков я наконец смогу развернуть код сайта с помощью "git push remote" благодаря этой статье.

Автор пост-обновления script является только одной строкой длиной, и его решение не требует конфигурации .htaccess, чтобы скрыть репозиторий Git, как это делают некоторые другие.

Несколько камней преткновения, если вы развертываете это на экземпляре Amazon EC2;

1) Если вы используете sudo для создания голого целевого репозитория, вам нужно изменить владельца репо на пользователя ec2 или прорыв не будет выполнен. (Попробуйте "chown ec2-user: ec2-user repo." )

2) Нажатие не будет выполнено, если вы не предварительно настроили местоположение своего файла amazon-private-key.pem, либо в /etc/ssh/ssh _config, либо в качестве параметра IdentityFile, либо в ~/.ssh/config, используя "[Host] - HostName - IdentityFile - Пользовательский макет, описанный здесь...

... ОДНАКО, если хост настроен в ~/.ssh/config и отличается от HostName, то нажатие Git завершится с ошибкой. (Вероятно, ошибка Git)

Ответ 4

dont установить git на сервер или скопировать туда папку .git. для обновления сервера из клона git вы можете использовать следующую команду:

git ls-files -z | rsync --files-from - --copy-links -av0 . [email protected]:/var/www/project

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

копирует все проверенные файлы. rsync использует ssh, который установлен на сервере в любом случае.

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

Ответ 5

В сущности, все, что вам нужно сделать, это следующее:

server = $1
branch = $2
git push $server $branch
ssh <username>@$server "cd /path/to/www; git pull"

Я использую эти строки в своем приложении как исполняемый файл deploy.

поэтому, когда я хочу выполнить развертывание, введите ./deploy myserver mybranch.

Ответ 6

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

Ответ 7

receive.denyCurrentBranch updateInstead, добавленный в Git 2.3, является возможностью.

Установите его в репозиторий сервера, а также обновите рабочее дерево, если оно чистое.

Дальше были улучшения в 2.4 с помощью push-to-checkout привязки и обработки неродившихся ветвей.

Использование образца:

git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead

cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master

cd ../server
ls

Вывод:

a
b

У этого есть следующие недостатки, упомянутые в объявлении GitHub:

  • Ваш сервер будет содержать каталог .git, содержащий всю историю вашего проекта. Вы, вероятно, хотите удостовериться, что его нельзя обслуживать пользователям.
  • Во время развертывания пользователи смогут мгновенно столкнуться с сайтом в несовместимом состоянии, с некоторыми файлами на старой версии и другими в новой версии или даже с полузаписью файлов. Если это проблема для вашего проекта, push-to-deploy, вероятно, не для вас.
  • Если вашему проекту нужен шаг "build", вам нужно будет установить это явно, возможно, через githooks.

Но все эти точки выходят за рамки Git и должны быть учтены внешним кодом. Таким образом, в этом смысле это, вместе с Git крючками, является окончательным решением.

Ответ 8

Обновление: теперь я использую решение Lloyd Moore с ключевым агентом ssh -A .... Нажатие на основное репо и последующее вытягивание из него параллельно со всеми вашими машинами происходит немного быстрее и требует меньше настройки на этих машинах.


Не вижу этого решения здесь. просто нажмите через ssh, если на сервере установлено git.

Вам понадобится следующая запись в вашем локальном .git/config

[remote "amazon"]
    url = amazon:/path/to/project.git
    fetch = +refs/heads/*:refs/remotes/amazon/*

Но эй, что это с amazon:? В вашем локальном ~/.ssh/config вам нужно будет добавить следующую запись:

Host amazon
    Hostname <YOUR_IP>
    User <USER>
    IdentityFile ~/.ssh/amazon-private-key

теперь вы можете позвонить

git push amazon master
ssh <USER>@<YOUR_IP> 'cd /path/to/project && git pull'

(BTW:/path/to/project.git отличается от фактического рабочего каталога/пути/в/проекте)

Ответ 9

Мы используем capistrano для управления развертыванием. Мы создаем capistrano для развертывания на промежуточном сервере, а затем запускаем rsync со всем нашим сервером.

cap deploy
cap deploy:start_rsync (when the staging is ok)

С capistrano мы можем сделать простой откат в случае ошибки

cap deploy:rollback
cap deploy:start_rsync

Ответ 10

Для сценария развертывания

В нашем сценарии мы сохраняем код на github/bitbucket и хотим развернуть на живых серверах. В этом случае для нас работает следующая комбинация (т.е. Ремикс очень высоких ответов здесь):

  • Скопируйте папку .git на ваш веб-сервер.
  • В вашей локальной копии git remote add live ssh://[email protected]:port/folder
  • На пульте дистанционного управления: git config receive.denyCurrentBranch ignore
  • На пульте дистанционного управления: nano .git/hooks/post-receive и добавьте это содержимое:

    #!/bin/sh GIT_WORK_TREE=/var/www/vhosts/example.org git checkout -f

  • На пульте дистанционного управления: chmod +x .git/hooks/post-receive

  • Теперь вы можете нажать туда git push live

Примечания

  • Это решение работает со старыми версиями git (проверено с 1.7 и 1.9).
  • Вам нужно сначала нажать github/bitbucket, чтобы у вас было постоянное репо на live
  • Если ваша папка .git находится внутри корня документа, убедитесь, что вы скрываете ее извне, добавляя к .htaccess (source):

    RedirectMatch 404 /\..*$

Ответ 11

Giddyup - это языковые агностики с простом добавлением воды git для автоматизации развертывания с помощью git push. Он также позволяет создавать пользовательские кнопки запуска/остановки для перезапуска веб-сервера, разогрева кеша и т.д.

https://github.com/mpalmer/giddyup

Отъезд examples.

Ответ 12

Похоже, у вас должно быть две копии на вашем сервере. Голый экземпляр, который вы можете нажать/вытащить, который вы нажмете на свои изменения, когда закончите, а затем вы клонируете это в свой веб-каталог и настройте cronjob для обновления git pull из вашего веб-каталога каждый день или около того.

Ответ 13

Вы могли бы создать привязку git, которая, когда сказано, что фиксация сделана, чтобы сказать "стабильную" ветвь, она вытащит изменения и применит их к сайту PHP. Большой недостаток заключается в том, что у вас не будет большого контроля, если что-то пойдет не так, и это добавит времени на тестирование, но вы можете понять, сколько работы будет задействовано, когда вы слились, сообщите, чтобы ваша ветвь ствола в стабильную ветку знала сколько конфликтов вы можете столкнуться. Будет важно следить за любыми файлами, которые являются специфичными для сайта (например, файлы конфигурации), если только вы не намерены запускать только один сайт.

В качестве альтернативы вы вместо этого перешли на изменение на сайт?

Информацию о перехватах git см. в документации githooks.

Ответ 14

Мое решение христиане.

git archive --prefix=deploy/  master | tar -x -C $TMPDIR | rsync $TMPDIR/deploy/ --copy-links -av [email protected]:/home/user/my_app && rm -rf $TMPDIR/deploy
  • Архивирует главную ветвь в tar
  • Извлекает архив tar в каталог развертывания в папке системной временной папки.
  • rsync меняет сервер
  • удалить папку dir из папки temp.

Ответ 15

Я использую следующее решение toroid.org, у которого более простой hook script.

на сервере:

$ mkdir website.git && cd website.git
$ git init --bare
Initialized empty Git repository in /home/ams/website.git/

и установите крючок на сервере:

$ mkdir /var/www/www.example.org
$ cat > hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=/var/www/www.example.org git checkout -f
GIT_WORK_TREE=/var/www/www git clean -f -d # clean directory from removed files

$ chmod +x hooks/post-receive

на вашем клиенте:

$ mkdir website && cd website
$ git init
Initialized empty Git repository in /home/ams/website/.git/
$ echo 'Hello, world!' > index.html
$ git add index.html
$ git commit -q -m "The humble beginnings of my web site."

$ git remote add web ssh://server.example.org/home/ams/website.git
$ git push web +master:refs/heads/master

затем опубликуйте, просто введите

$ git push web

На веб-сайте есть полное описание: http://toroid.org/ams/git-website-howto

Ответ 16

В качестве дополнительного ответа я хотел бы предложить альтернативу. Я использую git -ftp, и он отлично работает.

https://github.com/git-ftp/git-ftp

Прост в использовании, только тип:

git ftp push

и git будут автоматически загружать файлы проекта.

Привет

Ответ 17

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

Убедитесь, что у вас есть группа unix, к которой принадлежат все разработчики, и предоставить право собственности на репозиторий .git для этой группы.

  • В .git/config набора репозитория сервера sharedrepository = true. (Это сообщает git разрешить нескольким пользователям, которые необходимы для коммитов и развертывания.

  • установить umask каждого пользователя в их файлах bashrc одинаково - 002 - хороший старт

Ответ 18

В итоге я создал свой собственный рудиментарный инструмент развертывания, который автоматически вытащил новые обновления из репо - https://github.com/jesalg/SlimJim - В основном он слушает github post-receive-hook и использует прокси-сервер для запуска обновления script.

Ответ 19

Я использую два решения для крюка после приема:

РАЗРЕШЕНИЕ РЕШЕНИЯ 1

#!/bin/bash 
#  /git-repo/hooks/post-receive - file content on server (chmod as 755 to be executed)
# DEPLOY SOLUTION 1 

    export GIT_DIR=/git/repo-bare.git
    export GIT_BRANCH1=master
    export GIT_TARGET1=/var/www/html
    export GIT_BRANCH2=dev
    export GIT_TARGET2=/var/www/dev
    echo "GIT DIR:  $GIT_DIR/"
    echo "GIT TARGET1:  $GIT_TARGET1/"
    echo "GIT BRANCH1:  $GIT_BRANCH1/"
    echo "GIT TARGET2:  $GIT_TARGET2/"
    echo "GIT BRANCH2:  $GIT_BRANCH2/"
    echo ""

    cd $GIT_DIR/

while read oldrev newrev refname
do
    branch=$(git rev-parse --abbrev-ref $refname)
    BRANCH_REGEX='^${GIT_BRANCH1}.*$'
    if [[ $branch =~ $BRANCH_REGEX ]] ; then
        export GIT_WORK_TREE=$GIT_TARGET1/.
        echo "Checking out branch: $branch";
        echo "Checking out to workdir: $GIT_WORK_TREE"; 

        git checkout -f $branch
    fi

    BRANCH_REGEX='^${GIT_BRANCH2}.*$'
    if [[ $branch =~ $BRANCH_REGEX ]] ; then
        export GIT_WORK_TREE=$GIT_TARGET2/.
        echo "Checking out branch: $branch";
        echo "Checking out to workdir: $GIT_WORK_TREE"; 

        git checkout -f $branch
    fi
done

РАЗРЕШЕНИЕ РЕШЕНИЯ 2

#!/bin/bash 
#  /git-repo/hooks/post-receive - file content on server (chmod as 755 to be executed)
# DEPLOY SOLUTION 2

    export GIT_DIR=/git/repo-bare.git
    export GIT_BRANCH1=master
    export GIT_TARGET1=/var/www/html
    export GIT_BRANCH2=dev
    export GIT_TARGET2=/var/www/dev
    export GIT_TEMP_DIR1=/tmp/deploy1
    export GIT_TEMP_DIR2=/tmp/deploy2
    echo "GIT DIR:  $GIT_DIR/"
    echo "GIT TARGET1:  $GIT_TARGET1/"
    echo "GIT BRANCH1:  $GIT_BRANCH1/"
    echo "GIT TARGET2:  $GIT_TARGET2/"
    echo "GIT BRANCH2:  $GIT_BRANCH2/"
    echo "GIT TEMP DIR1:  $GIT_TEMP_DIR1/"
    echo "GIT TEMP DIR2:  $GIT_TEMP_DIR2/"
    echo ""

    cd $GIT_DIR/

while read oldrev newrev refname
do
    branch=$(git rev-parse --abbrev-ref $refname)
    BRANCH_REGEX='^${GIT_BRANCH1}.*$'
    if [[ $branch =~ $BRANCH_REGEX ]] ; then
        export GIT_WORK_TREE=$GIT_TARGET1/.
        echo "Checking out branch: $branch";
        echo "Checking out to workdir: $GIT_WORK_TREE"; 

        # DEPLOY SOLUTION 2: 
        cd $GIT_DIR/; mkdir -p $GIT_TEMP_DIR1; 
        export GIT_WORK_TREE=$GIT_TEMP_DIR1/.
        git checkout -f $branch
        export GIT_WORK_TREE=$GIT_TARGET1/.
        rsync $GIT_TEMP_DIR1/. -v -q --delete --delete-after -av $GIT_TARGET1/.
        rm -rf $GIT_TEMP_DIR1
    fi

    BRANCH_REGEX='^${GIT_BRANCH2}.*$'
    if [[ $branch =~ $BRANCH_REGEX ]] ; then
        export GIT_WORK_TREE=$GIT_TARGET2/.
        echo "Checking out branch: $branch";
        echo "Checking out to workdir: $GIT_WORK_TREE"; 

        # DEPLOY SOLUTION 2: 
        cd $GIT_DIR/; mkdir -p $GIT_TEMP_DIR2; 
        export GIT_WORK_TREE=$GIT_TEMP_DIR2/.
        git checkout -f $branch
        export GIT_WORK_TREE=$GIT_TARGET2/.
        rsync $GIT_TEMP_DIR2/. -v -q --delete --delete-after -av $GIT_TARGET2/.
        rm -rf $GIT_TEMP_DIR2
    fi
done

Оба решения основаны на более ранних решениях, доступных в этом потоке.

Обратите внимание: BRANCH_REGEX = '^ ${GIT_BRANCH1}. $' фильтры для названий ветвей, соответствующих строкам "master" или "dev *", и развертывает дерево работы, если соответствует толкаемому ответвлению. Это позволяет развернуть версию dev и основную версию в разных местах.

DEPLOY SOLUTION 1 удаляет только файлы, которые являются частью репо, и удаляется фиксацией. Это быстрее, чем Deployment Solution 2.

DEPLOY SOLUTION 2 имеет то преимущество, что он удалит любые новые файлы из производственного каталога, который был добавлен на стороне сервера, независимо от того, был ли он добавлен в репо или нет. Это будет всегда чистый обман репо. Это медленнее, чем решение для развертывания 1.