Edited at

(デプロイ編②)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで


世界一丁寧なAWS解説シリーズ 項目表

No.
タイトル

1
下準備編

2
DB・サーバー構築編

3
デプロイ編①

4
〜〜デプロイ編②(今ここ)〜〜

5
Capistrano編

「分かりづらいAWSやネットワークを、出来るだけ丁寧に」

と思って記事を書き続けたら、まさかの4部作になってしまいました... 笑

いよいよほんとにラストです。

最後まで頑張りましょう!(と、言い聞かせている相手は自分ですw)

前回までの記事で、

AWS側の準備→作成したアプリをgitからクローン というところまで行いました。

(まだの方は、 1.下準備編 2.DB、サーバー編 3.デプロイ編① をお読みください。)

このクローンしたアプリを、実際に動かすにはまだ準備が必要です。

まずは、Unicornのインストール...の前に、webサーバー/アプリケーションサーバー/Rackの違いから見ていくこととしましょう。


Webサーバー/アプリケーションサーバー/Rackとは?

さて突然ですがここで皆さんに問題です。

開発環境において、rails s のコマンドを打ち込んで起動するサーバー(WEBrick)は、Webサーバーですか? アプリケーションサーバーですか?

正解は...........アプリケーションサーバーです。

それぞれの違いを見ていきましょう。

Webサーバーとは、ユーザーから送られてきた自サイトへのリクエストを受け取り、なんらかの処理を加えるプログラムです。

本番環境にあがっているプロダクトの場合、ユーザーからのリクエストは大半がまずここに送られます。 「受付窓口」といったイメージですね。

この受付が「自分だけで処理できる!」と判断すれば、ちょいちょいっと作業をした上で、ユーザーにレスポンスを返します。

逆に「自分だけじゃ無理!」と判断した場合は、処理をアプリケーション本体に投げます。そして、アプリケーション側から返ってきたレスポンスをユーザーに返すのです。

では、その「アプリケーション本体」はどこに置かれているのか。

その答えが、アプリケーションサーバーになります。

アプリケーションサーバーには、ご自身で作られたアプリケーションが置かれています。

Webサーバーから「僕だけじゃ無理です。助けてください」との依頼を受けたアプリケーションサーバーは、自身の中にいるアプリ本体に指令を出し、処理完了後、webサーバーに対して「終わりましたよー」と報告をするのです。

ですが、ここで一つ問題があります。

アプリケーションサーバーとアプリ本体は、使用している言葉が違うので、上手くコミュニケーションが取れないのです。

さて困った。と思った矢先、登場するのがRackです。

Rackは、いわば通訳です。

彼が通訳をしてくれるお陰で、無事にアプリケーションサーバーとアプリ本体がコミュニケーションを取ることができ、結果、ユーザーにレスポンスを返すことができたのでした。

ちゃんちゃん。

... と、なんとなくイメージは掴めましたか? 笑

ちなみに冒頭の問題に関してなのですが、

大半のアプリケーションサーバーは、webサーバーを使わずに単体で実行できます。

(本番環境ではwebサーバーを設置することがほとんどですが)

ですので、正解は、アプリ本体を設置する「アプリケーションサーバー」...となるのです。

この違いを頭に入れた上で、それぞれをインストールしていきましょう。


Unicornの設定

Unicornとはアプリケーションサーバーの一種です。

先ほど出てきましたね。アプリ本体を格納するためのサーバーです。

分かってしまえばこっちのもの。

早速インストールしていきましょう。

下記コマンドを実行して下さい。

[naoki|mumu] $: vi Gemfile

-----------------------------
#以下を追記
group :production, :staging do
gem 'unicorn'
end
----------------------------
[naoki|mumu] $ gem install bundler
[naoki|mumu] $ bundle install
[naoki|mumu] $ vi config/unicorn.conf.rb
----------------------------

打ち込むコマンド自体は見慣れたものばかりですね。

viコマンドでconfig配下に生成したunicornの設定ファイルに、下記を記述します。


