QA@IT

Webサイトのソース管理&リリース管理について

4832 PV

ソース管理とリリース管理について検討しています。
いくつか悩んでいる点があるためご教示いただけますでしょうか。

◆現在の構成・状況
検証サーバ、ステージサーバ、本番サーバの3台構成。
検証サーバ・ステージサーバはソース管理サーバを兼ねており、ローカルマシンでコード修正後、検証サーバにコミットすることで検証サイトへ反映(リポジトリ=公開ディレクトリ)。
また同様にステージ環境にコミットすることでステージサイトへ反映。
ステージからRsyncで本番サーバへ反映。

◆やりたいこと
・ソース管理サーバを別サーバとして構築する。(=検証・ステージではソース管理は行わなくする)ソース管理はSubversionもしくはGITを検討しており、ソース管理&リリース管理の方法を決めたいと思っています。

できれば現在の運用をかえずに、
(1)ローカル環境からソース管理サーバにコミット⇒検証環境にソース転送(=検証サイトへ反映)
(2)ローカル環境からソース管理サーバにコミット⇒ステージ環境にソース転送(=ステージサイトへ反映)を行いたいのですがローカルマシン用にツールを準備する必要がある?(検証用とステージ用)と考えています。

が、少し難しそうなため現実的な案としては、
「ソース管理サーバへSVNもしくはGITのクライアントツールでコミット(現在の運用と一緒でよい)」した上で、ソース管理サーバにSSHアクセスしてリリースバッチを手動実行(引数に応じて検証もしくはステージ環境に転送するようなリリースバッチを想定)とかかなと考えていますが、保守性や汎用性を考慮したい場合に他にどのような案があり最適なのかをご教示(ご提案)いただけないでしょうか?

できればリリースのたびにソース管理サーバにアクセスしたくないので、
ローカルで完結したいのですがローカル用のツールを作ってその中でコミット&検証もしくはステージにリリースというのをどう実現すればよいかで悩んでいます。(TortoiseSVNを拡張するような感じ?)

またソース管理サーバはさくらのレンタルサーバを予定しているためできることには制限があります。SSHアクセス&バッチ実行とかは問題なしですが、ミドルのインストールとかは制限があります。

  • ngyukiさん
    アドバイスありがとうございます。
    フックスクリプトの存在は初めて知りました。

    今回検証・ステージサーバには作業ディレクトリを持たない予定です(ソースの修正自体は開発者のローカルPC上で行います)
    その場合ソース管理サーバへのコミットをトリガーとしてソース管理サーバ上で検証サーバもしくはステージサーバへのソース転送コマンドを実行するといったことがでできるのでしょうか?
    -
  • SCM でリポジトリからチェックアウトされたディレクトリを「作業ディレクトリ」と呼ぶのが一般的だと思うので「作業ディレクトリ」と書きましたが、
    検証サーバ上の作業ディレクトリは、最初に人手でリポジトリから clone した後はフックスクリプトから自動で pull されるのみで、実際に人が何か作業するわけではありません。
    -
  • フックスクリプトの中で、ソース管理サーバの適当なディレクトリに git clone とかで最新のソースを取得して rsync などで検証・ステージングサーバに転送することも可能です。 -

回答

ソース管理サーバの Subversion または Git のリポジトリでフックスクリプトを使えば実現出来ないでしょうか?

Git のカスタマイズ - Git フック

検証・ステージサーバの公開ディレクトリは Subversion や Git からクローン・チェックアウトした作業ディレクトリそのものにしておいて、
作業ディレクトリで svn updategit pull だけで最新のソースに更新出来るようにしておきます。

ソース管理サーバにフックスクリプトを設置して、SSH などを経由して検証・ステージサーバで上記コマンドを実行させます。

検証orステージサーバで反映するタイミングを変えたいのであれば、それぞれ用のブランチを切っておいて、PUSH先ブランチをどちらにするかで制御出来ます。

Gitならリポジトリの構成(gitolite とか gitlab とか)によりますが概ね次のような感じです。

Gitサーバ ... gitserver
検証サーバ ... testserver
Gitサーバ内ののリポジトリ ...  /var/lib/git/repositories/testing.git
検証サーバ内のデプロイ先 ... /var/www/html/testing

検証サーバで deploy ユーザを作成して秘密鍵/公開鍵を準備

useradd -m deploy

su - deploy
ssh-keygen
scp .ssh/id_rsa.pub username@gitserver:/tmp/deploy.pub

Gitサーバで git ユーザの秘密鍵/公開鍵を準備

su - git
ssh-keygen
scp .ssh/id_rsa.pub username@testserver:/tmp/git.pub

検証サーバで deploy ユーザの authorized_keys に追記

su - deploy
cat /tmp/git.pub >> .ssh/authorized_keys
chmod 600 .ssh/authorized_keys

Gitサーバで git ユーザの authorized_keys に追記

su - git
cat /tmp/deploy.pub >> .ssh/authorized_keys
chmod 600 .ssh/authorized_keys

検証サーバから deploy ユーザで Git サーバに ssh でアクセス(known_hosts 更新のため)

su - deploy
ssh git@gitserver uname -a

ソース管理サーバから git ユーザで検証サーバに ssh でアクセス(known_hosts 更新のため)

su - git
ssh deploy@testserver uname -a

検証サーバでソースを clone しておく(必要ならブランチのチェックアウトも)

mkdir /var/www/html/testing
chown deploy. /var/www/html/testing
su - deploy
cd /var/www/html/testing
git clone git@gitserver:testing .

ソース管理サーバから SSH 経由で pull してみる

su - git
ssh deploy@testserver 'cd /var/www/html/testing/ && git pull'

ソース管理サーバのリポジトリに post-receive を設置

vi /var/lib/git/repositories/testing.git/hooks/post-receive

post-receive の内容・・・

#!/bin/sh
ssh deploy@testserver 'cd /var/www/html/testing/ && git pull'

post-receive のパーミッション設定

chmod +x /var/lib/git/repositories/testing.git/hooks/post-receive

ローカル環境からリポジトリに push すれば検証環境にデプロイされます

編集 履歴 (1)
  • ngyukiさん アドバイスありがとうございます。
    お聞きしたいのですがこの場合、クライアント(?)となる検証サーバ側にもgitをインストールする必要があるということでよいでしょうか?また検証とステージで分ける場合は、リポジトリもそれぞれ用意しpost-receiveもそれぞれのリポジトリに配置しPULL先を変えておくということでよいでしょうか?
    -
  • ご教示いただいた方法で試していますが「ソース管理サーバから SSH 経由で pullしてみる」の所がうまくいきません。以下のエラーが出てしまいました。
    Permission denied, please try again.
    Permission denied (publickey,password).
    fatal: The remote end hung up unexpectedly
    -
  • 度々すみません。自分で気づいたのですがSSHのパスフレーズを設定しない前提でしょうか?パスフレーズを設定しなければ出来そうなのですがセキュリティ上できればパスフレーズを設定したいのです(ソース管理、検証ともに)それは可能でしょうか?post-receiveを使う限りパスフレーズ入力は自動化しなければならないと思うのでexpectなどを使ってパスフレーズを自動認証にする必要があるのでしょうか? -
  • ↑の方法だと検証・ステージングサーバにも git が必要です。 -
  • ↑の方法は、SSHをパスワード認証ではなく、公開鍵認証で行う前提です。
    expect とかを使ってパスワード認証も不可能では無いと思いますが(expect 使った事無いですが・・・)、
    公開鍵認証と比べてセキュリティ的に勝りはしません(パスワードが平文で書かれた何かをソース管理サーバ上に置かなければならなくなるので)。
    -
  • パスフレーズ有りの公開鍵認証という意味で書きました。パスフレーズ有りの公開鍵認証を作成しssh-agentで自動読み込みできるようにしました。最後のpost-receive の設定までしたのですが、pushしてもデプロイされません。push後にsh post-receiveで直接実行すればデプロイされるのでpost-receive内の記述は正しいと思うのですが・・・。。 -
  • git push をしたときに何かメッセージ出ていないでしょうか?
    post-receive が標準出力や標準エラーに何か書き込めば git クライアント側でその内容が表示されます。
    -
  • もしかして post-receive にパーミッションが設定されていない? ./post-receive で実行できる必要があります。 -
  • 以下のエラーが出ていました。
    remote: Permission denied, please try again.
    remote: Permission denied, please try again.
    remote: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
    -
  • パーミッションは755にしており、 ./post-receive で実行できました。 -
  • やはりソース管理サーバから検証サーバへ自動でSSH鍵認証アクセスさせる部分がうまくいっていないようです。ssh-agentでログイン時にパスフレーズを入れて後はログアウトするまで鍵無しでアクセスできるようにしているのですがpost-receiveを使う場合は実行ユーザが違うから(?)かうまくいかないようです。 -
  • 普通にソース管理サーバに ssh でログインして、ssh-agent を立ち上げているということですか? -
  • ssh-agent は詳しくないですが、git push でソース管理サーバに ssh でアクセスするユーザと、ssh-agent を実行するユーザが同じである必要があり、
    かつ、post-receive で環境変数 SSH_AUTH_SOCK を設定する必要があるので、多分その利用方法は無理そうです。
    -
  • ssh-agentで設定してもログインした際にパスフレーズをいれなければいけないので確かにダメですね、、。やはりパスフレーズ無しの鍵認証にするしかないですかね。外部アプリからSSH自動認証させる場合はパスフレーズ無しにするのが一般的なのでしょうか? -
  • 一般的かどうか判りませんが、例えば自動バックアップとかで SSH 接続がどうしても必要な場合は、それ専用の秘密鍵を作成して、接続先サーバの authorized_keys の command で特定のコマンドだけ実行出来るようにしたりします。 -
  • 問題の趣旨と外れてきた感がしますので、git のフックスクリプトで自動デブロイする方法 のようなタイトルで別の質問にすると良いかもしれません。 -
  • ありがとうございます。とりあえず今回はパスフレーズ無しにして authorized_keys の commandで「cd /var/www/html/testing/;git pull」でSSHアクセスされたらPULLする方式にすることにしました。
    数日間、長々とお付き合いいただき本当にありがとうございました。また何かありましたらよろしくお願いいたします。
    -
  • 解決であれば解決済にしておいた方がいいです。
    http://qa.atmarkit.co.jp/faq
    -

Jenkins等のCIツールを使ってみたらどうでしょうか?
ポーリングになるので、コミットからデプロイ(?)まで、多少のラグはありますが、
すぐに反映させたかったら、画面から指示することもできますし。

編集 履歴 (0)
  • h-satomiさんアドバイスありがとうございます。CIツールは使ったことなく導入や初期設定に工数がかかりそうな気がしています。デプロイまでの多少のラグは問題ありません。出来れば検証サーバ側に手を入れたくない(管理者が異なるため)のですが、鍵発行やgitインストールが必要なのはngyukiさんの案と変わらないですよね?どちらがよいか悩ましいです。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。