Ubuntu 14.04上にFuelPHPアプリをCapistrano3でデプロイする環境をChefでセットアップした手順のまとめ

MySQLは、DB専用サーバーを立てることを前提に、WebアプリケーションサーバーとしてApache + mod_phpな環境をChefで構築していく
また、Capistranoに合わせたApacheの設定もChefで記述する

Chefの実行およびCapistoranoによるデプロイは、踏み台を使わずPC Macからすべて実行可能な環境を作る

Chef開発環境セットアップ

Chef DevKITのインストール

Chefは、現在開発キットが提供されておりRuby gemでのインストールは不要になっている
Chef Development KITのサイトに行くとプラットフォームごとのインストーラーを入手できる
https://downloads.chef.io/chef-dk/
開発キットには、chefおよび以下の周辺ツールがオールインワンで含まれている

  • Berkshelf 3.0
  • Test Kitchen
  • Foodcritic

Knife soloのインストール

PCからChefを実行するためにはKnife soloが必要になる
ChefDKのgemに追加する

$ /opt/chefdk/embedded/bin/gem install knife-solo

ホスト名を設定

Chefのノード名に使うホスト名を登録しておく

54.33.11.22 fuelphp_web

SSHの設定

Knife soloコマンドを実行するには、対象サーバーへキーなしでsshできるように設定しておく必要がある
2つの手順のいずれかを適用する

手順1: 新しくキーペアを生成
対象サーバーにログインし、sshdの設定PubkeyAuthenticationを有効にする

PubkeyAuthentication yes

設定を適用

$ sudo service ssh reload

ssh-keygenコマンドで、ローカルに生成したキーの公開キーを対象サーバーに追加する
ここでは、~/.ssh/id_rsa.pubを対象サーバーの.ssh/authorized_keysに追加

$ ssh-keygen
$ ssh-copy-id fuelphp_web

または

$ cat ~/.ssh/id_rsa.pub | ssh ubutu@fuelphp_web 'cat >> ~/.ssh/authorized_keys'

sshして、手動でコピーしても良い

ssh-rsa AAAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx fuelphp_web
ssh-rsa BBBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx foo@localhost.local

以上の設定で、以下のコマンドで対象サーバーにssh可能になる

$ ssh ubuntu@fuelphp_web

参考: インフラエンジニアじゃなくても押さえておきたいSSHの基礎知識

手順2: サービスに割り当てられた既存のキーを使う
AWS EC2のようにインスタンス作成時にsshキーを紐づける場合は、以下のようにローカルの~/.ssh/configに設定を追加してもよい

Host fuelphp_web
   HostName fuelphp_web
   User ubuntu
   Port 22
   IdentityFile ~/.ssh/fuelphp-web-instance.pem

この設定の中でUserを指定しているので、以下のようにユーザーなしでsshコマンドを実行した場合、ユーザーubuntuでログインすることができる

$ ssh fuelphp_web

Chefリポジトリの作成

ここからChefリポジトリ(プロジェクト)を作成していく
ローカルで以下のコマンドを実行してChefリポジトリを作成する

$ mkdir call_system_chef
$ cd call_system_chef/
$ knife solo init .
Creating kitchen...
Creating knife.rb in kitchen...
Creating cupboards...
Setting up Berkshelf...

作成されたChefリポジトリのディレクトリ構成

$ tree -L 2
.
├── Berksfile
├── cookbooks
├── data_bags
├── environments
├── nodes
├── roles
└── site-cookbooks

6 directories, 1 file

また、Gitリポジトリとして初期化しておく

$ git init .
$ git add --all
$ git commit -m "first commit"

対象サーバーにChef Clientをインストール

Chef Clientを対象サーバーに以下のコマンドでインストールする

$ knife solo bootstrap ubuntu@fuelphp_web
Bootstrapping Chef...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 18736  100 18736    0     0  11006      0  0:00:01  0:00:01 --:--:-- 11001
Downloading Chef 12.0.3 for el...
downloading https://www.opscode.com/chef/metadata?v=12.0.3&prerelease=false&nightlies=false&p=el&pv=6&m=x86_64
  to file /tmp/install.sh.2606/metadata.txt
trying wget...
url https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-12.0.3-1.x86_64.rpm

...

Running Chef...
Starting Chef Client, version 12.0.3
Compiling Cookbooks...
Converging 0 resources

Running handlers:
Running handlers complete
Chef Client finished, 0/0 resources updated in 0.878828957 seconds

コマンドはknife solo prepareでもOK

サードパーティcookbookの追加