unicorn.conf.rb

  # set lets

$worker = 2
$timeout = 30
$app_dir = "/var/www/rails/mumu" #自分のアプリケーション名
$listen = File.expand_path 'tmp/sockets/.unicorn.sock', $app_dir
$pid = File.expand_path 'tmp/pids/unicorn.pid', $app_dir
$std_log = File.expand_path 'log/unicorn.log', $app_dir
# set config
worker_processes $worker
working_directory $app_dir
stderr_path $std_log
stdout_path $std_log
timeout $timeout
listen $listen
pid $pid
# loading booster
preload_app true
# before starting processes
before_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
Process.kill "QUIT", File.read(old_pid).to_i
rescue Errno::ENOENT, Errno::ESRCH
end
end
end
# after finishing processes
after_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

ここら辺は設定ファイルなので、詳細には追いません。

これでUnicornの設定が完了です。


Nginxの設定

お次はNginxです。「エンジンエックス」と読むそうです。

このNginxはWebサーバーにあたります。

これも先ほど出てきましたね。受付窓口です。

早速下記コマンドを打ち込んでください。

[naoki|~] sudo yum install nginx

[naoki|~]$ cd /etc/nginx/conf.d/
[naoki|conf.d]$ sudo vi mumu.conf #自分のアプリケーション名でファイル名変更

viコマンドで作成したnginxの設定ファイルには、下記を記述します。


mumu.conf

# log directory

