Railsアプリをrbenv nginx unicornで運用するためのVPSのセットアップ

それぞれのバージョンはCentOS5.5 Rails 3.1.3。

PART1 サーバー設定


■rootパスワードの変更
ssh root@123.456.7.89
パスワード入力してログイン
[root@localhost ~]$
sudo passwd
Enter new UNIX password 新しいパスワードを入力
Retype new UNIX password 新しいパスワードを入力

■サーバーの設定
参考:ウェブ開発者のための、1時間でできるLAMP環境構築術(CentOS編) - さくらインターネット創業日記

アップデート
sudo yum update -y
アップグレードする場合は
yum upgrade -y

開発ツールのインストール
これをしておくとgccなどのパッケージを個別にインストールする手間が省ける。
sudo yum groupinstall 'Development Tools'

■タイムゾーン設定
sudo vi /etc/sysconfig/clock
ZONE="America/New_York"
UTC=true
ARC=false

clock ファイルを修正
ZONEに /usr/share/zoneinfo/ から希望するタイムゾーンを設定する。 ※UTCに設定する場合
ZONE="UTC"
UTC=true
ARC=false

localtimeの修正
sudo rm -f /etc/localtime
sudo cp -p /usr/share/zoneinfo/UTC /etc/localtime

確認
date
2012年 5月 27日 日曜日 05:08:41 UTC

■ロケールを設定
sudo vi /etc/sysconfig/i18n
LANG=ja_JP.UTF-8
LC_ALL=ja_JP.UTF-8
再度ログインすると反映される。

PART2 ユーザー設定


■Railsアプリの実行ユーザー、gitリポジトリのユーザーを作成
git: gitリポジトリ用のユーザー
deployer: Railsアプリ実行ユーザー
の2つを作成し、デプロイはgit/app -> deployer/public_html/appにcloneする。
sudo /usr/sbin/adduser git
sudo /usr/sbin/adduser deployer

各ユーザーのパスワードを変更
sudo passwd git
sudo passwd deployer

Railsアプリの実行ユーザーユーザーをwheelグループに変更して、wheelグループがsudoできるよう変更。
/usr/sbin/usermod -a -G wheel deployer
sudo /usr/sbin/visudo
## Allows people in group wheel to run all commands
# %wheel ALL=(ALL) ALL
をコメントをはずして
## Allows people in group wheel to run all commands
%wheel ALL=(ALL) ALL

■SSH公開鍵認証の設定
SSH公開鍵の作成
ローカルマシン上で
ssh-keygen

SSH公開鍵をサーバにコピー
scp ~/.ssh/id_rsa.pub deployer@123.456.7.89:
mkdir ~deployer/.ssh
mv ~deployer/id_rsa.pub ~deployer/.ssh/authorized_keys

本番サーバーでも、gitリポジトリからRailsアプリのディレクトリへSSHでgit cloneする際に鍵認証が必要になるので、本番サーバーでも同様にdeployerの公開鍵を作成し~git/.ssh/authorized_keysへ追記する。
これをしないとデプロイで
Permission denied (publickey,gssapi-with-mic).
みたいになって悩むハメになる。

ファイルの所有権、パーミッションなどの変更
Rails実行ユーザー
chown -R deployer:wheel ~deployer/.ssh
chmod 700 ~deployer/.ssh
chmod 600 ~deployer/.ssh/authorized_keys

gitユーザー
chown -R git:git ~git/.ssh
chmod 700 ~git/.ssh
chmod 600 ~git/.ssh/authorized_keys

SSHの設定を変更。SSHポート番号や、許可ユーザーを設定
sudo vi /etc/ssh/sshd_config
Port 20000
PermitRootLogin no
UsePAM no
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
RhostsRSAAuthentication no
PermitEmptyPasswords no
PasswordAuthentication no
ChallengeResponseAuthentication no
AllowUsers deployer git
に変更

