web-dev-qa-db-ja.com

悪い習慣をデプロイするためにGitを使用していますか?

私は、Gitを使用して本番用コードをWebサーバーにデプロイする傾向があります。これは通常、マスターGitリポジトリがsshを介してアクセス可能な場所でホストされ、本番サーバーが.git/および.gitignoreへのアクセスを制限しながら、その複製されたリポジトリを提供することを意味します。更新する必要があるときは、マスターリポジトリからサーバーのリポジトリにプルするだけです。これにはいくつかの利点があります。

  1. 何か問題が発生した場合、以前のリビジョンにロールバックするのは非常に簡単です。チェックアウトするだけです。
  2. ソースコードファイルのいずれかが変更されている場合は、git statusと同じくらい簡単に確認できます。また、サーバーのリポジトリが変更されている場合は、次にプルしようとすると明らかになります。
  3. これは、問題が発生した場合に備えて、ソースコードのコピーがもう1つ存在することを意味します。
  4. 更新とロールバックは簡単で非常に高速です。

ただし、これにはいくつかの問題がある可能性があります。

  • 何らかの理由でWebサーバーが.git/ディレクトリを提供する必要があると判断した場合、そこにあったすべてのソースコードが誰にとっても読み取り可能になります。歴史的に、その間違いをしたいくつかの(大規模な)企業がありました。 .htaccessファイルを使用してアクセスを制限しているので、現時点では危険はないと思います。おそらく、誰も.git/フォルダーを読み取ることができないことを確認する統合テストが適切か?

  • 誤ってフォルダーへの読み取りアクセス権を取得したすべてのユーザーは、以前存在していたソースコードの過去のすべてのリビジョンにもアクセスできます。しかし、それは現在のバージョンへのアクセスを持っているよりもずっと悪いことではありません。結局のところ、これらのリビジョンは定義上は廃止されています。

とはいえ、コードを本番環境にデプロイするためにGitを使用することはかなり安全であり、rsyncftp、または単にコピーするよりもはるかに簡単だと思います。どう思いますか?

109
Septagram

私はデプロイにgitを使用することを検討するところまで行きます非常に良い習慣

リストした2つの問題は、デプロイ自体にgitを使用することとはほとんど関係がありません。代用.git/データベースのパスワードを含む構成ファイルの場合、同じ問題があります。 Webルートへの読み取りアクセス権があれば、そこに含まれているものすべてへの読み取りアクセス権があります。これは、サーバー管理の問題であり、システム管理者と話し合う必要があります。

gitには、セキュリティに関して非常に魅力的な利点がいくつかあります。

  1. 本番環境にデプロイするためのシステムを実施できます。 post-receiveフックを使用すると、masterへのコミットが行われるたびに自動的に本番環境にデプロイされます。もちろん、ワークフローは git flow に似ています。

  2. gitを使用すると、セキュリティの問題が発生した場合に、本番環境にデプロイされたコードを以前のバージョンに簡単にロールバックできます。これは、適切に修正するために時間が必要なミッションクリティカルなセキュリティ欠陥へのアクセスをブロックするのに役立ちます。

  3. 開発者が行うコミットに署名する必要があるシステムを実施できます。これは、意図的なセキュリティ欠陥が見つかった場合に、誰が何を本番環境にデプロイしたかを追跡するのに役立ちます。

77
user10211

Gitリポジトリからのデプロイには何も問題はありません。実際、これはかなり一般的な方法であり、ftpやrsyncでファイルをコピーするよりもエラーが発生しにくいと言っています。

あなたが提供した情報を考慮して、私は次の点に注意します:

  • 最新のマスターを引き込むだけではいけません。プロダクションはリリースタグからデプロイする必要があります。 git flow または同様のものを使用して、コードのデプロイとタグの作成に関するもう少しプロセスを取得します。タグは、ある時点でのコードへの不変の参照であるため、誤ったコミットによって更新される可能性のあるマスターブランチを指すよりも安定しています。

  • .gitディレクトリの提供に関しては、これは大きな問題ではありません。接頭辞が.gitのすべてのものを.htaccessの404にリダイレクトするだけです。

  • Git認証はsshキーベースである必要があるため、サーバーにレポパスワードを保存する必要はありません。

Gitデプロイメントワークフローの万歳!

26
Matt Surabian

git clone を呼び出すときに--separate-git-dir=<git dir>引数を使用できます。これにより、シンボリックリンクが.gitディレクトリに配置され(Gitのシンボリックであり、OSへのシンボリックリンクではないようです)、ドキュメントルートの外部への<git dir>を指定できます。 。

8
Brendon

ここでは世論に反対するつもりです。 Gitはバージョン管理用であり、デプロイ/ CI用ではありません。

ここで人々が主張している方法は、小規模なプロジェクトには適していますが、一般的に言えば、あまり拡張性がありません。

...これは、自分がやっていることを続けてはならないということではありません。キャリアが進むにつれて、あなたが取り組んでいるプロジェクトは、純粋にgitベースのデプロイメントワークフローよりも大きくなる可能性があることを覚えておいてください。

パラダイムの主な変化は、ブランチのデプロイについて考えるのをやめ、ビルド結果のデプロイについて考え始め、環境の依存関係を注入して、インフラストラクチャをブランチ戦略から切り離すことです。

