スポンサーリンク

Linux上のApacheで,複数のWebサイトを同時テストできる環境を作る (仮想ホストでサイト住み分け + SVNフックスクリプトで自動デプロイ+ユーザ認証でチーム作業)

複数のWebサイトのメンテナンス作業を,Windowsマシン上で実施しているとする。

各Webサイトのソースコードは,別個のSVNプロジェクトに属する。


これらの全Webサイトを,1台のLinuxマシン内の1台のWebサーバで動作確認したい。

しかもSVNコミットした瞬間に,すぐ動作確認できるようにしたい。

さらに,複数人から成るチームで作業できるように,リポジトリ操作にはユーザ認証をかけたい。


以下は,そのような環境の構築方法。

全体構成図

 ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 ┃Linux(仮想マシン)                     ┃
 ┃           コミット時に ┌─────────┐ ┃
 ┃ ┌───────┐  自動実行  |   Apache   | ┃
 ┃ │ フックスクリプト  │←───────|(Webサーバ かつ | ┃
 ┃ └───────┘        |  リポジトリサーバ) | ┃
 ┃    ↓ SVN更新   複数の   │http://guest/svn/ | ┃
 ┃ ┌───────┐ 仮想ホスト  │         │ ┃
 ┃ | デプロイ  | として参照  │http://guest:81  │ ┃
 ┃ │  資材   │←───────│http://guest:82  │ ┃
 ┃ └───────┘        └─────────┘ ┃
 ┃                     ↑    ↑    ┃
 ┗━━━━━━━━━━━━━━━━━━━━ │ ━━━│━━━━┛
                       │    │複数の
                 コミット・ │    │Webサイトを
                チェックアウト│    │テスト
 ┏━━━━━━━━━━━━━━━━━━━━ │ ━━━│━━━━┓
 ┃                     ↓    │    ┃
 ┃ ┌───────┐ ┌─────────┐ ┌────┐ ┃
 ┃ │       │ │  Tortoise SVN  │ │    │ ┃
 ┃ │  Apache  │ └─────────┘ │ Web  │ ┃
 ┃ │       │    ↓ ワーキングコピー   │ブラウザ│ ┃
 ┃ │http://host:81│ ┌─────────┐ │    │ ┃
 ┃ │http://host:82│→│ 作業用     │ │    │ ┃
 ┃ │       │ │  ソースコード │ │    │ ┃
 ┃ │       │ └─────────┘ │    │ ┃
 ┃ │       │             │    │ ┃
 ┃ │       │←────────────│    │ ┃
 ┃ └───────┘  複数のWebサイトをテスト  └────┘ ┃
 ┃Windowsマシン                        ┃
 ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛


OSは,

  • Windows側:Vista
  • Linux側:CentOS 5.6

を想定。

(1)Linux上にApacheを導入

Linux上へのApacheの導入手順は,下記ページを参照。

CentOS 5.6上で Apache+Passenger+Ruby on Rails 1.2 を動作させる手順 (仮想マシン上に,レガシーRailsの実運用環境を構築)
http://language-and-engineering.hatenablog.jp/entry/20110814/p1

  • (6)Apacheのインストール
  • (7)Apacheの動作確認

(2)Linux上にSubversionを導入

下記のコマンドを実行

yum install subversion


リポジトリ格納用のフォルダを作成

mkdir -p /var/svn/repos

(3)Linun上のSubversionを,WebDAV経由で利用可能にする

下記のコマンドを実行

yum install mod_dav_svn


設定ファイル
/etc/httpd/conf.d/subversion.conf
が生成される。


このファイルの冒頭には,下記のように記載されている。

LoadModule dav_svn_module     modules/mod_dav_svn.so
LoadModule authz_svn_module   modules/mod_authz_svn.so


このファイルに,下記の設定を追加。

<Location /svn>
    DAV svn
    SVNPath /var/svn/repos
</Location>


Apacheを再起動。

/etc/init.d/httpd restart


参考:

CentOS4/CentOS5 - subversionの導入
http://park1.wakwak.com/~ima/centos4_...

  • WebDAV経由でリポジトリへのアクセスを行える様にします


Linux上でSVN+Apache
http://www.gside.org/Gentoo/subversio...
http://www.gside.org/Gentoo/subversio...

  • Gentoo Linuxなので,パッケージ管理にemergeコマンドを使っている

これで,ネットワーク越しにSVNリポジトリにアクセス可能になった。


(4)Windows上でTortoiseSVNを導入

下記ページを参照。

Windows Vista上に Apache+Subversion+Tortoise SVN をインストールして,ネットワーク越しにリポジトリを利用できるようにする手順
http://language-and-engineering.hatenablog.jp/entry/20110723/p1

  • (1)Tortoise SVNのインストール

(5)Linux上に複数プロジェクトを作成