error_log /var/www/rails/mumu/log/nginx.error.log; #自分のアプリケーション名に変更
access_log /var/www/rails/mumu/log/nginx.access.log; #自分のアプリケーション名に変更
# max body size
client_max_body_size 2G;
upstream app_server {
# for UNIX domain socket setups
server unix:/var/www/rails/mumu/tmp/sockets/.unicorn.sock fail_timeout=0; #自分のアプリケーション名に変更
}
server {
listen 80;
server_name ~~~.~~~.~~~.~~~;(#アプリのElastic IPに変更してください)
# nginx so increasing this is generally safe...
keepalive_timeout 5;
# path for static files
root /var/www/rails/mumu/public; #自分のアプリケーション名に変更
# page cache loading
try_files $uri/index.html $uri.html $uri @app;
location @app {
# HTTP headers
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
# Rails error pages
error_page 500 502 503 504 /500.html;
location = /500.html {
root /
var/www/rails/mumu/public; #自分のアプリケーション名に変更
}
}

ここも設定ファイルなので詳細には追いません。

また、設定ファイルの記述が終わったら、下記も実行してください。

[naoki|conf.d] cd /var/lib

[naoki|lib] sudo chmod -R 775 nginx

この呪文はpostメソッドでもエラーが出ないようにするためのものなのだとか。

「開けごま」的な勢いでとりあえず唱えてあげましょう。

これにて設定完了です。


MySQLの設定

続いてDBです。

(アプリケーションのDBがMySQLで作成されている前提で話を進めていきます。)

下記コマンドを打ち込み、MySQLに関する設定を変更していきましょう。

[naoki|protospace]$ vi config/database.yml

----------------------------
production:
<<: *default
database: mumu_production
username: root #ここをrootに変更する
  password: #ここを空欄にする
----------------------------

[naoki|mumu]$ sudo service mysqld start #mysqldの起動
[naoki|mumu]$ ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock
[naoki|mumu]$ rake db:create RAILS_ENV=production
[naoki|mumu]$ rake db:migrate RAILS_ENV=production

my.cofとはMySQLのオプション設定向けファイルです。

ここに文字コードを設定した上で、mysqidを起動させます。

mysqlとmysqld... この「d」は一体なんなのでしょうか。

実はこの「d」は「デーモン」のdを指しており、デーモンとはバックグラウンド処理のことを指します。

つまり、mysqldとは、mysqlの裏側の処理を担当する箇所で、

クライアントからmysqlに送られた来たSQL等を処理し、結果をクライアントに返すという役割を担っている箇所となります。

このmysqldを起動させ、MySQLが動く状態にした上で、

In -sコマンドで、ローカル環境で起動させているMysqlの場所を本番環境に合わせれるようリンクを作成し、

そしていつもの、「rake db:create」「rake db:migrate」を実行です。

上記のように、

アプリのmigrationファイルが実行されたログが出て来れば無事成功です。

(権限が原因でmysqldの起動が出来ないことがあります。その場合はchownやchmodコマンドでmysql関連ファイルの権限を変更してあげましょう。)


Nginxの起動

先ほど設定したNginxを起動させましょう。

使うはたった1行のコマンド。

[naoki|mumu]$ sudo service nginx start

これだけです。

そして全ての行程が上手くいっていれば、これが打ち込む最後のコマンドになります。

なんて感慨深いのでしょう。

涙が出そうです。(ほんとに)


確認!!!!!!

さぁ、これで全行程が終了しました。

52.64.~~~~~~~~~(ご自身のIPアドレス)

にアクセスし、作成したアプリがきちんとデプロイされたか確認してみてください。

ん...?

あ...

あれ...?

あれれ....???

MASAKANO

まさかの

エラーです。

あ... 慌てないでください...あわわわわ...

魔法のコマンド、再起動の出番です。

まずはUnicornの起動確認。

[mumu]$ ps -ef | grep unicorn | grep -v grep

このコマンドを打ち込んで、

naoki  24265     1 27 03:12 ?        00:00:01 unicorn_rails master -c /var/www/rails/tech-ruche/config/unicorn.conf.rb -D -E production

naoki 24271 24265 0 03:12 ? 00:00:00 unicorn_rails worker[0] -c /var/www/rails/tech-ruche/config/unicorn.conf.rb -D -E production
naoki 24273 24265 0 03:12 ? 00:00:00 unicorn_rails worker[1] -c /var/www/rails/tech-ruche/config/unicorn.conf.rb -D -E production
----------------------------

こんな感じでなんだかゴニョゴニョ表示されていれば既に起動されています。

表示されない場合は下記を実行してください。

[naoki]$ unicorn_rails -c /var/www/rails/mumu(アプリの名前)/config/unicorn.conf.rb -D -E production #unicornを起動させる

その後もう一度上記の起動確認コマンドを実行し、例のゴニョゴニョが出て来ればOKです。

その後、Nginxも再起動させます。

[naoki|mumu]$ sudo nginx -s reload

これでもう一度アクセスしてみてください!!

アプリが表示されましたか?

されてます...よね!?

ちなみに、画像の表示が出来ていない場合は、プリコンパイルが出来ていない可能性が高いです。

その際は、

1.unicornの停止(kill [PID])

2.rake assets:precompile RAILS_ENV=production の実行
3.unicornの再起動(上記コマンド)

を実施してみてください。

assets配下に画像を置いていると本番環境で反映されないこともあるみたいですので、画像は出来るだけpublic配下においてあげるようにしましょう。

(※特にbackgroundの画像表示に関してはこちらを参考にさせて頂きました。 ありがとうございます!)

以上で解説は終了です。

...が、きっとまだ表示されないという人もいるかと思います。

そんな方(と自分)の為に、いつの日かエラー対応集を作りたいなと思ってます。

なので、その日まではggrksで頑張ってください 笑

お疲れさまでした!!!

どうでしたでしょうか?

AWSにアプリをアップロードさせる過程を通じて、それなりにネットワーク関連の知識も付いたのではないでしょうか?

今回は解説しきれなかったですが、AWSにはまだまだ便利な機能が沢山あります(ERBやAuto Scalingなどなど...)

またデプロイの方法に関しても、CapistranoやBeansTalkなどを用いて更に簡単に行う手段も用意されています。

今回は勉強用に敢えて色々複雑にしてみましたが、今後のデプロイを考えるとCapistranoの方が良いので、Capistrano編も作ってみたいと思ってます。

お楽しみにー!

では、また会う日まで!