2012年2月23日木曜日

FuelPHPってなんじゃ?(Capistranoでデプロイ編)

今回はCapistranoでFuelPHPをデプロイしてみたいと思います。

構成は以下のとおりで、すべてEC2インスタンスです。また今回はDBに関しての説明は省きます。

  • repository(git): vvv.vvv.vvv.vvv
  • admin(capistrano): xxx.xxx.xxx.xxx
  • hoge1(web+app): yyy.yyy.yyy.yyy
  • hoge2(web+app): zzz.zzz.zzz.zzz

各インスタンスでのアクセス関係は以下の通りです。
admin→(deploy)→ hoge1,hoge2 → (git clone) → repotitory
└→ (git ls-remote) → repotitory

まず、各インスタンス間でアクセスできるように設定します。
adminからhoge1, hoge2, repositoryへ、またhoge1, hoge2からrepositoryへSSHできるようにセキュリティグループの設定を行なっておきます。

次にadminからhoge1,hoge2, repositoryへアクセスできるよう、adminの公開鍵をhoge1, hoge2, repositoryに保存します。

admin
# su - memorycraft
$ ssh-keygen -t rsa
$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAslxvqb3fg7IA8qjrKbLanetaTcoESWznl9BrjmygSlUEaKlaqd5FRM1R4mGgJSHFOVV3rBArvRw1V14FW6QKaG6oVNBd6PVryXVWQufC0eSi+FBhkkdgISXUdpLApdx01ZxmMha9HvGl04Y+bSj0lz8oggfdBJrMAxGiUe3POy9dJA6Hw79FMVhBTcycxQ6aJ5PNxd/jOeiI/Npcwved/s7Y8DFwDTJAIz9uiCzdQrPmrM75gyrwis2I2kmeLANQ+d2pcsM8zZf7kglBTifmcegWTQkCkbu4WFO1BL8/JjaoWj7KIXFlHzstkPyn1duvbCBBmkR0HabbU+zNU4J/hw== memorycraft@ip-10-146-69-156
↑
この出力内容をコピー(1)


GitlabもしくはGithubへ(1)の公開鍵を登録します。GUIがない場合はgitユーザーの~/.ssh/authorized_keysに登録します。



hoge1, hoge2
# su - memorycraft
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/memorycraft/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/memorycraft/.ssh/id_rsa.
Your public key has been saved in /home/memorycraft/.ssh/id_rsa.pub.
The key fingerprint is:
b5:6d:1b:f9:e6:ee:c8:86:a3:a6:27:b8:d0:54:2d:ad memorycraft@ip-10-146-93-65
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|       o         |
|      o o .      |
|     . o . o .   |
|    . E S . =    |
|   o       . +   |
|  . ..     .. o  |
|   .. . o o..+   |
|    ...=.. ooo+  |
+-----------------+
$ vi ~/.ssh/authorized_keys
コピーした(1)をペースト
$ chmod 600 ~/.ssh/authorized_keys

次にhoge1, hoge2からrepositoryにSSHアクセスできるよう、hoge1, hoge2の公開鍵をrepositoryに登録します。

hoge1, hoge2
$ cat ~/.ssh/id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzOkvpSWfge0pzSsfbIkVpPZU8xZ+XXoDr+NhWCVVD4iC+F3bh69C90FSGbEDLF1hrgQGcaU6THSmXgozm0uPp0uP2vbjsFgxyklEEDhZrr7kBWIpVx5k2uhzp9xFI1Ijd+xXm1BW1/w1pSvuo0IAvpKMT0Pr5JA5x/1jvQ2JWNSMuZEp19bAQjGA1kgy82BbmX8bQxcnNMKaewiMAT8DrORBFH+yzagvKIcJDhi2/8z5Fp9P0Yxq1clLHEQBnU2g8918Zq5KMkRNnwQEqSrl1KrLVNpuTxh3IdqBXDPxlrdMYDfqdOAfH92f5Mq1cpThJJV2Kv+iej4bkUFcm/CGBQ== memorycraft@ip-10-146-93-65
↑
この出力内容をコピー(2)


capistranoのconfigで登録したリポジトリサーバーにこの内容(2)を登録します。
GitlabやGithubの場合は管理画面のSSH Keysで、gitだけの場合はgitユーザーの~/.ssh/authorized_keysに追加します。



必要なライブラリをインストールしておきます。
# yum install -y make openssh-clients gcc libxml2 libxml2-devel libxslt libxslt-devel python-devel wget readline-devel ncurses-devel gdbm-devel glibc-devel tcl-devel openssl-devel db4-devel byacc httpd gcc-c++ curl-devel openssl-devel zlib-devel httpd-devel apr-devel apr-util-devel sqlite-devel libicu-devel pcre-devel git-core python-setuptools python-devel libicu-devel python-setuptools python-devel libicu-devel git patch libtool php

またホスト登録のyes/noのダイアログを解消しておくため、それぞれ一度sshでログインを試みます。