「site1」と「site2」の2プロジェクトを管理することにする。


下記のコマンドを実行:

cd /var/svn/repos

mkdir site1
svnadmin create site1

mkdir site2
svnadmin create site2

chown -R apache:apache /var/svn/repos

Windows側からのSVN操作要求は,Apache経由で実行されるので,所有者をapacheに変更しておく必要がある。



この時点で,ブラウザ上からリポジトリを確認できるはず。

下記のURLにアクセス。

「site1 - Revision 0: /」
のように表示されれば成功。

site2のほうについても,同様の結果になることを確認。


※もしブラウザ上で「Could not open the requested SVN filesystem」
のエラーが出た場合,たいていconfファイル中でのパス指定ミスである。
下記のコマンドでエラー内容を確認すること。

less /var/log/httpd/error_log


これで,具体的な複数のSVNプロジェクトを,リモートから利用可能になった。


(6)Linux上のSubversionに,フックスクリプトで自動デプロイ設定

まずは,デプロイ先のフォルダを作る。

mkdir /var/projects
mkdir /var/projects/site1
mkdir /var/projects/site2

次に,デプロイ先に対してチェックアウトを実行する。

svn checkout http://localhost/svn/site1/ /var/projects/site1
chown -R apache:apache /var/projects/site1/

svn checkout http://localhost/svn/site2/ /var/projects/site2
chown -R apache:apache /var/projects/site2/

※もし「svn: Could not open the requested SVN filesystem」というエラーが出たら,URLの打ち間違い。

※もしchown -R の対象パスの末尾に「*」(アスタリスク)をつけてしまうと,
「.svn」などの隠しフォルダ・隠しファイルの所有者が変更されない
chownコマンドが効かない!と慌てがちな,意外なはまり所なので注意。