Webアプリケーション固有のクックブックを作成していく前に、Apache2やPHPといった一般的な環境について準備をする
Chef supermarketに公開されているクックブックを利用する

Berksfileにgitとapache2とをphp追加する

site :opscode

cookbook 'git'
cookbook 'apache2'
cookbook 'php'

これらの設定はChef適用時に自動でcookbooksディレクトリにダウンロードされるのでberks installコマンドは実行しなくてもよい

nodeの設定

run_listに追加

{
  "run_list": [
    "recipe[git]",
    "recipe[php]",
    "recipe[php::module_curl]",
    "recipe[php::module_mysql]",
    "recipe[apache2]",
    "recipe[apache2::mod_php5]",
    "recipe[apache2::mod_rewrite]"
  ],
  "automatic": {
    "ipaddress": "fuelphp_web"
  },
  "apache": {
    "docroot_dir": "/var/www/messagecall/current/public",
    "mpm": "prefork"
  }
}

ここまで適用

$ knife solo cook ubuntu@fuelphp_web

FuelPHPアプリ固有の環境を作成する

クックブックを作成する

$ knife cookbook create fuelblog-web -o site-cookbooks/

デプロイを実行するユーザーdeployを作成して、sshでアクセスするための設定を追加
デプロイ先のディレクトリを作成してApacheにサイトを追加する

# デプロイ用のユーザーを追加 グループはApacheのグループを指定
user 'deploy' do
  comment  'Capistrano User'
  group    'www-data'
  home     '/home/deploy'
  shell    '/bin/bash'
  password nil
  supports :manage_home => true
  action   [:create, :manage]
end

# .sshディレクトリの作成
directory '/home/deploy/.ssh' do
  owner     'deploy'
  group     'www-data'
  mode      00700
  action    :create
end

# .ssh/authorized_keysファイルの作成
file "/home/deploy/.ssh/authorized_keys" do
  user   'deploy'
  group  'www-data'
  mode   00644
  action :create
end

# deployユーザーで公開鍵認証を設定 id_rsa.pubの中身を/home/deploy/.sshにコピー
# 実際は、キーの値はnodeごとに異なるのでattributesにしておいた方がよい
execute 'add key to authorized_keys' do
  command 'echo "ssh-rsa BBBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx foo@localhost.local" >> /home/deploy/.ssh/authorized_keys'
  not_if "grep \"ssh-rsa BBBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx foo@localhost.local\" /home/deploy/.ssh/authorized_keys"
end

# グループに書き込み権限をつけてデプロイ先のディレクトリを作成
directory '/var/www/fuelblog' do
    owner 'www-data'
    group 'www-data'
    mode '2775'
    action :create
end

# Apacheにサイトを追加
web_app 'fuelblog-web' do
       template 'fuelblog.conf.erb'
       server_name node['hostname']
       server_port 80
       docroot node['apache']['docroot_dir']
       allow_override 'All'
       fuel_env node['apache']['fuel_env']
end

# composerのインストール
execute "composer-install" do
  command "curl -sS https://getcomposer.org/installer | php ;mv composer.phar /usr/local/bin/composer"
  not_if { ::File.exists?("/usr/local/bin/composer")}
end

web_appリソースに指定しているApacheのサイト設定のテンプレート
FUEL_ENVはここで指定している

<VirtualHost *:<%= @params[:server_port] || node['apache']['listen_ports'].first %>>
  # ServerName <%= @params[:server_name] %>
  DocumentRoot <%= @params[:docroot] %>

  SetEnv FUEL_ENV <%= @params[:fuel_env] %>

  <Directory <%= @params[:docroot] %>>
    Options <%= [@params[:directory_options] || "FollowSymLinks" ].flatten.join " " %>
    AllowOverride <%= [@params[:allow_override] || "None" ].flatten.join " " %>
  <% if node['apache']['version'] == '2.4' -%>
    Require all granted
  <% else -%>
    Order allow,deny
    Allow from all
  <% end -%>
  </Directory>
</VirtualHost>

参考: Chef-SoloでApacheにプロジェクト固有の設定をする – Qiita

run_listに作成したcookbookを追加

{
  "run_list": [
    ...
    "recipe[apache2::mod_php5]",
    "recipe[apache2::mod_rewrite]",
    "recipe[fuelphp-web]"
  ],
  ...
}

再度Chefを実行して、アプリケーション環境を適用する

$ knife solo cook ubuntu@fuelphp_web

以上で、Capistrano3を使ってFuelPHPアプリをデプロイする準備が整う
次に記事で、この環境に対するデプロイを実装する