admin
# su - memorycraft
$ ssh memorycraft@yyy.yyy.yyy.yyy
$ ssh memorycraft@zzz.zzz.zzz.zzz

hoge1, hoge2
#su - memorycraft
$ ssh memorycraft@vvv.vvv.vvv.vvv

ここでcapistrano用にディレクトリを作成し、capistranoディレクトリの中でcapifyコマンド実行します。
capifyはcapistranoのタスクなどを定義するためのひな形を作成するためのコマンドです。

admin
$ mkdir ~/capistrano
$ cd ~/capistrano
$ capify .
$ tree ~/capistrano
capistrano
|-- Capfile
`-- config
    `-- deploy.rb

作成されたCapfileを以下のように修正します。

load 'deploy' if respond_to?(:namespace)
Dir['vendor/gems/*/recipes/*.rb','vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
load 'config/deploy' # remove this line to skip loading any of the default tasks


またconfig/deploy.rbを以下のように修正します。

set :application, "bookstore" #アプリケーション名
set :user, "memorycraft" #SSHアクセスする際のユーザー
set :use_sudo, false #sudoは使用しない

set :deploy_to, "/home/memorycraft/bookstore" #デプロイ先
set :scm, :git #今回はgitを使用
set :repository, "git@vvv.vvv.vvv.vvv:bookstore.git"  # gitリポジトリ
set :branch, "master" # ブランチはmasterを選択
set :git_enable_submodules, 1 #サブモジュールを使用するか
set :deploy_via, :remote_cache #

role :web, "yyy.yyy.yyy.yyy","zzz.zzz.zzz.zzz"

set :keep_releases, 3

namespace :deploy do
  task :start do ; end
  task :stop do ; end
  task :restart, :roles => :app, :except => { :no_release => true } do
  end
end


ここでcap deploy:setupを行います。
$ cd ~/capistrano
$ cap deploy:setup

するとhoge1, hoge2にデプロイ用のリリース管理ディレクトリが作成されます。capistranoはこのディレクトリを使用してデプロイの世代管理なども行うことができます。

hoge1, hoge2
$ tree bookstore/
bookstore/
├── releases
└── shared
    ├── log
    ├── pids
    └── system

これで準備ができたので、デプロイを行います。

admin
$ cd ~/capistrano
$ cap deploy

するとタスク処理の進捗結果が出力されます。
デフォルトのdeployタスクは、Railsアプリのデプロイを想定しているため、結果には、例えばgitサーバーのEIPの正引き逆引きの不一致やRailsに特化したjavascript, stylesheet, imagesなどのディレクトリの検索などのエラーが表示されていますが、最終行にfailedという項目が表示されていなければ全体的には成功しているようです。

hoge1, hoge2
ここではhttpdでホストするために、/var/www/html/bookstoreにリンクします。
capistranoはcurrentというディレクトリに最新のデプロイを保存しているので、そこをリンクターゲットにします。
# cd /home
# chmod 755 /home/memorycraft
# cd /var/www/html
# ln -s /home/memorycraft/bookstore/current/public bookstore

httpdでホストします。
# /etc/init.d/htpd start

hoge1,hoge2をブラウザ画面を見てみます。
ともにFuelPHPがホストされているのがわかります。





次に、開発環境でfuel/app/views/welcome/index.phpの中身を変えてpushします。
$ cd ~/bookstore
$ vi fuel/app/views/welcome/index.php
<h1>Welcome!</h1>
↓
<h1>Welcome!(version 2)</h1>

$ git add .
$ git commit -m 'change welcome message to version 2'
$ git push origin master


そして、deployします。
$ cd ~/capistrano
$ cap deploy

ブラウザで確認します。


きちんとデプロイされています。

次にこれをひとつ前のバージョンに戻してみます。
デプロイを前のバージョンに戻すには、deploy:rollbackタスクを実行します。

$ ~/capistrano
$ cap deploy:rollback



おお!、もとに戻っています!
これで、アプリケーションのデプロイコントロールがだいぶ楽になりました。
次回はcapistranoでマイグレーションを行いたいと思います。

今回は以上です。

2012年2月21日火曜日

FuelPHPってなんじゃ?(Git管理編)

以前FuelPHPのインストールと簡単なアプリの作成を行いましたが、
今回はFuelPHPを使ったアプリケーションを自分の管理するGitマスターリポジトリに登録してみたいと思います。

前回のGitlabのプロジェクト登録編では、すでにリポジトリに一度pushしました。そのように未取得の変更がマスタリポジトリ上に存在する場合はマージしてからpushする必要があります。その説明は別の機会にするとして、今回はリポジトリがまだ空の状態という想定で行います。

まずはoilコマンドで適当にプロジェクトを作成します。
oil create bookstore
cd bookstore/

oil createコマンドはFuelPHPを含めたアプリケーションひな形をGithubからcloneするので、Githubのgit管理下にあるため、まず.gitから始まるファイルを削除します。
rm -rf .git*

.gitが削除されたのでGithubリポジトリ管理外となりました。
ここで、あらためて自分のgit管理下におくため初期化を行います。
git init

また、FuelPHPのfuel/coreとfuel/packagesのみをGithubのFuelPHPのgit管理下に置き、このアプリケーションのサブモジュールとして登録します。
git submodule add git://github.com/fuel/core.git fuel/core/
git submodule add git://github.com/fuel/oil.git fuel/packages/oil
git submodule add git://github.com/fuel/auth.git fuel/packages/auth
git submodule add git://github.com/fuel/parser.git fuel/packages/parser
git submodule add git://github.com/fuel/orm.git fuel/packages/orm
git submodule add git://github.com/fuel/email.git fuel/packages/email

ここまで行ったらアプリケーションツリー全体を次回コミットに含めるためステージに上げます。
git add .

ここでは前回のGitlabサーバーをマスターリポジトリとするのでGitlabのユーザー情報を登録します。
git config --global user.name "miura"
git config --global user.email  "miura@cloudpack.jp"

まずローカルリポジトリにコミットします。
git commit -m 'reinitialize with submoduled'

ここで、Gitlabサーバーのgitリポジトリをoriginという名前でリポジトリ登録します。
この時点でgitサーバー側ではGitlabでプロジェクト登録してあるか、Gitlabを使用していない場合はgitのベアリポジトリを作成してある必要があります。
git remote add origin git@176.34.51.75:bookstore.git

今登録したoriginリポジトリのmasterブランチへpushします。
git push -u origin master

それでは反映しているかGitlabで確認してみます。



うまく登録されているようです。
これで、FuelPHPを利用したチーム開発もできるようになります。

今回は以上です。

Gitlabってなんじゃ?(プロジェクト登録編)

前回はGitlabでユーザーを登録したので、今回はbookstoreという名前のプロジェクトを登録してみます。
最初はダッシュボードにはプロジェクトは表示されていないので、右側にある「New Project」ボタンをクリックします。するとプロジェクトの登録画面が表示されます。




プロジェクト名とリポジトリ内のパスとコードを入力します。ここではすべてbookstoreとします。
説明欄に適当に入力して、「Save」ボタンをクリックします。
この時点でこのサーバーのgitのリポジトリが作成されます。
また、「Save」を押下すると以下のような説明画面が表示されます。

この画面の上部赤の部分は設定不足などのエラーで、下部のグレーの部分はこれから行う必要のあることが記載されています。まず赤のエラーをなくすようにしてみます。
最初にSSHキーがないと書いてあるので、これを解消します。




githubと同様に、SSHキーはユーザーがgitリポジトリにアクセスする際に必要で、gitアクセスを行う端末のSSH公開鍵をgitlabに登録することで、リポジトリへのアクセスを許可する仕組みになっています。

ローカルの端末でSSHキーをrsaで作成し、公開鍵の中身をコピーします。
$ ssh-keygen -t rsa
$ cat ~/.ssh/id_rsa.pub



次に、gitlabのヘッダ右端のアイコンから「My profile」を選択し、現在ログイン中の自分の情報設定画面を表示します。ローカルナビゲーションの右端に「Keys」というタブボタンがあるので、それを選択します。
ここにSSHキーを複数登録できます。「Add New」をクリックして、適当にタイトルをつけ、先程コピーした公開鍵の中身を貼付けて「Save」ボタンをクリックし、登録します。




ここで改めてbookstoreプロジェクトを表示してみると、先ほどの赤いエラーがひとつ減っていることがわかります。
次のエラーはまだリポジトリになにもpushされていない旨のエラーです。



それではコンテンツを作成し、マスタリポジトリにpushしてみます。
グレーの部分の指示通りにすすみます。

ユーザーの情報を設定し、
$ git config --global user.name "miura"
$ git config --global user.email  "miura@cloudpack.jp"


bookstoreディレクトリを作成しローカルリポジトリの作成を行います。
$ mkdir bookstore
$ cd bookstore/
$ git init


適当なファイルをローカルリポジトリにコミットし、
$ echo 'Hello World! books' > README.md
$ git add .
$ git commit -m 'initial commit'


先程gitlab上で作成したリモートリポジトリをoriginという名前で登録を行います。
$ git remote add origin git@176.34.51.75:bookstore.git


そのoriginに対して、変更をpushします。
$ git push -u origin master


完了したら再度プロジェクト画面をリロードしてみます。
すると先ほどの説明画面ではなく、プロジェクトの情報画面になっていることがわかります。
これですべて正常に登録が完了したことになります。





ローカルナビの「Files」をみてみるとリポジトリのファイルリストが表示され、さきほどコミットしたファイルがあるのを確認できます。


また、「Project」内の「Team」タブで登録済みのユーザーをこのプロジェクトへ参加させることができます。


これで、ユーザーとプロジェクトが登録でき、gitからの登録もでき、プロジェクトで使用することができるようになりました。

今後プロジェクトで試しに使ってみたいと思います。
今回は以上です。

Capistranoってなんじゃ?(EC2にインストール編)

CapistranoはSSH経由でリモートコマンドを実行するためのツールで、端末間でのアプリケーションのデプロイなどに使用されています。Ruby on Railsの台頭とともに知名度をあげ、Railsのデプロイメントでは定番のツールになっています。

Capistranoはそれ自体がRuby製で、Rubyのためのツールのようですが、冒頭の通りSSHでリモートコマンド実行を管理する用途であればどんな状況でも利用できます。

今回試してみるユースケースでは
1台の管理サーバーから2つのサーバー上にファイルを作成してみます。

まずEC2でAmazon Linuxを3台分マイクロインスタンスで起動しておきます。
ここでは管理サーバーをadmin、リモートの2台をhoge1,hoge2とし、3台にそれぞれEIPを付与します。
仮にそれぞれのEIPは以下の通りとします。
  • admin: xxx.xxx.xxx.xxx
  • hoge1: yyy.yyy.yyy.yyy
  • hoge2: zzz.zzz.zzz.zzz


また、adminからhoge1,hoge2にはsshでアクセスするため、hoge1,hoge2が所属するセキュリティブループにadminからのSSH接続を許可しておきます。


インストール

まずは早速インストールしてみます。Capistranoは管理サーバーにだけインストールされていればよく、
リモート先のサーバーにはインストールする必要はありません。
zlib-develやopenssl-develなどの必要なライブラリはあらかじめインストールしてあることとします。
今回はrvmをつかってRubyをインストールします。

$ cd ~/
$ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
$ source ~/.bash_profile
$ rvm install 1.9.3
$ rvm 1.9.3 --default

Capistranoはgemで提供されているのでgemからインストールし、インストールが成功しているかバージョンを確認してみます。
$ gem install capistrano
$ cap --version
Capistrano v2.10.0

これでインストールは完了です。


SSH設定

管理サーバーadminからhoge1, hoge2へSSHアクセスを行う必要があるので、SSHの設定を行います。
まずadmin, hoge1, hoge2で同じユーザーを作成します。

admin, hoge1, hoge2
# useradd memorycraft
# passwd memorycraft

次にadminで作成したSSH公開鍵をhoge1, hoge2へ登録します。

admin
# su - memorycraft
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/memorycraft/.ssh/id_rsa):
Created directory '/home/memorycraft/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/memorycraft/.ssh/id_rsa.
Your public key has been saved in /home/memorycraft/.ssh/id_rsa.pub.
The key fingerprint is:
4d:78:29:3a:b1:e2:19:a3:f0:47:fb:53:75:5d:c1:76 memorycraft@ip-10-146-93-65
The key's randomart image is:
+--[ RSA 2048]----+
|              ...|
|         . .   oE|
|      . o +  ....|
|       + =. . .  |
|.   = + S...     |
| o + * ..        |
|  o =  .         |
|   . ..          |
|      ..         |
+-----------------+

$ cd ~/.ssh/
$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA7wXX3xR9rT7EoVfT1NI3oZbzAZGJKD45jnm3CR40G37w+MCFpw1x4XlEF5IWNAXUIKWowVsul88i4g3NDpFd7QFDN0X5cgfkmddLh5B7qDGMKZU8/N4T55AYP4go5TkH0XSESrZDMBcdCII6n6/saB1xMLOO0+dqBLQZ48G2LyrJd6ZxEBHEUhP6Ed4MQeQoQw1uonMsbHC8UwPTfggfhhAGgv488GVgYUo6jYzMez/iagXObrpzBE3gM6vMpPRSH+IivGBeFZirIMOm4qrQPxaojy5f6YQoeqMG3MFKwk/575vCT4cjJa2WwIHEqzMRYfWeFrgRGVqUYbtZ3nV0Hw== memorycraft@ip-10-146-93-65
↑これをコピーする

hoge1, hoge2
# su - memorycraft
$ ssh memorycraft@localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
RSA key fingerprint is 01:b3:bd:1f:ee:85:7f:ce:9a:e9:a0:f0:15:e1:10:ed.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
Permission denied (publickey).
$ cd ~/.ssh
$ vi authorized_keys
↑さきほどコピーした内容をペーストする
$ chmod 600 authorized_keys