SSHをリロードして反映。
sudo /etc/init.d/sshd reload

公開鍵認証をテスト
ssh -p 20000 deployer@123.456.7.89
でログインできればOK。

PART3 iptables


現在の設定を確認
sudo /sbin/iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

現在の設定をクリア
sudo /sbin/iptables -F

新規ルールのファイルを作成
sudo vi /etc/iptables.up.rules
*filter

# Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT


# Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT


# Allows all outbound traffic
# You can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT


# Allows HTTP and HTTPS connections from anywhere (the normal ports for websites)
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

# Allows SSH connections
#
# THE -dport NUMBER IS THE SAME ONE YOU SET UP IN THE SSHD_CONFIG FILE
#
-A INPUT -p tcp -m state --state NEW --dport 20000 -j ACCEPT


# Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT


# log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7


# Reject all other inbound - default deny unless explicitly allowed policy
-A INPUT -j REJECT
-A FORWARD -j REJECT

#MySQL
#-P INPUT ACCEPT
-A INPUT -p tcp --dport 3306 -j DROP

# FTP for backup to another sever
-A INPUT -p tcp --dport 21 -j ACCEPT

COMMIT

このファイルを適用
sudo /sbin/iptables-restore < /etc/iptables.up.rules

適用されたか確認
sudo /sbin/iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere
REJECT all -- anywhere 127.0.0.0/8 reject-with icmp-port-unreachable
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:https
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:20000
ACCEPT icmp -- anywhere anywhere icmp echo-request
LOG all -- anywhere anywhere limit: avg 5/min burst 5 LOG level debug prefix `iptables denied: '
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere

保存
/sbin/service iptables save
ファイアウォールのルールを /etc/sysconfig/iptables に保存中[ OK ]

後日設定を変更する場合は同様に
編集
sudo vi /etc/iptables.up.rules

フラッシュ
sudo /sbin/iptables -F

適用
sudo /sbin/iptables-restore < /etc/iptables.up.rules

保存
sudo /sbin/service iptables save

SSHをリロード
sudo /etc/init.d/sshd reload

念のため、SSH接続できるか別のターミナルを開いて確認しておく。
この時点でログインできれば完了。

PART4 MySQLの設定


■MySQLのインストール
インストールされているかチェック
yum list mysql*
インストールは
sudo yum install mysql-server
sudo yum install mysql-devel
起動
sudo /etc/init.d/mysqld start
rootパスワードを設定
mysqladmin -u root password 'new-password'

■MySQLの文字コード設定
sudo vi /etc/my.cnf
[client]
default-character-set=utf8

[mysqld]
default-character-set=utf8

MySQLを再起動して反映
sudo /etc/init.d/mysqld restart

反映されたか確認
mysql -u root -p
mysql> show variables like 'character_set%';

#以下でOK
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

mysql-develをインストール
sudo yum install mysql-devel

RailsアプリのDB、MySQLユーザー作成と権限設定
mysql >GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, LOCK TABLES ON *.* TO 'deployer'@'localhost' IDENTIFIED BY 'password';
exit

ユーザーのテスト
mysql -u deployer -p
パスワード入力
>mysql

DBの作成
mysql> create database rails_app;

■MySQLの自動起動
sudo /sbin/chkconfig mysqld on
sudo /sbin/chkconfig --list mysqld
mysqld 0:off 1:off 2:on 3:on 4:on 5:on 6:off

■MySQLのタイムゾーン設定
現在の設定を確認
SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM | SYSTEM |
+--------------------+---------------------+
この場合はシステムと同期するようになっている。
システムのタイムゾーンなどを詳細に表示。
mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | UTC |
| time_zone | SYSTEM |
+------------------+--------+
MySQLのシステムのタイムゾーンは、起動した際のタイムゾーンが設定されるので、システムのタイムゾーンを変更した場合はMySQLを再起動する。
sudo /etc/init.d/mysqld restart


PART5 git、nginx、rubyのセットアップ


■gitのインストール
リポジトリを追加してインストール
sudo rpm -Uvh http://repo.webtatic.com/yum/centos/5/latest.rpm
sudo yum install --enablerepo=webtatic git-all

■nginxのインストール
sudo yum install nginx
sudo /etc/init.d/nginx start
IPアドレスでアクセスして表示されれば完了。

■nginx.confの設定
sudo vi /etc/nginx/nginx.conf
user    nginx;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 1024; # increase if you have lots of clients
# accept_mutex off; # "on" if nginx worker_processes > 1
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
# tcp_nopush on;
# tcp_nodelay off;

upstream unicorn {
server unix:/tmp/unicorn.rails_app.sock fail_timeout=0;
}

server {
listen 80 default deferred;
# server_name example.com;
root /home/deployer/public_html/rails_app/current/public;

location ~* ^/assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}

try_files $uri/index.html $uri @unicorn;
location @unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}

error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
}
再起動して反映
sudo /etc/init.d/nginx restart


PART6 デプロイ


■deploy.rbの設定
require "bundler/capistrano"

# rbenv =========================================================
set :default_environment, {
'RBENV_ROOT' => '/usr/local/rbenv',
'PATH' => "/usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH"
}
# delayed_job =========================================================
# Wiki: https://github.com/collectiveidea/delayed_job/wiki/Rails-3-and-Capistrano
require "delayed/recipes"
after "deploy:stop", "delayed_job:stop"
after "deploy:start", "delayed_job:start"
after "deploy:restart", "delayed_job:restart"

# whenever ==============================================================
set :whenever_command, "bundle exec whenever"
require "whenever/capistrano"

# Rails app ============================================================
server "123.456.78.90" , :web, :app, :db, primary: true
# ※使い回す値は set :name, value で変数にしておく
set :application, "app_dir_name"
set :user, "rails_run_user"
set :runner, "rails_run_user"
set :deploy_to, "/home/#{ user }/public_html/#{ application }"
set :deploy_via, :export
set :use_sudo, false
set :rails_env, "production"
# bundlerで除外するグループ ※通常は不要
set :bundle_without, [:darwin, :development, :test]
set :scm, :git
set :brannch, "master"
set :repository, "ssh://git@123.456.78.90:20000/home/git/#{ application }"

ssh_options[:port] = 20000
ssh_options[:forward_agent] = false
ssh_options[:paranoid] = false

namespace :deploy do
desc "Start unicorn"
task :start, :roles => :app do
run "cd #{ current_path }; bundle exec unicorn -c #{ current_path }/config/unicorn.rb -E #{ rails_env } -D"
end

task :restart, :roles => :app do
run "kill -s USR2 `cat #{ current_path }/tmp/pids/unicorn.pid`"
end

task :stop, :roles => :app do
run "kill -s QUIT `cat #{ current_path }/tmp/pids/unicorn.pid`"
end
end

■デプロイ
git push origin master
cap deploy
エラーがでなければRailsアプリが動くはず。その後DNSネームサーバをドメイン管理元に設定。
(今回はGMOクラウドVPSだったので、ns.namedserver.net ns2.namedserver.net)
これで一通り公開までは完了となる。

PART7 バックアップ


wheneverとbackupのgemを利用して、cronで定期的にMySQLをbackupでdumpして保存し外部サーバにrsyncで保存する。
■wheneverのセットアップ
RailsでCronを簡単にするプラグインwheneverを参考にインストール

■backupのセットアップ
RailsアプリのMySQL、PostgreSQLを自動バックアップを参考にローカルにバックアップしたディレクトリをrsyncで外部サーバにバックアップする。
FTPはポート開けたりが面倒。
posted by digital-squad at 2012年07月04日 19時46分 | Comment(0) | TrackBack(0) | Web関連ニュース
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック