VirtualBoxにWeb関連のテスト実行環境を作成してgitでデプロイする

VirtualBoxの仮想マシンにテスト実行環境を作成し、gitを使って作成したコードを仮想マシンにデプロイする環境を作りました。

準備ですが、サンドボックスのテスト環境を作るために仮想化ソフトウェアのVirtualBoxを利用します。仮想マシンのOSにはDebian Squeezeをインストールします。 ホストOSと仮想マシンのアクセスにはSSHとgitを利用します。

自分が試した環境はDebian(Sid)とゲストOS Debian(Squeeze)でしたが、Debianに依存した仕掛けは使っていないのでWindowsやMac環境でも使えますし、ゲストOSもCentOSなどどんな組み合わせでもできると思います。

VirtualBox、git、SSHをインストールします。Debian Sidではaptを使ってインストールできます。

$ sudo apt-get install virtualbox git ssh

VirtualBoxの準備

VirtualBoxにはDebian 6.0 Squeezeをインストールするので、Debianのインストールイメージを用意してください。 使用するインストールイメージは名刺サイズのインストーラ( debian-6.0.x-i386-businesscard.iso )でかまいません。

それではVirtualBoxに仮想マシンを作成して、Debianをインストールします。

Debianのインストールですが、Webアプリの実行にXやGNOMEは必要ありませんので、パッケージグループの選択画面ではチェックをすべて外し最小限のシステムをインストールします。インストール後に必要なパッケージを追加します。

Debianのインストールは手動でおこなって構いませんが、素早く終わらせるためにDebian自動インストール用のpreseedファイルを用意しました。

preseedファイルの使い方は、Debianインストーラーを起動後、メニューの Advanced options → Automated install にカーソルを合わせTabキーを押します。 オプションの入力画面で「url=http://www.nofuture.tv/squeeze.cfg」と追加してエンターキーを押すと最小限のシステムが自動的にインストールされます。(スクリーンショット参照) preseedファイルの設定など、詳しいことについては「Debianのインストールを自動化」をご覧ください。

Squeezeのインストールが終了したら、必要なパッケージを追加するために仮想マシンへログインします。 preseedファイルを利用してインストールした場合のユーザー設定は、以下のようになっています。

ユーザー名 debian
パスワード debian
root なし(sudoを利用)

SSHとgitをインストールします。preseedファイルを利用してインストールした環境ではgitとSSHはすでにインストール済みですので飛ばして次へ進みます。

$ sudo apt-get update
$ sudo apt-get install git ssh

続いてWebアプリを動かすために必要なパッケージをインストールします。必要なパッケージは各自違うと思いますが、例ではapacheとphp5、mysql-serverをインストールしました。

$ sudo apt-get install apache php5 mysql-server

必要ならばサーバーの設定をして、パッケージの追加は終了です。

ホストOSにあるファイルをVirtualBox側に転送する手段としてgit pushを利用します。それを受けるためには共有gitリポジトリが必要になるので作成します。

本来ならばPro Gitの「ちょっとしたセットアップ」のように、gitユーザーを作って共有gitリポジトリの設定をしますが、非常に閉じた環境なので、ログインしたユーザー(例では「debian」という名前のユーザー)で設定をします。

それではgit pushの転送先である共有gitリポジトリを作成します。共有gitリポジトリの作成場所はどこでも構わないのですが、ホームディレクトリにrepoという名前で作成しました。

$ cd ~/
$ mkdir repo
共有リポジトリの場所 /home/(ユーザー名)/repo/

共有gitリポジトリを初期化します。gitリポジトリの初期化にはgit initを使いますが、共有gitリポジトリとして初期化するためには –bare オプションをつけて実行します。

$ cd repo/
$ git init --bare

これでプッシュされたコードをVirtualBox側で受け入れる準備は出来ましたが、共有gitリポジトリは通常のgitリポジトリのようにファイルをそのまま格納しているわけではないので、リポジトリのファイルを利用するには、改めてどこかのディレクトリで git pull を実行する必要があります。

どこかのディレクトリで git pull を実行する方法ですが、gitにはフックと呼ばれる仕組みがあり、アクションが起こるとアクションに応じてスクリプトが実行されます。 このフックを利用して、共有gitリポジトリにプッシュされるとApacheのドキュメントルート /var/www の下でgit pullを実行するように設定をします。

pullするためにはリポジトリをgit cloneをしておく必要があるので /var/www の下でクローンします。

$ cd /var/www/
$ sudo git clone ~/repo/
Cloning into repo...
done.
warning: You appear to have cloned an empty repository.

/var/www以下に書きこみ権限がないのでsudoをつけてgit cloneを実行しましたが、repoの所有者とグループはrootになっています。 このままでは都合が悪いのでrepo以下の所有者とグループを変更しますが、debianユーザーに変更せずに www-data ユーザーにします。 これはApacheが専用のユーザー/グループ www-data で動いており、php(libapache2-mod-php5)も同じ権限で動いているので、それに合わせるためです。

$ sudo chown -R www-data:www-data repo/

www-data に変更しましたが、このままではdebianユーザーが/var/www以下でプルできないので、debianユーザーがwww-dataユーザーになってgit pullできるよう、sudoの設定を追加します。

$ sudo sh -c "echo 'debian ALL=(www-data) NOPASSWD:/usr/bin/git pull' > /etc/sudoers.d/debian"
$ sudo chmod 0440 /etc/sudoers.d/debian 

それではテストをしてみます。

$ sudo -u www-data git pull
Your configuration specifies to merge with the ref 'master'
from the remote, but no such ref was fetched.

クローンしてからなにも変わってないのでフェッチできないと言ってますが、ひとまず、debianユーザーが/var/www/repoでwww-dataとしてgit pullできるようになったので、次はフックの設定を行います。

