去年夏に Chef に出会い、スマートWPのセットアップ方法を変えました。
今までは「AWS EC2 を手動でセットアップして AMI 保存」を繰り返すことでサーバをバージョンアップしてきた方法から、まっさらな AWS AMI を Chef で一気にセットアップするように切り替えました。
何が良いかというと、
- 最新のバージョンが常に保たれる
- AWS AMI もバージョンアップされるし、各アプリケーションも常にバージョンアップされるので
- AMIを更新し続けると古いバージョンのままになってどこかでバージョンアップの作業が必要になる
- すべての作業内容がレシピに残る
- どうしても手動だとやったことの記録漏れが出がち
- 手動よりも圧倒的に早い
というところかと思う。
そんな Cehf で作ったスマートWPのレシピを公開します。
このレシピで作られたスマートWPのサーバ環境は私の個人ブログ hirofukami.com と会社のサイト ShakeSoul inc. があって、負荷状況に応じて自動的にサーバを増減させるオートスケーリングが動くようになっています。
ご興味のある方は スマートWPのサービス紹介ページを見てみてください。

レシピは2つ使っていて、他の環境とも共用しているベースとなるセットアップの後にスケーラブルな構成のためのレシピを適用しています。
では、以下。私の Github Gist からの貼付けです。
まずはベースの設定。recipe[swp_setup]です。
# | |
# Cookbook Name:: swp_setup | |
# Recipe:: default | |
# | |
# Copyright 2014, YOUR_COMPANY_NAME | |
# | |
# All rights reserved - Do Not Redistribute | |
# | |
######### create SWAP for micro instance of AWS EC2 ########## | |
bash 'create swapfile' do | |
user 'root' | |
code <<-EOC | |
dd if=/dev/zero of=/swap.img bs=1M count=2048 && | |
chmod 600 /swap.img | |
mkswap /swap.img | |
EOC | |
only_if { "test ! -f /swap.img -a `cat /proc/swaps | wc -l` -eq 1" } | |
end | |
mount '/dev/null' do # swap file entry for fstab | |
action :enable # cannot mount; only add to fstab | |
device '/swap.img' | |
fstype 'swap' | |
end | |
bash 'activate swap' do | |
code 'swapon -ae' | |
only_if "test `cat /proc/swaps | wc -l` -eq 1" | |
end | |
############## nginx ############## | |
package "nginx" do | |
action :install | |
end | |
############## php ############## | |
package "php" do | |
action :install | |
end | |
package "php-fpm" do | |
action :install | |
end | |
package "php-mbstring" do | |
action :install | |
end | |
package "php-mysql" do | |
action :install | |
end | |
package "php-xml" do | |
action :install | |
end | |
package "php-gd" do | |
action :install | |
end | |
############## mysql ############## | |
package "mysql" do | |
action :install | |
end |
続いて、recipe[swap_scale-org]です。
# | |
# Cookbook Name:: swp_scale-org | |
# Recipe:: default | |
# | |
# Copyright 2014, YOUR_COMPANY_NAME | |
# | |
# All rights reserved - Do Not Redistribute | |
# | |
############## s3fs install ########### | |
package "gcc" do | |
action :install | |
end | |
package "libstdc++-devel" do | |
action :install | |
end | |
package "gcc-c++" do | |
action :install | |
end | |
package "fuse" do | |
action :install | |
end | |
package "fuse-devel" do | |
action :install | |
end | |
package "curl-devel" do | |
action :install | |
end | |
package "libxml2-devel" do | |
action :install | |
end | |
package "openssl-devel" do | |
action :install | |
end | |
package "mailcap" do | |
action :install | |
end | |
# install s3fs | |
bash "install s3fs" do | |
user 'root' | |
cwd "/home/#{node['userinfo']['username']}" | |
environment "HOME" => "/home/#{node['userinfo']['username']}" | |
code <<-EOH | |
wget -O - "http://s3fs.googlecode.com/files/s3fs-#{node['s3fs']['version']}.tar.gz" | tar xzf - | |
cd s3fs-#{node['s3fs']['version']}/ | |
./configure --prefix=/usr | |
make | |
make install | |
touch /etc/passwd-s3fs | |
echo #{node['userinfo']['accessley_id']}:#{node['userinfo']['secret-accesskey_id']} > /etc/passwd-s3fs | |
chmod 600 /etc/passwd-s3fs | |
echo s3fs smartwp:/manage/uploads-st /home/#{node['userinfo']['username']}/Dropbox/SmartWP/demo00/html-staging/wp-content/uploads -o allow_other -o nonempty >> /etc/rc.local | |
echo s3fs smartwp:/manage/uploads /home/#{node['userinfo']['username']}/Dropbox/SmartWP/demo00/html-production/wp-content/uploads -o allow_other -o nonempty >> /etc/rc.local | |
echo s3fs smartwp:/manage/shakesoul_uploads-st /home/#{node['userinfo']['username']}/Dropbox/SmartWP/shakesoul.net/html-staging/wp-content/uploads -o allow_other -o nonempty >> /etc/rc.local | |
echo s3fs smartwp:/manage/shakesoul_uploads-pr /home/#{node['userinfo']['username']}/Dropbox/SmartWP/shakesoul.net/html-production/wp-content/uploads -o allow_other -o nonempty >> /etc/rc.local | |
echo s3fs smartwp:/manage/hirofukami_uploads-st /home/#{node['userinfo']['username']}/Dropbox/SmartWP/hirofukami.com/html-staging/wp-content/uploads -o allow_other -o nonempty >> /etc/rc.local | |
echo s3fs smartwp:/manage/hirofukami_uploads-pr /home/#{node['userinfo']['username']}/Dropbox/SmartWP/hirofukami.com/html-production/wp-content/uploads -o allow_other -o nonempty >> /etc/rc.local | |
EOH | |
not_if {::File.exists?("/etc/passwd-s3fs")} | |
end | |
############## nginx and php-fpm ################## | |
template "nginx.conf" do | |
path "/etc/nginx/nginx.conf" | |
source "nginx.conf.erb" | |
owner "root" | |
group "root" | |
mode 0644 | |
notifies :reload, 'service[nginx]' | |
end | |
template "nginx demo00.conf" do | |
path "/etc/nginx/conf.d/demo00.conf" | |
source "nginx-demo00.conf.erb" | |
owner "root" | |
group "root" | |
mode 0644 | |
notifies :reload, 'service[nginx]' | |
end | |
template "nginx hirofukami.conf" do | |
path "/etc/nginx/conf.d/hirofukami.conf" | |
source "nginx-hirofukami.conf.erb" | |
owner "root" | |
group "root" | |
mode 0644 | |
notifies :reload, 'service[nginx]' | |
end | |
template "nginx shakesoul.conf" do | |
path "/etc/nginx/conf.d/shakesoul.conf" | |
source "nginx-shakesoul.conf.erb" | |
owner "root" | |
group "root" | |
mode 0644 | |
notifies :reload, 'service[nginx]' | |
end | |
template "php.ini" do | |
path "/etc/php.ini" | |
source "php.ini.erb" | |
owner "root" | |
group "root" | |
mode 0644 | |
notifies :reload, 'service[php-fpm]' | |
end | |
template "www.conf" do | |
path "/etc/php-fpm.d/www.conf" | |
source "php-fpm-www.conf.erb" | |
owner "root" | |
group "root" | |
mode 0644 | |
notifies :reload, 'service[php-fpm]' | |
end | |
directory "/var/lib/nginx" do | |
owner node['userinfo']['username'] | |
group "root" | |
action :create | |
end | |
directory "/var/lib/nginx/tmp" do | |
owner node['userinfo']['username'] | |
group "root" | |
action :create | |
end | |
############## Dropbox and WordPress ############## | |
# install Dropbox Linux | |
bash "install dropbox" do | |
user node['userinfo']['username'] | |
group node['userinfo']['username'] | |
cwd "/home/#{node['userinfo']['username']}" | |
environment "HOME" => "/home/#{node['userinfo']['username']}" | |
code <<-EOH | |
wget -O - "https://www.dropbox.com/download?plat=lnx.x86_64" | tar xzf - | |
mkdir ~/bin | |
cd ~/bin | |
wget -O ~/bin/dropbox https://www.dropbox.com/download?dl=packages/dropbox.py | |
chmod a+x dropbox | |
EOH | |
not_if {::File.exists?("/home/#{node['userinfo']['username']}/.dropbox")} | |
end | |
# dropbox start | |
template "/etc/init.d/dropbox" do | |
path "/etc/init.d/dropbox" | |
source "dropbox-initd.erb" | |
owner "root" | |
group "root" | |
mode 0755 | |
notifies :reload, 'service[dropbox]' | |
end | |
service "dropbox" do | |
supports :start => true, :stop => true | |
action [:enable, :start] | |
end | |
############# Last process start ############### | |
service "nginx" do | |
supports :status => true, :restart => true, :reload => true | |
action [:enable, :start] | |
end | |
service "php-fpm" do | |
supports :status => true, :restart => true, :reload => true | |
action [:enable, :start] | |
end |
これを nodes/[hostname].json で、
{ | |
"userinfo" : { | |
"username" : [your username], | |
"accessley_id" : [your accesskey_id], | |
"secret-accesskey_id" : [your secret-accesskey_id] | |
}, | |
"s3fs" : { | |
"version" : "1.74" | |
}, | |
"run_list":[ | |
"yum::epel", | |
"recipe[swp_setup]", | |
"recipe[swp_scale-org]" | |
] | |
} |
のように書いて適用させています。
こんな感じで、Webサーバとしては nginx + php-fpm、それに Dropbox linux と s3fs を使っているのがお分かりかと思います。 今後、ここで読み込んでいるテンプレートの nginx のコンフィグとかなんかも公開しようかなと思っています。
色々やっている方とディスカッションしてみたいので、違うやり方しているよとかこっちのほうが良いよみたいなのがあればフィードバックください〜
あと、Chef 学びたいとかスケーラブルなサーバ環境つくりたいとかもあれば相談いただければです。