Ruby on RailsでDev環境は使ったことあるけど、test・prod環境を考慮した環境構築をしたことがない人にお勧めの内容です。
##サーバー構成図
##サーバーの役割
###リバースプロキシサーバー(ホスト名:rp01)
- ロードバランサ機能を使ってWEBサーバ二台に処理を振り分け、アクセスを1台のサーバーに集中させない
- WEBサーバーを外部から隠せることでセキュリティ面の向上
###WEBサーバー(web01、web02)
- webサーバーを2台用意することでアクセスが1つのサーバーに集中しないため、レスポンスを早くできる
###マスターDBサーバー(db01m)
- DB内容をもう1台のDBサーバー(スレーブ)へリアルタイムにコピーし、障害でマスターが停止したときはスレーブに切り替える
###スレーブDBサーバー(db01s)
- 読み込み専用のサーバー。書き込みをしない分レスポンスが早くなる
- マスターの内容を常にコピーする(レプリケーションという)
###開発環境(dev01)
- 開発はこの環境だけで行い、完成物をWEBサーバーにアップロードする(デプロイという)
###DNS(rp01)
- 各サーバーのホスト名を管理するDNS。リバースプロキシと同じサーバー内で動作させる
##準備
- VPS等でサーバーを5台借りておく(rp01、web01、web02、db01m、db01s)
- リバースプロキシはグローバルIP必須
- 開発環境(手持ちにMacやUnix環境がないならvpsで借りる)
##サーバー仕様
###WEBサーバー・リバースプロキシ
- Apache/2.2.15 (Unix)
###データベース
- MySQL Server 5.1.71
###DNS
- mydns 1.2.8.31
###Ruby
- ruby-2.0.0-p353
###Ruby on Rails
- Rails 4.0.2
##全サーバーに共通するセットアップ
###ログインユーザーのセキュリティ設定編
初期インストールされたパッケージをアップデート
$ sudo yum update
ログインユーザー(deploy01)の作成
$ useradd deploy01
$ passwd deploy01
deploy01をsudo権限が使えるグループに所属させる
$ usermod –G wheel deploy01
wheelグループ以外はsudo権限を与えない設定。
下記行のコメントを外す。
#auth required pam_wheel.so use_uid
wheelグループのみrootユーザーにログイン可能にする。
下記行を追加
SU_WHEEL_ONLY yes
wheelグループのユーザーのみ sudoコマンドを実行許可。
下記コマンドを実行する。
$ visudo
すると、設定ファイルが開くので下記行のコメントを外す
# %wheel ALL=(ALL) ALL
rootユーザーでのsshログインを禁止する。
下記行をコメント化する
PermitRootLogin no
SSHのポートを狙った攻撃を回避するため、ポート番号を変更する。
Portの後ろに変更したいポート番号を入れる
Port 3243
SSHの変更を有効にするため、SSHを再起動するコマンドを実行
$ /etc/init.d/sshd restart
###ファイアウォール編
下記コマンドを実行するとファイアウォールの設定情報を確認できる
$ /sbin/iptables -L --line-number
Chain INPUT (policy ACCEPT)
num target prot opt source destination
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
上記と同じ表示の場合、すべての通信を許可しているためセキュリティ上問題がある。
各サーバーごとにファイアウォールを設定する。
リバースプロキシ(rp01)のファイアウォール設定
外部パケットから入ってくるパケットのうち
http、https、ssh(ポートは3824)、DNSのみ許可する。
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
## allow well-known port ##
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
## allow port(SSH,http,https,DNS) ##
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3824 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 53 -j ACCEPT
COMMIT
WEBサーバー(web01、web02)の設定
※IPアドレスをホスト名に置き換えてます。
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#------------------------------------------------------
# ping、ループバックアドレスを許可
#------------------------------------------------------
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
#------------------------------------------------------
# RPのみ、webサーバーへの通信を許可
# 80は本番環境(prod)のサイト表示
# 8000はテスト環境(test)のサイト表示
#------------------------------------------------------
-A INPUT -s rp01 -p tcp --dport 80 -j ACCEPT
-A INPUT -s rp01 -p tcp --dport 8000 -j ACCEPT
#------------------------------------------------------
# SSHを許可
#------------------------------------------------------
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3843 -j ACCEPT
COMMIT
DBサーバー(db01m)の設定
※IPアドレスをホスト名に置き換えてます。
*filter
#------------------------------------------------------
# メンテナンス可能リスト
# web01
# web02
# db01s
#------------------------------------------------------
#------------------------------------------------------
# ポリシー:全ての送受信パケットを破棄。必要な用途に応じて開けていく。
#------------------------------------------------------
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
#------------------------------------------------------
# pingとループバックアドレス(自分自身のIP)からの送受信を許可
#------------------------------------------------------
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A OUTPUT -p icmp -j ACCEPT
#------------------------------------------------------
# 内部からのDNS送信を許可
#------------------------------------------------------
-A OUTPUT -m state --state NEW -m udp -p udp --dport 53 -j ACCEPT
#------------------------------------------------------
# 内部からのhttp送信を許可(yum等)
#------------------------------------------------------
-A OUTPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
#------------------------------------------------------
# メンテナンスのみSSH接続を許可
#------------------------------------------------------
-A INPUT -s web01 -p tcp --dport 3843 -j ACCEPT
-A OUTPUT -d web01 -p tcp --sport 3843 -j ACCEPT
-A INPUT -s web02 -p tcp --dport 3843 -j ACCEPT
-A OUTPUT -d web02 -p tcp --sport 3843 -j ACCEPT
-A INPUT -s db01s -p tcp --dport 3843 -j ACCEPT
-A OUTPUT -d db01s -p tcp --sport 3843 -j ACCEPT
#------------------------------------------------------
# メンテナンスのみMySQL接続を許可
#------------------------------------------------------
-A INPUT -s web01 -p tcp --dport 3306 -j ACCEPT
-A OUTPUT -d web01 -p tcp --sport 3306 -j ACCEPT
-A INPUT -s web02 -p tcp --dport 3306 -j ACCEPT
-A OUTPUT -d web02 -p tcp --sport 3306 -j ACCEPT
-A INPUT -s db01s -p tcp --dport 3306 -j ACCEPT
-A OUTPUT -d db01s -p tcp --sport 3306 -j ACCEPT
#------------------------------------------------------
# 接続済みパケットの送受信を許可
#------------------------------------------------------
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
COMMIT
DBサーバー(db01s)の設定
※IPアドレスをホスト名に置き換えてます。
*filter
#------------------------------------------------------
# メンテナンス可能リスト
# web01
# web02
# db01m
#------------------------------------------------------
#------------------------------------------------------
# ポリシー:全ての送受信パケットを破棄。必要な用途に応じて開けていく。
#------------------------------------------------------
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
#------------------------------------------------------
# pingとループバックアドレス(自分自身のIP)からの送受信を許可
#------------------------------------------------------
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A OUTPUT -p icmp -j ACCEPT
#------------------------------------------------------
# 内部からのDNS送信を許可
#------------------------------------------------------
-A OUTPUT -m state --state NEW -m udp -p udp --dport 53 -j ACCEPT
#------------------------------------------------------
# 内部からのhttp送信を許可(yum等)
#------------------------------------------------------
-A OUTPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
#------------------------------------------------------
# メンテナンスのみSSH接続を許可
#------------------------------------------------------
-A INPUT -s web01 -p tcp --dport 3843 -j ACCEPT
-A OUTPUT -d web01 -p tcp --sport 3843 -j ACCEPT
-A INPUT -s web02 -p tcp --dport 3843 -j ACCEPT
-A OUTPUT -d web02 -p tcp --sport 3843 -j ACCEPT
-A INPUT -s db01m -p tcp --dport 3843 -j ACCEPT
-A OUTPUT -d db01m -p tcp --sport 3843 -j ACCEPT
#------------------------------------------------------
# メンテナンスのみMySQL接続を許可
#------------------------------------------------------
-A INPUT -s web01 -p tcp --dport 3306 -j ACCEPT
-A OUTPUT -d web01 -p tcp --sport 3306 -j ACCEPT
-A INPUT -s web02 -p tcp --dport 3306 -j ACCEPT
-A OUTPUT -d web02 -p tcp --sport 3306 -j ACCEPT
-A INPUT -s db01m -p tcp --dport 3306 -j ACCEPT
-A OUTPUT -d db01m -p tcp --sport 3306 -j ACCEPT
#------------------------------------------------------
# 接続済みパケットの送受信を許可
#------------------------------------------------------
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
COMMIT
すべての設定を書き終えたらiptablesを再起動してファイアウォールを有効化
$ service iptables restart
ファイアウォールの設定は以上。
開発環境のファイアウォールは任意で設定してください。
MySQL(データベースサーバー)のインストール
Mysqlのパッケージについて
mysqlのパッケージには大きく分けて3種類ある
- mysql:client用
- mysql-server:server用
- mysql-devel:アプリケーションとの連携用
そのため、用途によってはインストールするパッケージを絞ることが可能
terminalからmysqlに接続する
- mysql
railsやmydns等のアプリケーションからmysqlサーバーに接続
- mysql、mysql-devel
データベース運用
- mysql-server
今回はサーバーごとにインストールするパッケージを変える
MySQLのインストール
rp01(DNSサーバー用として使う)
$ yum install mysql mysql-devel mysql-server
web01、web02(rails用にインストール)
$ yum install mysql mysql-devel
db01m、db01s(mysqlデータベース用)
$ yum install mysql mysql-server
mysqlの設定
以下をサーバー5台全てに設定する
mysqlの設定ファイルをバックアップする
$ sudo cp /etc/my.cnf /etc/my.cnf.org
MySQLの設定ファイルをバックアップ
$ sudo cp /etc/my.cnf /etc/my.cnf.org
MySQLの設定ファイルを下記のように設定
[mysqld]
character-set-server = utf8
skip-character-set-client-handshake
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
symbolic-links=0
innodb_buffer_pool_size = 512MB # サーバのメモリ70〜80%
innodb_log_file_size = 100MB # 100-500MB程度
innodb_flush_log_at_trx_commit = 2
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
rootのパスワード設定
$ sudo mysqladmin -u root password 'パスワード'
mysql-serverをインストールしている
rp01とdb01m、db02mのみMySQLの自動起動をONにする
$ sudo service mysqld start
$ sudo chkconfig mysqld on
MySQLにログインし、不要なユーザーとデータベースを削除する
$ mysql -u root -p ****
mysql > use mysql;
mysql > select user,password, host from user;
+------+-------------------------------------------+-------------------------+
| user | password | host |
+------+-------------------------------------------+-------------------------+
| root | *hogehogehogehogehogehogehogehogehogehoge | localhost |
| root | | hogehogehogehogeh.ne.jp |
| root | | 127.0.0.1 |
| | | localhost |
| | | hogehogehogehogeh.ne.jp |
+------+-------------------------------------------+-------------------------+
mysql > DELETE FROM user WHERE user = '' OR ( user = 'root' AND host != 'localhost' );
Query OK, 4 rows affected (0.00 sec)
mysql > select user,password, host from user;
+------+-------------------------------------------+-----------+
| user | password | host |
+------+-------------------------------------------+-----------+
| root | *hogehogehogehogehogehogehogehogehogehoge | localhost |
+------+-------------------------------------------+-----------+
1 row in set (0.00 sec)
続いて、不要なデータベースを削除
mysql > show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| test |
+--------------------+
3 rows in set (0.00 sec)
mysql> DROP DATABASE test;
Query OK, 0 rows affected (0.00 sec)
文字セットの確認
show variables like 'character_set%';
# ↓ のようになっていれば成功
+--------------------------+----------------------------+
| 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/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)
rails用のデータベースを作成
mysql > create database app;
mysql > create database app_test;
mysql > create database app_dev;
mydns(DNSサーバー)のインストール
mydnsとは?
MySQLのデータベースを使って、ホスト名の管理ができる。
ホストを追加するときはinsert文を1つ打つだけで設定可能なので管理が楽。
インストールについて
MyDNSのインストールは任意。
SSH接続やiptables、apache設定でipを使わずホスト名を使いたい人は
設定してください。(この記事は全てホスト名になっています)
インストール方法
インストールはrp01で行います。
mydnsをダウンロードするためのリポジトリを追加
rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
mydnsパッケージのインストール
$ yum install mydns
$ yum install mydns-mysql
mysqlにログインし、mydns用データベースを作成
mysql > create database mydns;
ターミナルから下記コマンドを実行
$ mydns --create-tables | mysql -u root -p mydns
mysqlにログインし、mydns用のテーブルができているか確認
mysql > use mydns;
Database changed
mysql> show tables;
+-----------------+
| Tables_in_mydns |
+-----------------+
| rr |
| soa |
+-----------------+
mydns用のユーザーを作成する。
※データベースmydnsに対して、全ての権限を持ったユーザー(全てのホストからのアクセス許可)
GRANT ALL ON mydns.* TO 'mydns'@'%' IDENTIFIED BY 'mydns';
Query OK, 0 rows affected (0.01 sec)
DNSゾーンとレコードの作成
※ネットワークをxxx.localにする
※xxx.xxx.xxx.xxxはIPアドレスです
mysql> insert into soa (origin, ns) values ('local.', 'ns.local');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into rr (zone, name, type, data) values(1, 'web01', 'A', ‘xxx.xxx.xxx.xxx’);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into rr (zone, name, type, data) values(1, 'web02', 'A', 'xxx.xxx.xxx.xxx’);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into rr (zone, name, type, data) values(1, 'db01m', 'A', 'xxx.xxx.xxx.xxx’);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into rr (zone, name, type, data) values(1, 'db01s', 'A', 'xxx.xxx.xxx.xxx’);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into rr (zone, name, type, data) values(1, ‘rp01, 'A', 'xxx.xxx.xxx.xxx’);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into rr (zone, name, type, data) values(1, ‘dev01’, 'A', 'xxx.xxx.xxx.xxx’);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select * from rr;
+----+------+-------+------------------+-----+-------+------+
| id | zone | name | data | aux | ttl | type |
+----+------+-------+------------------+-----+-------+------+
| 1 | 1 | web01 | xxx.xxx.xxx.xxx | 0 | 86400 | A |
| 2 | 1 | web02 | xxx.xxx.xxx.xxx | 0 | 86400 | A |
| 3 | 1 | db01m | xxx.xxx.xxx.xxx | 0 | 86400 | A |
| 4 | 1 | db01s | xxx.xxx.xxx.xxx | 0 | 86400 | A |
| 5 | 1 | rp01 | xxx.xxx.xxx.xxx | 0 | 86400 | A |
| 6 | 1 | dev01 | xxx.xxx.xxx.xxx | 0 | 86400 | A |
+----+------+-------+------------------+-----+-------+------+
mysql > select * from soa;
+----+--------+----------+------+--------+---------+-------+--------+---------+-------+
| id | origin | ns | mbox | serial | refresh | retry | expire | minimum | ttl |
+----+--------+----------+------+--------+---------+-------+--------+---------+-------+
| 1 | local. | ns.local | | 1 | 28800 | 7200 | 604800 | 86400 | 86400 |
+----+--------+----------+------+--------+---------+-------+--------+---------+-------+
1 row in set (0.00 sec)
###DNSの設定とmydnsの起動
ホスト名で通信したいすべてのサーバーで下記を設定
xxx.xxx.xxx.xxxはrp01のグローバルIPアドレス
search local
nameserver xxx.xxx.xxx.xxx
mydnsを起動
$ service mydns start
設定したホスト名でpingが通るか確認
ping web01
##レプリケーションの設定
レプリケーションとは
データベースの内容を別のデータベースにリアルタイムで同期させる。
コピ元をマスター、コピー先をスレーブという。
レプリケーションの設定方法
マスターのdb01mのmy.cnfを下記のように設定
[mysqld]
log-bin=mysql-bin
server-id=1001
スレーブのdb01sにマスターに接続するmysqlユーザーを作成するため、
db01sのmysqlにログインして、下記を実行
※xxx.xxx.xxx.xxxはmasterのipアドレス
GRANT REPLICATION SLAVE ON *.* TO 'repl’@‘xxx.xxx.xxx.xxx’ IDENTIFIED BY 'slavepass';
スレーブのmy.cnfファイル内で以下の通り設定
[mysqld]
server-id=1002
マスター側のpositionを確認
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000002 | 379 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
それぞれの意味
File : バイナリログ名
Position : ファイル内のオフセット(現在位置)
Positionとファイル名をメモしておき、マスターのデータベースのテーブルをロックしておく
mysql > FLUSH TABLES WITH READ LOCK
マスターのデータベースのバックアップを取る
$ mysqldump -u root -p --all-databases --lock-all-tables > /tmp/dbdump.db
スレーブ側でSCPコマンドを使って、マスターのdbファイルを取得
$ scp -P sshのポート番号 deploy01@db01m :/tmp/dbdump.db /tmp/
スレーブのデータベースにマスターの内容を反映
# mysql -u root -p /tmp/dbdump.db
スレーブ側でマスター情報を登録
xxx.xxx.xxx.xxxにはマスターのipアドレスを入れる
mysql > CHANGE MASTER TO
MASTER_HOST=‘xxx.xxx.xxx.xxx’,
MASTER_USER='repl',
MASTER_PASSWORD='XXXXXX',
MASTER_LOG_FILE='mysql-bin.000002',
MASTER_LOG_POS=379;
レプリケーション開始するため、スレーブ側で下記コマンドを実行
mysql > START SLAVE;
レプリケーションが開始されているか確認
show slave status;
mysql> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: xxx.xxx.xxx.xxx
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 450
Relay_Log_File: mysqld-relay-bin.000003
Relay_Log_Pos: 251
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
下記を確認できればDBの同期が取れている
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Rubyのインストール
作業はweb01とweb02で行う
rootユーザーでインストールすると、root権限が必要なときがあるため
deploy01ユーザーにインストールを行う。(シングルインストール)
rvmを使ったRubyのインストール
rvmはRubyのバージョン管理を容易に行える。
コマンド1つでバージョンを切り替えたり、バージョンごとのインストールが可能
必要なパッケージのインストール
$ sudo yum -y install curl curl-devel gcc gcc-c++ httpd-devel readline-devel tk-devel make zlib-devel libffi-devel
rvmをインストール
$ bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer )
$ echo "source $HOME/.rvm/scripts/rvm" >> ~/.bash_profile
$ source ~/.bash_profile
Rubyのver 2.0.0をインストール
$ rvm install 2.0.0
RVMの設定確認
$ rvm list
=* ruby-2.0.0-p247 [ x86_64 ] #
railsの導入
railsのインストール(RDocのインストール部分で結構時間かかる)
$ gem install rails
RDocが不要な場合は下記でインストールする
$ gem install rails –no-ri –no-rdoc
passangerのインストールを行う
$ gem install passenger
$ passenger-install-apache2-module
インストール完了後、下記のような表示が出るのでコピー
LoadModule passenger_module /usr/lib64/ruby/gems/1.8/gems/passenger-4.0.19/buildout/apache2/mod_passenger.so
PassengerRoot /usr/lib64/ruby/gems/1.8/gems/passenger-4.0.19
PassengerDefaultRuby /usr/bin/ruby
passenger.confに上記設定とオプションを記入
# Passengerの基本設定
LoadModule passenger_module /usr/local/rvm/gems/ruby-2.0.0-p247@global/gems/passenger-4.0.18/buildout/apache2/mod_passenger.so
PassengerRoot /usr/local/rvm/gems/ruby-2.0.0-p247@global/gems/passenger-4.0.18
PassengerDefaultRuby /usr/local/rvm/wrappers/ruby-2.0.0-p247@global/ruby
# Passengerが追加するHTTPヘッダを削除するための設定
Header always unset "X-Powered-By"
Header always unset "X-Rack-Cache"
Header always unset "X-Content-Digest"
Header always unset "X-Runtime"
# 必要に応じてPassengerのチューニングのための設定を追加
PassengerMaxPoolSize 20
PassengerMaxInstancesPerApp 4
PassengerPoolIdleTime 3600
PassengerHighPerformance on
PassengerStatThrottleRate 10
RailsSpawnMethod smart
RailsAppSpawnerIdleTime 86400
PassengerMaxPreloaderIdleTime 0
デプロイ用のディレクトリを作成
test環境とprod環境の2つを用意する
$ sudo mkdir /var/www/deploy01/
$ sudo chown deploy01:deploy01 /var/www/deploy01/
$ chmod 775 /var/www/deploy01/
$ mkdir /var/www/deploy01/prod/
$ mkdir /var/www/deploy01/test/
開発環境側の設定
開発環境側(dev01)はappというアプリが出来ている状況とします。
database.ymlにslaveとmasterのdb情報を設定する
development:
adapter: mysql2
encoding: utf8
database: app_dev
pool: 5
username: root
password: xxxx
host: localhost
test_slave_database:
adapter: mysql2
encoding: utf8
database: app_test
pool: 5
username: root
password: xxx
host: db01s
test:
adapter: mysql2
encoding: utf8
database: app_test
pool: 5
username: root
password: xxx
host: db01m
production_slave_database:
adapter: mysql2
encoding: utf8
database: app
pool: 5
username: root
password: xxx
host: db01s
production:
adapter: mysql2
encoding: utf8
database: app
pool: 5
username: root
password: xxx
host: db01m
Gemfileに下記パッケージを記載する
gem 'multi_db'
デプロイツールのインストール
web01とweb02にgitをインストール
$ sudo yum install git
appアプリ配下で下記を実行
$ gem install capistrano
インストールが完了したらcapifyコマンドを実行
capify .
> [add] writing './Capfile'
> [add] writing './config/deploy.rb'
> [done] capified!
test環境とprod環境用のCapistrano設定ファイルを作成
$ mkdir config/deploy
$ touch config/deploy/test.rb
$ touch config/deploy/production.rb
共通のデプロイ情報をdeploy.rbに記入
ipアドレスをホスト名に変えてます。
# -*- coding: utf-8 -*-
set :default_stage, "production"
# 複数環境にデプロイできるようにする
require "capistrano/ext/multistage"
# capistranoの出力をカラーに
require 'capistrano_colors'
# cap deploy時に自動で bundle installを実行
require "bundler/capistrano"
# RVM
require "rvm/capistrano"
set :rvm_ruby_string, ‘2.0.0-p353’
set :rvm_type, :user
# gitリポジトリの設定
#### gitリポジトリをセット ####
set :repository, “gitのリポジトリ”
set :scm, :git
set :deploy_via, :remote_cache
# SSH
set :use_sudo, false
set :default_run_options, :pty => true
ssh_options[:port] = 22
ssh_options[:forward_agent] = true
set :normalize_asset_timestamps, false
# 過去のデプロイしたフォルダを履歴として保持する数
set :keep_releases, 5
# デプロイ先のサーバの設定
server “web01:3843", :app, :web, :db, :primary => true
server “web02:3843", :app, :web, :db, :primary => true
# bundle install条件
set :bundle_flags, "--no-deployment --without test development"
# SSH
set :user, "deploy01"
set :user_group, "deploy01"
set :password, “SSHのログインパスワード”
# RVM
set :rvm_path, '/home/deploy01/.rvm/'
set :rvm_bin_path, “app/bin"
set :rvm_lib_path, “app/lib"
# assets:precompile
namespace :assets do
task :precompile, :roles => :web do
run "cd #{current_path} && RAILS_ENV=#{rails_env} bundle exec rake assets:precompile"
end
end
# メンテナンスモード
namespace :maintenance do
desc "Maintenance start"
task :on, :roles => :web do
on_rollback { run "rm #{current_path}/tmp/maintenance.yml" }
page = File.read("config/maintenance.yml")
put page, "#{current_path}/tmp/maintenance.yml", :mode => 0644
end
desc "Maintenance stop"
task :off, :roles => :web do
run "rm #{release_path}/tmp/maintenance.yml"
end
end
namespace :deploy do
# Passengerの実行ユーザー/Groupをセット
task :set_file_process_owner do
sudo "chown -R #{user}:#{user_group} #{deploy_to}"
end
#### sitemap_generatorを使ってない場合は削除 ####
desc "sitemapの更新"
task :refresh_sitemaps do
run "cd #{latest_release} && RAILS_ENV=#{rails_env} bundle exec rake sitemap:refresh"
end
# 本番サーバでPassenger以外を使っている場合は適宜変更して下さい。
desc "Passenger用に起動/停止タスクを変更"
task :restart, :roles => :web do
run "touch #{current_path}/tmp/restart.txt"
end
# page_cacheを使用していない場合は不要
desc "キャッシュhtmlの削除(deploy中に不完全なhtmlを生成しないための対策)"
task :remove_caches, :roles => :web do
run "rm -rf #{current_path}/public/index.html"
end
#### Wheneverを使っていない場合は削除
desc "wheneverのアップデート"
task :whenever_update do
run "cd #{latest_release} && RAILS_ENV=#{rails_env} bundle exec whenever --update-crontab #{application} -f config/schedule_#{rails_env}.rb"
end
end
before :deploy, "deploy:set_file_process_owner"
prod用の設定
#### デプロイ先のフォルダを設定 ####
set :deploy_to, "/var/www/deploy01/prod/app”
set :rails_env, "production"
# deploy ==========================
after :deploy, "maintenance:on"
after :deploy, "assets:precompile"
after :deploy, "deploy:migrate"
after :deploy, "deploy:restart"
after :deploy, "deploy:remove_caches"
after :deploy, "maintenance:off"
after :deploy, "deploy:cleanup"
test用の設定
#### デプロイ先のフォルダを設定 ####
set :deploy_to, "/var/www/deploy01/test/app”
set :rails_env, “test”
# deploy ==========================
after :deploy, "assets:precompile"
after :deploy, "deploy:migrate"
after :deploy, "deploy:restart"
after :deploy, "deploy:remove_caches"
after :deploy, "deploy:cleanup"
メンテナンス画面表示用にconfig/maintenance.ymlを追加。
---
reason: メンテナンス中です
allowed_paths:
- ^/help
- ^/contact_us
allowed_ips:
- 127.0.0.1
- 192.168.0.0/24
リポジトリへのパスフレーズ入力を省略するため、ssh-agentの追加をする
※鍵にはgitリポジトリの秘密鍵を指定
# ssh-agent zsh
# ssh-agent ~/.ssh/id_rsa
デプロイができるかのテスト(初回のみ)
cap deploy:check
デプロイコマンド一覧
セットアップ(初回に実行)
$ cap production deploy:setup
$ cap test deploy:setup
デプロイを実行
$ cap production deploy:cold
$ cap test deploy:cold
以前の状態に戻す
$ cap production deploy:rollback
$ cap test deploy:rollback
以前の状態のソースコードを削除
$ cap production deploy:cleanup
$ cap test deploy:cleanup
Apacheの設定
deployが完了したらweb01とweb02のhttpd.confにrailsアプリの設定を行う
xxx.xxx.xxx.xxxにはweb01ならweb01のIPを記入
# prod
<VirtualHost *:80>
ServerName xxx.xxx.xxx.xxx
DocumentRoot /var/www/deploy01/prod/app/current/public/
ErrorLog /var/log/httpd/prod_app_error.log
CustomLog /var/log/httpd/prod_app_access.log combined
<Directory "/var/www/deploy01/prod/app/current/public">
Options -MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
# test
<VirtualHost *:8000>
RailsEnv test
ServerName xxx.xxx.xxx.xxx
DocumentRoot /var/www/deploy01/test/app/current/public/
ErrorLog /var/log/httpd/test_app_error.log
CustomLog /var/log/httpd/test_app_access.log combined
<Directory "/var/www/deploy01/test/app/current/public">
Options -MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
serverNameでvirtualhostを分ける設定をONにするため
下記行のコメントを外す
#NameVirtualHost *:80
web01とweb02のapacheを再起動
$ sudo service httpd restart
iptablesを停止して、testとprod環境にアクセスできるか確認
http://xxx.xxx.xxx.xxx:80/
http://xxx.xxx.xxx.xxx:8000/
testとprod環境が動いていることを確認できたらiptablesを再スタートする
$ sudo service iptables start
リバースプロキシの設定
rp01のhttp.confファイルに下記モジュールを設定
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
さらに、rp01のhttp.confにロードバランサの処理を追加
※ipアドレスをホスト名に置き換えてます
#prod環境へのアクセスを「xxx.com」
#test環境へのアクセスを「test.xxx.com」のサブドメインにした場合の設定
#prod設定
<VirtualHost *:80>
ServerName xxx.com:80
ProxyPass /balancer-manager !
<Location /balancer-manager>
SetHandler balancer-manager
</Location>
ProxyPass / balancer://rp01/
ProxyPassReverse / balancer://rp01/
<Proxy balancer://rp01/>
BalancerMember http://web01:80 loadfactor=5
BalancerMember http://web02:80 loadfactor=5
</Proxy>
</VirtualHost>
#test設定
<VirtualHost *:80>
ServerName test.xxx.com:80
ProxyPass /balancer-manager !
<Location /balancer-manager>
SetHandler balancer-manager
</Location>
ProxyPass / balancer://test-rp01/
ProxyPassReverse / balancer://test-rp01/
<Proxy balancer://test-rp01/>
BalancerMember http://web01:8000 loadfactor=5
BalancerMember http://web02:8000 loadfactor=5
</Proxy>
</VirtualHost>
loadfactorの数字を大きくすると、使用頻度が大きくなります。
web01・web02のapacheを交互に停止して、xxx.comにアクセスできたらロードバランサの設定が完了している。
余談
DTIのVPSを借りれば、月420円 * 5台 = 2100円で実現可能です。
DTIの場合、aaa.bbb.ccc.1とaaa.bbb.ccc.2のように、グローバルIPの4桁目以外が同じの場合は
セキュリティ上、通信が出来ないようです(T_T)