フックの設定ですが、フックは共有gitリポジトリの中に hooks というディレクトリがあり、その中にアクションに応じたファイル名があります。 共有gitリポジトリにプッシュされた時に、/var/www/repo でpullをしてほしいので post-receive に以下の内容を書きます。

$ cd ~/repo/hooks/
$ vi post-receive
post-receive
#!/bin/sh
cd /var/www/repo/ && sudo -u www-data git pull
$ chmod 755 post-receive

これでひとまず仮想マシンの設定は終わりましたので、仮想マシンを終了させます。

ホストOS側の設定

ゲストOSの設定も終了したので、ホストOSからゲストOSへアクセスするための設定を行います。

ゲストOSのポートをホストOSのポートに割り当てるための、ポートフォワーディングの設定を行います。

登録した仮想マシンの設定ウィンドウを開き、ネットワークにある「高度」をクリックします。高度なオプションの中にある「ポートフォワーディング」ボタンを押し、ポートを割り当てます。 ポート以外の設定ですがプロトコルはそのまま。ホスト・ゲストIPは空にしておきます。

ゲストOS ホストOS
SSH 22 2222
Web 80 8080

これでホストOSからポート2222を使ってSSHアクセスと、ポート8080を使ってWebサーバーへアクセスができるようになりました。

ゲストOSにアクセスする方法ですが、IPアドレスはlocalhost(127.0.0.1)を利用します。 ですので、SSHを使ってゲストOSにアクセスするのであれば localhost(127.0.0.1)の2222ポートにアクセスします。

$ ssh -p 2222 (ユーザー名)@localhost

ブラウザを使ってゲストOSのWebサーバーにアクセスするには、http://localhost:8080/ にアクセスします。

ポートフォワーディングの設定が終わったので、再び仮想マシンを起動します。

仮想マシンの起動ですが、通常通りVirtualBoxのGUIから起動してもよいのですが、VirtualBoxを利用しているのでバックグラウンドで仮想マシンを動かします。

GUIなしでVirtualBoxの仮想マシンを起動するには vboxheadless コマンドを使います。バックグラウンドで動かすには「&」をつければよいので、このようにします。

$ vboxheadless -s (仮想マシン名) &

仮想マシンにアクセスをするには、上でポートフォワードしたSSHを利用してアクセスします。 vboxheadlessを使って起動すると自動的にVRDP(Virtualbox Remote Desktop Protocol)も有効になるので、RDPクライアントを利用してアクセスすることもできます。

バックグラウンドで動かしている仮想マシンを終了するには?

SSHで仮想マシンにログインしているときは shutdown コマンドで終了できます。 ログインしていないときは、コマンドラインから vboxmanage controlvm コマンドを利用して終了させる方法もあります。

$ vboxmanage controlvm (仮想マシン名) acpipowerbutton

ゲストOSにSSHでアクセスする際に必要なSSH鍵ペアを作成します。 例ではvboxで作成しましたが、名前は適当でかまいません。パスフレーズはテストなので無しのほうが使い勝手はよいでしょう。

$ ssh-keygen -f vbox
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 

作成したSSH鍵ペア(例ではvboxとvbox.pub)を ~/.ssh ディレクトリに移動します。

$ mv  vbox* ~/.ssh/

ゲストOSにアクセスするための設定を ~/.ssh/config に追加します。

Host vbox
Hostname localhost
User debian ← ゲストOSにアクセスするユーザー
Port 2222 ← ゲストOSに
IdentityFile ~/.ssh/vbox

SSH公開鍵をVirtualBoxにコピーします。

$ ssh-copy-id -i ~/.ssh/vbox.pub vbox

これでSSHの設定は終わりです。

デプロイしたいコードをgit pushを使って転送するために、コードをgitの管理下に置きます。

gitを使い始める前に初期設定として名前とメールアドレスを登録します。 例ではJohn Doeさんになってますが、自分の名前とメールアドレスに置き換えてください。

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

コードのあるディレクトリに入りgitの初期化をします。(–bareをつけてはいけません)

$ cd (ソースがあるディレクトリ)/
$ git init

ソースをコミット(登録)します。

$ git add . (見えにくいですがaddの後ろにスペースとドットがあります)
$ git commit

コミットをするとエディタが起動するので、ログにどんな事をしたか書きます。初回の登録なので「first commit」とか書くといいですね=)

これでコードがgitの管理下に置かれました。以後、コードを変更した場合はaddしてcomitをしていきます。

もう少しgitのことを知りたいなら「git - 簡単ガイド」を読んでみましょう。 知らない間にgitの第一歩を踏み出していたことがわかります。

コードはgitの管理下に入りましたが、git pushを使ってコードを転送するにはプッシュする先を登録しないと転送できません。 git remoteを使って転送先を登録します。

$ git remote add origin ssh://vbox/home/debian/repo

登録できたのでgit pushを使ってプッシュします。 初めてのプッシュなのでoriginにmasterをプッシュということを明示的に書いていますが、次回からはgit pushのみで更新できます。

$ git push origin master 
Counting objects: 83, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (83/83), done.
Writing objects: 100% (83/83), 3.49 MiB | 5.35 MiB/s, done.
Total 83 (delta 12), reused 0 (delta 0)
remote: sudo: no tty present and no askpass program specified
To ssh://vbox/home/debian/repo
 * [new branch]      master -> master

デプロイできたか確認してみましょう。ブラウザで http://localhost:8080/repo/ にアクセスします。 無事、表示されたでしょうか?

この後はどうするのか

これからソースコードを変更したりしますが、変更したらgit addとgit commitをして、git pushをしていくとVirtualBox側も更新されます。