How to Chown a directory recursively including hidden files or directories
http://serverfault.com/questions/1564...
What won't work, and what tripped me up early in my command line usage, is using * in a directory with hidden files/directories. So doing
$ chown -R /home/user/*
will not do the hidden files and directories.

これで,デプロイ先の準備が整った。

次に,SVNコミット時の自動デプロイの設定を行なう。


/var/svn/repos/site1/hooks/post-commit.tmpl
というファイルを,「post-commit」にリネーム。

中身の末尾を,下記のように書き換え。

mailer.py commit "$REPOS" "$REV" /path/to/mailer.conf

↓

#mailer.py commit "$REPOS" "$REV" /path/to/mailer.conf
/usr/bin/svn up /var/projects/site1/*

このファイルに実行権を付与。

chmod 755 /var/svn/repos/site1/hooks/post-commit


同様の作業を,/var/svn/repos/site2/hooks/post-commit に対しても行なう。


参考:

Subversionのpost-commitフックでsvn updateできないときは
http://www.akiyan.com/blog/archives/2...

  • 「Subversion Best Practices」ではWebサイトのsvn updateはpost-commitフックで自動的にやろうといわれています。
  • 「svn update /DocumentRoot/*」と言う風に、本来フォルダ指定だけでいけるところをわざわざワイルドカードで中身全指定したら更新されるようになった


【Subversion】mod_dav_svnでCommitした時に自動的にupdateを行う
http://blog.livedoor.jp/loopus/archiv...

  • rootでcheckoutしてしまうとpost-commitからupdateできないため、所有者をapacheに


post-commit リポジトリのフック
http://www.caldron.jp/~nabetaro/svn/s...

  • トランザクションがコミットされ、新しいリビジョンが作られた後に実行されます


SVNで,コミット時にログの入力を強制する (Windows版subversionのサーバ側フックスクリプトの作成方法)
http://language-and-engineering.hatenablog.jp/entry/20100819/p1

  • pre-commitフックのサンプル


これで,フックスクリプトによる自動デプロイ設定が完了した。


(7)Windowsから,複数プロジェクトにWeb資材をSVNコミット

Windows上にワーキングコピーを作る。


適当なフォルダ上に「site1」というフォルダを作り,
右クリック→SVNチェックアウト
で,「リポジトリのURL」に

と入力。

「OK」を押下。

チェックアウトが完了する。


「site2」についても,別フォルダで同様の手順を実行する。



これで,作業場所が確保できた。


次に,テスト用のファイルをコミットしてみる。

site1フォルダ直下に「index.html」として,「This is site1」とだけ書いたテキストファイルを作成し,コミット。

同様に,site2フォルダにも「This is site2」という内容のindex.htmlをコミット。



この時点で,post-commitフックが働き,
/var/projects/site1/index.html や
/var/projects/site2/index.html が生成されているはずである。

つまり,コミット内容が,毎回自動的にデプロイ(配置)されている。



※もし,コミット時に下記のようなエラーが出たら,.svnフォルダのパーミッションの設定漏れである。
上述した通り,アスタリスクの有無次第で隠しフォルダの権限変更有無が影響を受けるので,注意を。

エラー: post-commit hook failed (exit code 1) with output:
エラー: svn: Can't open file '/var/projects/site1/.svn/lock': Permission denied


これで,自動デプロイの動作検証が完了した。

あとは,デプロイスポット上に配置されたファイルを,Apacheに認識させるだけ。


(8)Linux上のApacheで,SVNの複数プロジェクトを仮想ホストする

デプロイ先のフォルダ(複数)をApacheに認識させ,

複数のWebサイトを同時に動作確認できるようにする。


Apacheの設定ファイル

  • /etc/httpd/conf/httpd.conf

を開き,末尾に下記の設定を付与。

Listen 81
<VirtualHost *:81>
    DocumentRoot /var/projects/site1
    ErrorLog logs/error_log
    CustomLog logs/access_log common
</VirtualHost>


Listen 82
<VirtualHost *:82>
    DocumentRoot /var/projects/site2
    ErrorLog logs/error_log
    CustomLog logs/access_log common
</VirtualHost>

管理対象のWebサイトごとに,異なるポート番号を割り当てて,

複数の仮想ホストを作成している。

参考:

バーチャルホストの例:違うポートで違うサイトを運営する
http://httpd.apache.org/docs/2.2/ja/v...

この状態で,Apacheを再起動。

/etc/init.d/httpd restart


これで,複数のWebサイトを同時にApacheで運営する準備が整った。


(9)Windowsから,複数プロジェクトのWebサイトを動作確認

site1から。

「This is site1」と表示されればOK。


site2:

「This is site2」と表示されればOK。


※もし表示されない場合は,Linux側のファイアウォールをOFFにする。

/etc/init.d/iptables stop

Windows側でSVNコミットすれば,すぐにブラウザ上の表示も変更される。

これで,複数のWebサイトの動作テスト環境ができた。

コミットと同時にデプロイなので,作業のフィードバックを素早く得られる。


(10)チーム作業のために,ユーザ認証を設定

このままではだれでも自由にコミットできてしまうので,チーム作業が難しい。

ユーザ名とパスワードによる認証処理を設ける事にする。


設定ファイル
/etc/httpd/conf.d/subversion.conf
を下記のように編集。

<Location /svn>
    DAV svn
    SVNParentPath /var/svn/repos
</Location>

↓


<Location /svn>
    DAV svn
    SVNParentPath /var/svn/repos
    
    AuthType Basic
    AuthName "Subversion repository"
    AuthUserFile "/var/svn/repos/svnpasswd"
    Require valid-user
</Location>


下記のコマンドを実行して,user1/pass1という認証情報を追加。

cd /var/svn/repos/

htpasswd -c svnpasswd user1
>New password:*****
>Re-type new password:*****
>Adding password for user user1

※2人目以降のユーザを追加する際には,-c オプションは不要なので注意。



Apacheを再起動。

/etc/init.d/httpd restart


これで,指定したユーザとパスワードを使わない限り,SVN操作できなくなった。

セキュリティや,構成管理上の安全性が確保されたわけだ。



クライアント側でのコミット・チェックアウト時には,ダイアログにユーザ名とパスワードを入力すればよい。

また,ブラウザ上からWebDAV経由でリぽいじ取りを閲覧する際にも,同様の認証作業が要求される。


サーバ側では,今のままだとフックスクリプトがうまく動作しないので,post-commitシェルを下記のように書き換える。

/usr/bin/svn up /var/projects/site1/*

↓

/usr/bin/svn --username user1 --password pass1 --no-auth-cache up /var/projects/site1/*

exit 0

これを全プロジェクトに対して行なう。

(※パスワードが平文で保存される点に注意。デプロイ専用のSVNユーザを設けるとよいかもしれない。)

こうすれば,フックスクリプトの動作時にもユーザ認証が行なわれ,

サーバ内で正常に自動デプロイが実行される。



※もし,コミットが成功してエラーメッセージもないにも関らず,
自動デプロイが走らない場合,
フックスクリプト中の認証情報の記載が間違っていると思われる。


※もし,コミットは成功するにもかかわらず,
post-commitバッチがうまく動作しない場合,
Tortoise SVNのウィンドウ上に下記のようなエラーメッセージが出る。

Subversion commit failed Merge of file: 200 OK
または
ファイルのデータを送信しています .svn: コミットに失敗しました (詳しい理由は以下のとおりです)
svn: MERGE リクエストが失敗しました

この理由を調査するためには,post-commit中でsvnコマンドの呼び出しの末尾に

 > /tmp/hoge.txt 2>&1

とかを付与して,再度コミットしてみる。
そうすると,Tortoise SVNクライアント上での表示は

post-commit hook failed (exit code 1) with no output.

のようになるが,/tmp/hoge.txtには標準エラー出力の内容が保存されている。
中身は,例えば以下のような内容かもしれない:

Authentication realm: <http://localhost:80> Subversion repository
Password for 'apache': Authentication realm: <http://localhost:80> Subversion repository
Username: svn: OPTIONS of 'http://localhost/svn/site1': authorization failed (http://localhost)

これは,フックスクリプト中でユーザ認証せずに svn up しているために起こる現象だ。
usernameとpasswordオプションを付ければ,このエラーは出なくなる。
しかし,代わりに下記のようなエラーが出ることになる。

-----------------------------------------------------------------------
ATTENTION!  Your password for authentication realm:

   <http://localhost:80> Subversion repository

can only be stored to disk unencrypted!  You are advised to configure
your system so that Subversion can store passwords encrypted, if
possible.  See the documentation for details.

You can avoid future appearances of this warning by setting the value
of the 'store-plaintext-passwords' option to either 'yes' or 'no' in
'/var/www/.subversion/servers'.
-----------------------------------------------------------------------
Store password unencrypted (yes/no)? svn: Can't read stdin: End of file found

これは,SVNがパスワードを暗号化しないまま(平文のまま)マシン内に保存してもよいかどうかをユーザに尋ねているのに対して,バッチ側から返事がない(Can't read stdin)ため,尻切れトンボで処理がそのまま終わってしまっている状況だ。
この場合,サーバ内でSVN更新処理は実行されるに至らない。
この事態を回避するためには,no-auth-cacheオプションを指定して,認証情報のキャッシュを防止すればよい。

参考:

SVN encrypted password store
http://stackoverflow.com/questions/38...

  • It is a client issue, it warns you that the credentials used for the different servers are being stored in plain text, you can hide that warning or use an encrypted storage to cache the passwords.


Linux上でシェルが実行される仕組みを,体系的に理解しよう (bash 中級者への道)
http://language-and-engineering.hatenablog.jp/entry/20110617/p1

  • (2−4)標準入力や標準出力とは,プログラムへの入出力を抽象化・一般化したものである
  • (2−6)各コマンドの実行結果は,終了ステータスに格納される
  • (3−2)デーモンは,端末に属さない(standard in must be a tty)


これで,サーバ側・クライアント側共に,複数Webサイトの開発作業及び自動デプロイを

チーム作業で進めてゆく体制が整った。


(11)Windows上にもテスト用のサーバを立てる

冒頭の図には含めなかったが,
ローカルのWindowsマシン上にもLinuxと同一構成のApacheを走らせておけば,
まずはローカルでの動作確認ができる。

ローカル環境にて動作確認後,問題がなければコミットする。
という開発の進め方にする事が望ましい。

コミット後に動作確認,というのは順序がおかしいので。


デプロイ環境は,単体レベルのテスト用途ではなく,チーム作業の統合結果の動作確認や,
ステージングレベルの用途で用いる。

ステージングサイトとは
http://www.sophia-it.com/content/%E3%...


Windows上でのApache構築作業は,下記のページの通り。

Windows Vista上に XAMPP と XOOPS Cube をインストールし,サイトをカスタマイズする手順
http://language-and-engineering.hatenablog.jp/entry/20110730/p1

  • (2)XAMPPをインストールする


その後,D:\xampp\apache\conf\httpd.conf の内容を書き換える。


<Directory "D:/svnrepos">
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Allow from all
</Directory>



Listen 81
<VirtualHost *:81>
    DocumentRoot "D:/svnrepos/site1"
    ErrorLog logs/error.log
    CustomLog logs/access.log common
</VirtualHost>



Listen 82
<VirtualHost *:82>
    DocumentRoot "D:/svnrepos/site2"
    ErrorLog logs/error.log
    CustomLog logs/access.log common
</VirtualHost>

これで,Windows上のワーキングコピーも

ブラウザ上での動作確認のために利用できる。



参考:

Apacheでのバーチャルホストの設定
http://www.gside.org/Gentoo/apache/vi...
Directory "/home/fuga/htdocs"

ディレクトリ /home/fuga/htdocs へのアクセスを許可する設定です。
この設定を行わないと

client denied by server configuration:

という内容のエラーログが出力され、アクセスできません。

補足

関連エントリ:

Linux上にSambaで共有フォルダを作り,Windowsから開発環境として利用しよう (環境構成のわかりやすい図解付き)
http://language-and-engineering.hatenablog.jp/entry/20110820/p1


Windows Vista上に Apache+Subversion+Tortoise SVN をインストールして,ネットワーク越しにリポジトリを利用できるようにする手順
http://language-and-engineering.hatenablog.jp/entry/20110723/p1