たとえば、「ファイルのデプロイ」とロールバックに関する上記のパラダイムを使用するには、 wereファイルをデプロイする場合、本番サーバーにアプリケーションの複数のバージョンを保持できます。ロールバックする必要がある場合は、Webルートを再シンボリックリンクすることにより、Webサーバーを古いバージョンにポイントできます。 2つのシェルコマンド、マイクロ秒のダウンタイム、gitを使用するよりもエラーの余地が少ない。

別の例-標準の開発ブランチ>ステージングブランチ>マスターワークフローがあり、それぞれにサーバーがあります。開発に取り掛かる準備はできていますが、ステージングに関する他のいくつかの作業はQAに失敗しました。したがって、いくつかの醜い操作を実行する必要があります-ステージから不良コミットを取り除き、ステージを再デプロイし、開発中の不良コミットを取り除いたり修正したりして、開発とステージングが同期しないことを望みます。

代わりに、リリースブランチをマスターから切り離し、そのリリースブランチに入る準備ができているものをマージして結果を構築し、AWSでテストサーバーを起動して結果をそれに展開し、QAと機能テストを実行しました。その一時的なステージングサーバー、そして同じ結果を本番クラスターにプッシュしてデプロイしましたか?次に、スピンアップした一時的なステージングボックスを廃止し、リリースをマスターにマージし、マスターにリリース番号をタグ付けします。

明らかにそれらは極端な例です。通常、クリーンにしたくても、データベースを変更する必要があるため、ターゲット環境でいくつかのビルドプロセスを実行する必要があります。そして、バージョン間でべき等でないデータベースmodがある場合、まあ、dbをロールバックする必要があるため、使用する方法に関係なく、ロールバックはそれほど簡単ではありません(一般的に言えば、べき等データベースをデプロイしてみてください)変更し、廃止されたデータベースビットをアプリケーションフロー外にあることを確認した後、後のリリースで削除します)。

とにかく、私が何を得ているのかと思います、それは「デプロイメントの悪いプラクティスにgitを使用していますか?」一般的に言って、「はい」です。これは、補助輪の使用が自転車に乗るのに悪いのと同じです。お尻をコンクリートの上で繰り返しつぶすよりも改善されますが、最終的にはそれを超えてうまくいけます。

8
siliconrockstar

私が以前に取った別のアプローチは、ポスト受信フックに関するTerry Chiaのコメントに似たものです。

Gitには フックの数 があり、複数の異なるアクションの前/最中/後にあらゆる種類のタスクを実行するために使用できます。

Webフォルダー以外の場所にbareリポジトリを作成します。次に、ベアリポジトリを リモートへのプッシュ として使用できます。受信後フックをトリガーして、指定したディレクトリに新しいコードをチェックアウトできます。

このアプローチにはいくつかの利点があります。展開場所は、コードがソース管理を通過して本番環境に到達する必要がある「一方向」の道として機能します。異なるブランチ/バージョンを異なる場所にデプロイできます(すべて同じベアリポジトリから)。また、標準のgitチェックアウトを使用してロールバックする簡単な方法も提供します。ただし、これの警告/結果として、サーバーでのコード変更はgitに反映されないため(ベアリポジトリには作業ディレクトリがないため)、手動でgit --work-tree=/path/to/code statusを実行して変更を確認する必要があります(ただしとにかく、製品コードを変更するべきではありませんよね?)

5
russdot

私はそれが非常に良い習慣であることをテリー・チアに同意します。それは保証します:

  • 実施されている改訂が正しいものであること、
  • 必要なすべてのファイルを使用して、バージョンの完全性をチェックし、
  • 展開手順を迅速かつ簡単にする

ただし、共有したいという警告があることも付け加えておきます。

通常、gitリポジトリに次のように配置します。

  • コード、
  • docs、
  • ユニットテスト、
  • 展開スクリプト、
  • 統合ツール、
  • .debアーカイブ、
  • sQLパッチ
  • またはそのようなもの、そしておそらく他のものの束

まあ、本番環境ではコードが必要です!

なぜなら、ドキュメント、単体テスト、ツール、または.debアーカイブは大量のディスクを必要とし、本番環境では何もしないからです。

Subversion(バージョン1.7より前)では、src/ディレクトリとすべての利点があります。しかし、Subversion> 1.7とGitでは、それはできません。

代わりの方法は、gitサブモジュールを使用してそのようなアーキテクチャを作成することです:project repo |- doc |- src -> submodule to project-src repo. \ testsしかし、あなたのプロジェクト/テストとproject-srcコードは同期されず、それは本当にうんざりするでしょう。

次に、解決策は「スパースチェックアウト」を使用することです。以下を参照してください。 https://stackoverflow.com/questions/600079/how-do-i-clone-a-subdirectory-only-of-a-git-リポジトリ

したがって、gitを使用できますが、これらの欠点に注意してください。

3
Thibault

Git to Push to prodを作成するために使用するスクリプトは次のとおりです。

https://Gist.github.com/Zamicol/f160d05dd22c9eb25031

Masterブランチにプッシュされたものはすべて本番環境で使用できる状態にあると想定しています。他のプッシュされたブランチはすべて無視されます。このフックスクリプトは、ニーズに合わせて変更できます。

あなたの懸念に関しては、私はgitディレクトリを/ var/gitの下に置き、本番ファイルを(/ var/wwwなどの)別の場所に置き、これらのディレクトリへのアクセスを制限します。

Git repoを本番サーバーとは別のサーバーに置き、上記のスクリプトでscpsshのようなものを使用して、ファイルをgitサーバーから本番サーバーに移動することもできます。これにより、コードをプロダクションから分離したまま、git to Push to prodを使用できます。

1
Zamicol