これで登録できました。
接続できるか確認してみます。

adminhoge1
# su - memorycraft
$ ssh memorycraft@yyy.yyy.yyy.yyy
Last login: Mon Feb 20 19:05:05 2012 from xxx.xxx.xxx.xxx

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

See /usr/share/doc/system-release/ for latest release notes.
There are 23 security update(s) out of 32 total update(s) available

adminhoge2
# su - memorycraft
$ ssh memorycraft@zzz.zzz.zzz.zzz
Last login: Mon Feb 20 19:05:05 2012 from xxx.xxx.xxx.xxx

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

See /usr/share/doc/system-release/ for latest release notes.
There are 23 security update(s) out of 32 total update(s) available

無事接続できました。


Capistranoのテスト

それではcapistranoを使用して、hoge1, hoge2にファイルを作成してみます。
capistranoはタスクを定義するCapfileという名前のファイルを読み込んで実行します。
まず、adminでCapfileという名前のファイルを作成し、以下のように内容を記述します。

admin
# su - memorycraft
$ mkdir cap_test
$ cd cap_test
$ vi Capfile
以下のように入力します。

# memorycraftでログインする
set :user, 'memorycraft'

# helloworldという名前でhoge1(yyy.yyy.yyy.yyy), hoge2(zzz.zzz.zzz.zzz)それぞれにリモートコマンドを実行するタスクを定義
task :helloworld, :hosts => "xxx.xxx.xxx.xxx,yyy.yyy.yyy.yyy" do
  # /home/memorycraft/footprintというファイルにhelloworld_日付という文字列を追加する
  run "echo helloworld_`date` >> /home/memorycraft/footprint"
end


各行の意味はコメントの通りです。
それではcapistranoを実行してみます。
capistranoの実行はcapコマンドを使用し、タスク名を指定します。
$ cap helloworld
  * executing `helloworld'
  * executing "echo helloworld_`date` >> /home/memorycraft/footprint"
    servers: ["yyy.yyy.yyy.yyy", "zzz.zzz.zzz.zzz"]
    [yyy.yyy.yyy.yyy] executing command
    [yyy.yyy.yyy.yyy] sh -c 'echo helloworld_`date` >> /home/memorycraft/footprint'
    [zzz.zzz.zzz.zzz] executing command
    [zzz.zzz.zzz.zzz] sh -c 'echo helloworld_`date` >> /home/memorycraft/footprint'
    command finished in 39ms

どうやら正常に終了したようです。
それではhoge1, hoge2でファイルを確認してみましょう。

hoge1
$ tail -1000f /home/memorycraft/footprint
helloworld_Mon Feb 20 21:12:40 UTC 2012

hoge2
$ tail -1000f /home/memorycraft/footprint
helloworld_Mon Feb 20 21:12:40 UTC 2012

おお、ちゃんと文字が入っています!
Capfileの記述を見る通り、シェルでできることであればなんでも設定できるため、デプロイ以外にも様々な使い道があります。

次回は、デプロイをためしてみたいと思います。
今回は以上です。


2012年2月20日月曜日

Gitlabってなんじゃ?(ユーザー登録編)

前回Gitlabのインストールが終了したので、今回は早速さわってみたいと思います。

http://ホスト名/gitlabhq/にアクセスすると、このような画面になります。
Gitlabのインストール終了時に表示されたIDとパスワードをここで入力し、「Sign in」をクリックします。



すると初期ユーザーのダッシュボードが表示されます。
ここにはプロジェクトの状況などが表示されます。




ダッシュボードの右側に新規プロジェクトの登録ボタンと管理エリアのボタンがあります。
まずはユーザーを登録するために管理エリアを覗いてみます。
「Visit Admin Area」をクリックします。

すると、ユーザーの一覧画面が表示されます。右上の「New User」ボタンをクリックすると以下のように登録画面が開きます。



ここに適宜情報を入力します。ここでは正規の管理者を登録するため、「Administrator」にチェックを入れます。
入力を終え、「Save」ボタンをクリックすると、完了画面が表示され、一覧画面に戻ると以下のようにユーザーが追加されているのがわかります。



ここでいま登録したばかりのユーザーにログインし直します。ヘッダの右端のアイコンから「logout」を選択し、一度ログイン画面に戻り、登録したメールアドレスとパスワードでログインし直します。

また、ここで正規の管理者を登録したので、セキュリティのためにデフォルトのAdministratorは削除するかパスワードを変更しておきましょう。

今回は以上です。
次回はプロジェクトの登録です。


2012年2月17日金曜日

Gitlabってなんじゃ?(EC2にインストール編)


Gitlabとは自ホストにGithubライクなリポジトリ管理サイトを立てられるオープンソースツールで、Gitlabhqとも呼ばれています。
Gitを使いたいが外部サイトに依存するには抵抗がある場合は、自前のサイトでホストしてプロジェクト管理、タスク管理、ソース管理できるのでとても有用なプロダクトです。

では早速導入してみます。

GitlabのホストをするためのインスタンスをEC2に立ち上げます。
運用時は必要に応じてインスタンスサイズを変えれば良いですが、インストール時は思いコンパイルが走るので、small以上にしておくと待ち時間が減ります。

今回はCentOS(suz-lab_ebs_centos-core-x86_64-6.0.5)へインストールを行ってみます。
gitアクセスとサイトのブラウジングでSSHとHTTPを使用するため、セキュリティグループ設定でSSHとHTTPを適宜開放しておきます。

以降はEC2インスタンスが起動し、SSH接続した時点からの手順になります。


必要なライブラリのインストール


SELinuxが有効な場合は無効に設定します。
# setenforce 0

まず、rootで以下のライブラリをインストールしておきます。
# yum install -y wget gcc gcc-c++ make patch libtool openssl-devel openssh-clients libxml2 libxml2-devel libxslt libxslt-devel readline-devel ncurses-devel gdbm-devel glibc-devel tcl-devel db4-devel byacc curl-devel zlib-devel httpd httpd-devel apr-devel apr-util-devel sqlite-devel libicu-devel pcre-devel git git-core python-setuptools python-devel

また、easy_installでpygmentsもインストールしておきます。
# cd /usr/local/src/
# curl -O http://peak.telecommunity.com/dist/ez_setup.py
# python ez_setup.py
# easy_install pygments

次にredisのインストールと起動を行います。redisとは高速で永続化可能なインメモリDBで、gitlabhqで利用されています。
# wget http://redis.googlecode.com/files/redis-2.4.6.tar.gz
# tar zxvf redis-2.4.6.tar.gz
# cd redis-2.4.6
# make
# make install
# nohup redis-server &


ユーザーの追加

ここでgitリポジトリとGitlabを管理するためのユーザーを追加し、グループを共有しておきます。
# useradd git
# useradd gitlabhq
# usermod -a -G git gitlabhq
# passwd gitlabhq

gitlabhqユーザーでSSHの鍵を作成します。gitlabhqのプロダクトからgitリポジトリにアクセスするために使用します。できた公開鍵をgitユーザーのホームディレクトリに置いておきます。
# su - gitlabhq
$ ssh-keygen -t rsa
$ ssh git@localhost
$ exit
# cp /home/gitlabhq/.ssh/id_rsa.pub /home/git/rails.pub
# chown git:git /home/git/rails.pub
# chmod 600  /home/git/rails.pub


gitoliteのインストール

gitリポジトリそのものの管理やアクセス管理をするためのgitoliteというプロダクトをインストールします。gitlabhqは間接的にgitoliteを使用してリポジトリを管理します。
# su - git
$ git clone git://github.com/gitlabhq/gitolite /home/git/gitolite
$ /home/git/gitolite/src/gl-system-install
$ sh -c "PATH=/home/git/bin:$PATH; gl-setup ~/rails.pub"

インストールの最中に自動的に設定ファイルが開くので、以下の変更を行います。
  //$REPO_UMASK = 0077;
  $REPO_UMASK = 0007;
ファイルを保存し閉じるとインストールが再開し、まもなく完了します。

次に各ディレクトリのパーミッションを調整します。
$ exit
# chmod 755 /home/gitlabhq/
# chmod 750 /home/git/
# chmod -R g+rwX /home/git/repositories/
# chown -R git:git /home/git/repositories/


gitlabhqのインストール

gitlab本体はgithubと同じくRails製です。ここでRubyとRailsをインストールします。今回はApacheで起動するためPassengerもインストールします。
# su - gitlabhq
$ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
$ source ~/.bash_profile
$ rvm install 1.9.2
$ rvm 1.9.2 --default
$ gem install rails passenger rake bundler grit
$ passenger-install-apache2-module

次にgitlabhq本体をgitからインストールします。
$ git clone git://github.com/gitlabhq/gitlabhq.git
$ cd gitlabhq
$ bundle install --without development test
<---追記:2012/02/28時点でのマスターブランチでは以下のようにymlをコピーをする必要があります。
$ cp config/database.yml.example config/database.yml
$ cp config/gitlab.yml.example config/gitlab.yml
--->
$ bundle exec rake db:setup RAILS_ENV=production
$ bundle exec rake db:seed_fu RAILS_ENV=production
$ vi  config/gitlab.yml
   gitlab.ymlのgit_host/host: の欄にこのインスタンスのパブリックIPかパブリックDNS名を入力


Apacheの設定

次に、gitlabhqをApacheでホストするための設定を行います。
まず、/var/www/htmlにgitlabhqのpublicフォルダへのリンクを貼ります。
$ exit
# cd /var/www/html
# ln -s /home/gitlabhq/gitlabhq/public gitlabhq


次にhttpd.confの設定を行います。
さきほどpassenger-install-apache2-moduleのインストール完了時に表示されたLoadModuleの設定とVirtualHostのサンプルを元に、httpd.confの最後尾に以下のように追加します。
# vi /etc/httpd/conf/httpd.conf
-------
LoadModule passenger_module /home/gitlabhq/.rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.11/ext/apache2/mod_passenger.so
PassengerRoot /home/gitlabhq/.rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.11
PassengerRuby /home/gitlabhq/.rvm/wrappers/ruby-1.9.2-p290/ruby
RailsEnv production

<VirtualHost *:80>
    ServerName gitlabhq.cloudpack.jp
    DocumentRoot /var/www/html
    ErrorLog logs/gitlabhq_error_log
    CustomLog logs/gitlabhq_access_log common
    RailsBaseURI /gitlabhq
</VirtualHost>

Apacheを起動します。
# /etc/init.d/httpd start


問題なく起動したら、さっそく画面を見てみましょう。

ブラウザでhttp://ホスト名/gitlabhq/を見てみます。


おお、表示されました!
インストールは成功のようです。

今回は以上です。
次回はGitlabの機能をさわってみたいと思います。

2012年2月6日月曜日

S3ってなんじゃ?(CloudFrontでストリーミングログを取得)

CloudFrontでストリーミングをするときに、デフォルトで試聴ログが取れるので、試してみました。


ストリーミングの設定

まずストリーミング用とログ用のにバケットを2つ用意します。
  • stream.memorycraft.jp:CDNストリーミングとプレイヤーのWEBホスト用のバケット
  • log.stream.memorycraft.jp:ストリームログ用のバケット



CDN用のバケットではプレイヤーのページをWEBホスティングするので、「Website」の設定をしておきます。




次にストリーミング用のバケットにプレイヤーとムービーなどをアップします。
今回は以下のWEBプレイヤーを使用しました。

JWPlayer
http://www.longtailvideo.com/players/jw-flv-player/

このフリープレイヤーにはムービーのサンプルとプレイヤーを埋め込むためのHTMLのテンプレートが付属しているので、以下のように変更してCDN用のバケットにアップします。
また今回はユーザーを特定するために、rtmpアクセスにuser_idのクエリをつけて見ました。
変更部分は赤字で示しています。

<!--     THIS IS A BASIC HTML FILE TO PLAY FLV's USING JW PLAYER
The following code is from longtailvideo.com's 'Setup Wizard', found at http://www.longtailvideo.com/support/jw-player-setup-wizard
-->
<HTML>
<HEAD>
<TITLE> 
Streaming Video with JW Player
</TITLE> 
</HEAD>
<BODY>
<!-- Put a header above your video, if you like
-->
<H1>This is my header</H1>
<!--This is where you call on the required JavaScript file. You uploaded this in step 2a; you can recognize it by the .js suffix
-->
<script type='text/javascript' src='http://s3-ap-northeast-1.amazonaws.com/stream.memorycraft.jp/swfobject.js'></script> 
<div id='mediaspace'>This text will be replaced</div>
<!--Where it says YOUR_BUCKET/player.swf is where you specify the player that you uploaded in step 2b
-->
<script type='text/javascript'>
var so = new SWFObject('http://s3-ap-northeast-1.amazonaws.com/stream.memorycraft.jp/player.swf','mpl','470','290','9');
   so.addParam('allowfullscreen','true');
   so.addParam('allowscriptaccess','always');
   so.addParam('wmode','opaque');
<!--This next line is where you specify your video file (uploaded in step 2c). For .flv files, you must write it as below ('YOUR_VIDEO_FILE'),  *without*  the .flv extension.
-->
   so.addVariable('file','mp4:mymovie');
<!--This next line is where you point to your streaming distribution on cloudfront (done in step 3 above). NOTE: you *MUST* add "/cfx/st/" for it to work. This specifies it is a cloudfront object (cfx) and that it is to be streamed (st). This is the URL of the streaming distribution--it ends with .cloudfront.net. In the example above, I would write: 'rtmp:// s1jng015tymskd.cloudfront.net/cfx/st/'
--> 
so.addVariable('streamer','rtmp://s23sut0ft0hkv9.cloudfront.net/cfx/st/?user_id=5678');
   so.write('mediaspace');
</script>
</BODY>
</HTML>
<!--Common problems:
- You cannot have any spaces in any of your URL's (including your 'rtmp://...'  URL)    (i.e.,  http:// thereisaspaceatthebeginninghere.xxx)
- Be sure you are calling the correctly numbered version of the flowplayer objects/players (i.e. flowplayer-3.2.2.swf
- You cannot have duplicates of 's3.amazonaws.com' or 'cloudfront.net' in the same address (i.e. (http://s3.amazonaws.com/s3.amazonaws.com/YOUR_BUCKET/player.swf)
- There is a different naming protocol for mp4 vs flv files. For .mp4 files, YOU MUST write it as 'mp4:YOUR_VIDEO_FILE_WITHOUT_THE _MP4_SUFFIX'. For .flv files, you simply write the name of the file, 'YOUR_VIDEO_FILE_WITHOUT_THE_FLV_SUFFIX'.
-->

バケットにアップされるファイルはこのようになります。



次にCDNの設定をします。CloudFrontタブで「Create Distribution」を選択し、最初のDISTRIBUTION TYPEのフェーズで「Delivery Method」にStreamingを選択します。またBucketには先程ムービー一式をアップしたCDN用のバケットを指定します。



次のDISTRIBUTION DETAILSフェーズでは「Logging」の項目をOnに設定して、「Select Log Bucket」から先ほどのログ用のバケットを指定します。また、ここでは「Log Prefix」にstreamと入力して作成を終了します。



それでは、S3ホスティングされたプレイヤーのページを表示してみます。


おお、表示されました!



ログの確認

しばらく(数時間)すると、ログ用のバケットにストリーミングのログが吐き出され始めます。



これらの一つをダウンロードして開いてみると以下のようになっています。いわゆるFMSのログです。


#Version: 1.0
#Fields: date time x-edge-location c-ip x-event sc-bytes x-cf-status x-cf-client-id cs-uri-stem cs-uri-query c-referrer x-page-url c-user-agent x-sname x-sname-query x-file-ext x-sid
2012-02-02 18:12:00 SFO4 219.117.233.241 connect 3073 OK 66f18822-d17a-4e1d-9319-e279ffe82caa rtmp://s23sut0ft0hkv9.cloudfront.net/cfx/st/ user_id=5678 http://s3-ap-northeast-1.amazonaws.com/stream.memorycraft.jp/player.swf http://s3-ap-northeast-1.amazonaws.com/stream.memorycraft.jp/player.html MAC%2011,2,202,183 - - - -
2012-02-02 18:12:00 SFO4 219.117.233.241 play 3476 OK 66f18822-d17a-4e1d-9319-e279ffe82caa rtmp://s23sut0ft0hkv9.cloudfront.net/cfx/st/ user_id=5678 http://s3-ap-northeast-1.amazonaws.com/stream.memorycraft.jp/player.swf http://s3-ap-northeast-1.amazonaws.com/stream.memorycraft.jp/player.html MAC%2011,2,202,183 mymovie - mp4 1
2012-02-02 18:12:01 SFO4 219.117.233.241 stop 205127 OK 66f18822-d17a-4e1d-9319-e279ffe82caa rtmp://s23sut0ft0hkv9.cloudfront.net/cfx/st/ user_id=5678 http://s3-ap-northeast-1.amazonaws.com/stream.memorycraft.jp/player.swf http://s3-ap-northeast-1.amazonaws.com/stream.memorycraft.jp/player.html MAC%2011,2,202,183 mymovie - mp4 1
2012-02-02 18:12:04 SFO4 219.117.233.241 pause 205295 OK 66f18822-d17a-4e1d-9319-e279ffe82caa rtmp://s23sut0ft0hkv9.cloudfront.net/cfx/st/ user_id=5678 http://s3-ap-northeast-1.amazonaws.com/stream.memorycraft.jp/player.swf http://s3-ap-northeast-1.amazonaws.com/stream.memorycraft.jp/player.html MAC%2011,2,202,183 mymovie - mp4 -
2012-02-02 18:12:18 SFO4 219.117.233.241 unpause 205295 OK 66f18822-d17a-4e1d-9319-e279ffe82caa rtmp://s23sut0ft0hkv9.cloudfront.net/cfx/st/ user_id=5678 http://s3-ap-northeast-1.amazonaws.com/stream.memorycraft.jp/player.swf http://s3-ap-northeast-1.amazonaws.com/stream.memorycraft.jp/player.html MAC%2011,2,202,183 mymovie - mp4 -
2012-02-02 18:12:21 SFO4 219.117.233.241 disconnect 205295 OK 66f18822-d17a-4e1d-9319-e279ffe82caa rtmp://s23sut0ft0hkv9.cloudfront.net/cfx/st/ user_id=5678 http://s3-ap-northeast-1.amazonaws.com/stream.memorycraft.jp/player.swf http://s3-ap-northeast-1.amazonaws.com/stream.memorycraft.jp/player.html MAC%2011,2,202,183 - - - -


これらの項目は以下のようになっています。

date日付
time時刻
x-edge-locationCDNのエッジロケーションを空港名のような3文字コード+数字で示しています。
c-ipクライアントのIP
x-eventストリームのイベントです。
Connect, Disconnect, Play, Stop, Pause, Unpause, Seekがあります。
sc-bytesサーバーから送られたバイト数
x-cf-statusイベントのステータス
x-cf-client-id
コネクションに対して一意のクライアントID
cs-uri-stemストリームURIのベース部分
cs-uri-queryストリームURIのクエリ部分
c-referrerストリーミングアクセスのリファラ
x-page-urlストリーミングアクセス元のWEBページのURL
c-user-agentユーザーエージェント
x-snameストリーミングされるファイル名
x-sname-queryストリーミングアクセスのクエリ
x-file-extストリーミングされるファイルの拡張子
x-sidコネクション内で一意なストリームID

ここで、x-eventでストリームの状態(Play, Stop, Pause, Unpauseなど)と、x-sname-queryでユーザーの特定やその他のデータを送信できることで、工夫すれば試聴解析ができそうです。

とりあえず今回は以上です。