を使用してWebサイトを展開することは可能git push
ですか?私はそれがサーバー側でgitフックを使用して実行することと関係があるという勘を持ってgit reset --hard
いますが、これを達成するにはどうすればよいですか?
を使用してWebサイトを展開することは可能git push
ですか?私はそれがサーバー側でgitフックを使用して実行することと関係があるという勘を持ってgit reset --hard
いますが、これを達成するにはどうすればよいですか?
回答:
私はこのサイトでこのスクリプトを見つけましたが、それは非常にうまく機能しているようです。
ローカルコピーで、.git / configファイルを変更し、Webサーバーをリモートとして追加します。
[remote "production"]
url = username@webserver:/path/to/htdocs/.git
ファイルへの実行アクセスを追加します(これもサーバー上):
chmod +x .git/hooks/post-update
これで、ローカルでWebサーバーにプッシュするだけで、作業コピーが自動的に更新されます。
git push production
以下の更新後のファイルを使用:
ローカルコピーで、.git / configファイルを変更し、Webサーバーをリモートとして追加します。
[remote "production"]
url = username@webserver:/path/to/htdocs/.git
サーバーで、.git / hooks / post-updateを以下のファイルに置き換えます
ファイルへの実行アクセスを追加します(これもサーバー上):
chmod +x .git/hooks/post-update
これで、ローカルでWebサーバーにプッシュするだけで、作業コピーが自動的に更新されます。
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's 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 HEAD@{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 HEAD@{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
この記事のおかげで、多くの誤ったスタートと行き止まりがありましたが、ようやく「git push remote」だけでWebサイトのコードをデプロイできるようになりました。
作者の更新後のスクリプトは1行しかないため、彼のソリューションでは、.htaccess構成でGitリポジトリを非表示にする必要はありません。
これをAmazon EC2インスタンスにデプロイする場合、いくつかの障害があります。
1)sudoを使用して最小限の宛先リポジトリを作成する場合、リポジトリの所有者をec2-userに変更する必要があります。そうしないと、プッシュが失敗します。(「chown ec2-user:ec2-user repo」を試してください。)
2)amazon-private-key .pem の場所を/ etc / ssh / ssh_configのIdentityFileパラメータとして、または〜/ .ssh / configで「[ Host]-HostName-IdentityFile-User " ここで説明するレイアウト...
...ただし、ホストが〜/ .ssh / configで構成されており、HostNameと異なる場合、Gitプッシュは失敗します。(それはおそらくGitのバグです)
サーバーにgitをインストールしたり、.gitフォルダーをそこにコピーしたりしないでください。git cloneからサーバーを更新するには、次のコマンドを使用できます。
git ls-files -z | rsync --files-from - --copy-links -av0 . user@server.com:/var/www/project
プロジェクトから削除されたファイルを削除する必要があるかもしれません。
これにより、チェックインされたすべてのファイルがコピーされます。rsyncは、とにかくサーバーにインストールされているsshを使用します。
サーバーにインストールするソフトウェアが少ないほど、彼の安全性が高くなり、構成の管理と文書化が容易になります。また、サーバー上に完全なgitクローンを保持する必要もありません。すべてを適切に保護することがより複雑になるだけです。
本質的にあなたがする必要があるのは以下のものです:
server = $1
branch = $2
git push $server $branch
ssh <username>@$server "cd /path/to/www; git pull"
私のアプリケーションには、これらの行がという実行可能ファイルとして含まれていますdeploy
。
私は展開のI型をしたいとき./deploy myserver mybranch
。
ssh -A ...
git pull
自動デプロイメントでは、競合がある場合にマージ部分で手動クリーンアップが必要になる可能性があるため、の使用は避けてください。
私が行う方法は、展開サーバーに変更をプッシュするためのGitリポジトリを裸にすることです。次に、展開サーバーにログインし、実際のWebサーバーのdocsディレクトリに移動して、git pullを実行します。私はこれを自動的に実行するためにフックを使用していません。それは価値があるよりも厄介なようです。
git reset
して、最新の変更(プル全体だけでなく、すべてのコミット)の間を移動できます。最新のコミットではない特定のものをロールバックする必要git revert
がある場合は、使用できますが、それは緊急時にのみ使用する必要があります(git revert
以前のコミットの影響を元に戻す新しいコミットを作成します)。
git config --local receive.denyCurrentBranch updateInstead
Git 2.3で追加された、これは良い可能性があります:https : //github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155
サーバーリポジトリに設定し、クリーンな場合は作業ツリーも更新します。
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の範囲外であり、外部コードで処理する必要があります。その意味で、これはGitフックと一緒に、究極のソリューションです。
更新:ロイドムーアソリューションとキーエージェントを使用していますssh -A ...
。メインリポジトリにpushしてから、すべてのマシンから並行してプルすることは、少し高速であり、それらのマシンで必要なセットアップが少なくなります。
このソリューションはここには表示されません。gitがサーバーにインストールされている場合は、sshを介してプッシュするだけです。
ローカルの.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'
(ところで:/path/to/project.gitは実際の作業ディレクトリ/ path / to / projectとは異なります)
このシナリオでは、コードをgithub / bitbucketに保存しており、ライブサーバーにデプロイしたいと考えています。この場合、次の組み合わせが機能します(これは、ここで非常に支持されている回答のリミックスです)。
.git
ディレクトリをWebサーバーにコピーするgit remote add live ssh://user@host: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
フォルダーがドキュメントルート内にある場合は、.htaccess
(source)を追加して、フォルダーを外部から非表示にしてください。
RedirectMatch 404 /\..*$
デプロイの管理にはcapistranoを使用します。ステージングサーバーにデプロイするcapistranoをビルドしてから、すべてのサーバーでrsyncを実行します。
cap deploy
cap deploy:start_rsync (when the staging is ok)
capistranoを使用すると、バグが発生した場合に簡単にロールバックできます
cap deploy:rollback
cap deploy:start_rsync
Giddyupは、言語にとらわれない、水を追加するだけの gitフックで、git pushを介してデプロイを自動化します。また、Webサーバーの再起動、キャッシュのウォームアップなどのためのカスタムの開始/停止フックを持つこともできます。
https://github.com/mpalmer/giddyup
例を確認してください。
gitフックを設定して、「安定した」ブランチと言ってコミットすると、変更がプルされてPHPサイトに適用されると考えられます。大きな欠点は、何か問題が発生した場合に多くの制御ができず、テストに時間がかかることです。しかし、トランクブランチを安定ブランチにマージすると、どのくらいの作業が必要になるかを知ることができます。衝突する可能性のある競合の数。1つのサイトのみを実行するつもりでない限り、サイト固有のファイル(構成ファイルなど)に注意することが重要です。
あるいは、代わりにサイトに変更をプッシュすることを検討しましたか?
gitフックの詳細については、githooksのドキュメントを参照してください。
私はtoroid.orgによる次のソリューションを使用しています。これには、より単純なフックスクリプトがあります。
サーバー上:
$ 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
git push web +master:refs/heads/master
単にではなくgit push web master
?
補足的な答えとして、私は代替案を提供したいと思います。私はgit-ftpを使用していますが、正常に動作します。
https://github.com/git-ftp/git-ftp
使いやすく、タイプのみ:
git ftp push
gitは自動的にプロジェクトファイルをアップロードします。
よろしく
リポジトリから新しい更新を自動的にプルダウンする独自の基本的な展開ツールを作成することになりました-https ://github.com/jesalg/SlimJim-基本的に、それはgithub post-receive-hookをリッスンし、プロキシを使用してトリガーします更新スクリプト。
ポスト受信フックには2つのソリューションを使用します。
ソリューション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 *」文字列に一致するブランチ名をフィルタリングし、プッシュされたブランチが一致する場合は作業ツリーをデプロイします。これにより、開発バージョンとマスターバージョンを別の場所にデプロイできます。
DEPLOY SOLUTION 1は、リポジトリーの一部であり、コミットによって削除されたファイルのみを削除します。Deployment Solution 2よりも高速です。
DEPLOY SOLUTION 2には、repoに追加されたかどうかに関係なく、サーバー側に追加された本番ディレクトリから新しいファイルが削除されるという利点があります。それは常にレポのきれいなだましでしょう。Deployment Solution 1よりも遅いです。