全世界に公開
EC2のサーバにChatSpaceのコードをクローンする準備
まず、アプリケーションのコードをGithubからEC2サーバへクローンする。全世界に公開できるIPアドレスを持ったEC2サーバ上でChatSpaceを動かすためである。
GithubにSSH鍵を登録する
現状、EC2サーバにアプリケーションのコードをクローンしようとしてもpermission denied
とエラーが出てしまう。
これは、Githubから見てこのEC2インスタンスが何者かわからないため。
EC2インスタンスからGithubにアクセスするためには、作成したEC2インスタンスのSSH公開鍵をGithubに登録する必要がある。
SSH鍵をGithubに登録すると、Githubはそれを認証に利用し、コードのクローンを許可してくれるようになる。
EC2サーバのSSH鍵ペアを作成する
途中で passphrase
など3段階ほど入力を求められることがあるが、全て何も入力せずにEnterキーで進む。
※EC2サーバにログインしていない場合はログインしてから以下の作業を行う。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[ec2-user@ip-172-31-23-189 ~]$ ssh-keygen -t rsa -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ec2-user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/ec2-user/.ssh/id_rsa.
Your public key has been saved in /home/ec2-user/.ssh/id_rsa.pub.
The key fingerprint is:
3a:8c:1d:d1:a9:22:c7:6e:6b:43:22:31:0f:ca:63:fa ec2-user@ip-172-31-23-189
The key's randomart image is:
+--[ RSA 4096]----+
| + |
| . . = |
| = . o . |
| * o . o |
|= * S |
|.* + . |
| * + |
| .E+ . |
| .o |
+-----------------+
|
次に、以下のコマンドで生成されたSSH公開鍵を表示し、値をコピーする。
1 2 |
そして、catで表示させた公開鍵を、Githubにアクセスして登録していく。
まず、以下のURLにアクセスしてください。
https://github.com/settings/keys
Githubに鍵を登録できたら、SSH接続できるか以下のコマンドで確認。
1 2 |
途中でこのまま続けるかどうかYes/Noで聞かれることがあるが、Yesで進む。
Permission denied (publickey).
と表示された場合は、SSH鍵の設定が間違っているので、作業を確認する。
アプリケーションサーバの設定
アプリケーションサーバの導入と設定を行う。
アプリケーションサーバ(Appサーバ)
アプリケーションサーバとは、ブラウザからの「リクエスト」を受け付けRailsアプリケーションを実際に動作させるソフトウェアのこと。実はすでにアプリケーションサーバを利用している。それが、rails s
コマンド。
rails sコマンドとは何か?
普段、ローカル環境でRuby on Railsのアプリケーションの動作を確認する際、以下の手順を踏む。
①ターミナルからrails s
コマンドを打つ
②ブラウザでlocalhost:3000
にアクセス
①をせずに②を行なっても、アプリケーションの動作を確認できない。
実は、①の操作はまさに「アプリケーションサーバの起動」を行なっている。
rails s
コマンドを打つと、puma
と呼ばれるアプリケーションサーバが起動している。以下は、ローカルでrails s
コマンドを打った時の様子。
1 2 3 4 5 6 7 8 9 10 11 |
#rails sコマンドでサーバを起動
$rails s
=> Booting Puma
=> Rails 5.0.7.2 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.0 (ruby 2.3.1-p112), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
|
3行目に「 Booting Puma」と書かれている。つまり「pumaを起動しています」ということ。rails sコマンドを打つことで、pumaというアプリケーションサーバが起動していることがわかる。
また、localhost:3000
とは自身のPCを指すドメインである。
つまり、①、②は言い換えれば「自身のPCをサーバに見立てアプリケーションサーバを起動し、ブラウザから自身のPCにアクセスする」ということを行なっていた。
アプリケーションサーバが動いていれば、ブラウザからのリクエストを受け付けてRailsアプリケーションが動作する。
という訳で、全世界に公開するEC2サーバ上でもアプリケーションサーバを動かす必要がある。
Unicorn
全世界に公開されるサーバ上で良く利用されるアプリケーションサーバ。rails s
コマンドの代わりにunicorn_rails
コマンドで起動することができる。
この後、EC2サーバにSSH接続しUnicornを起動することで全世界からアクセスできるようにしていく。イメージとしては、以下の図。
ここでちょっと脇道にそれて、Unicornを理解するために必要な重要で新しい概念がある。それが、プロセスである。
プロセスについて
プロセス
プロセスとは、PC(サーバ)上で動く全てのプログラムの実行時の単位。ここで言うプログラムとは、ブラウザや音楽再生ソフト、ExcelといったGUIや、Rubyなどのスクリプト言語の実行などが含まれる。
プログラムが動いている数だけ、プロセスが存在している。例えばテキストエディタを起動する時、テキストエディタ用のプロセスが生み出される。
プロセスを確認してみる
PCがMacの場合、アクティビティモニタというアプリケーションでプロセスを確認することができる。
アクティビティモニタは、現在MacPC上で動いているプログラムの状況をモニタリングするアプリです。
以下が、アクティビティモニタを開いた画面です。
一番左上の「プロセス名」と言う列に、Google Chromeや、アクティビティモニタ自身も表示されている。
つまり、Google Chromeもアクティビティモニタもプロセスであるということ。
もう一つ注目したいのは、真ん中あたりにある「PID(プロセスアイディー)」という列である。
数字が入っているが、これはプロセスを識別するための一意の数字になる。PIDがあることで、あるプログラムから別のプロセスを指定して操作したり、プロセスからプログラムを停止したりできる。
Unicornなどのアプリケーションサーバを起動するとアプリケーションサーバのプロセスが生まれる。アプリケーションサーバのプロセスがあれば、リクエストを受け付けブラウザにレスポンスを返すことができる。
Unicornをインストールする
UnicornはRubyで作成されており、gem化されている。
1. ローカルでGemfile
を編集。
1 2 3 |
group :production do
gem 'unicorn', '5.4.1'
end
|
2. ローカルのChatSpaceディレクトリでbundle install
コマンドを実行。
1 |
$ bundle install
|
group :production do ~ end
このgroup :production do ~ end
の間に記述されたgemは本番環境のみ
で読み込まれる。
Unicornは本番環境でのみ必要なので、開発環境下では不要。
config/unicorn.rbを作成し、内容を以下のように編集して保存
Unicornの設定ファイルとして、次の内容でファイルを作成する。
最初からは存在していないので、自分でconfig
ディレクトリ以下に作成する。
まずはコピー&ペーストで作成したファイルに貼り付ける。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#サーバ上でのアプリケーションコードが設置されているディレクトリを変数に入れておく
app_path = File.expand_path('../../', __FILE__)
#アプリケーションサーバの性能を決定する
worker_processes 1
#アプリケーションの設置されているディレクトリを指定
working_directory app_path
#Unicornの起動に必要なファイルの設置場所を指定
pid "#{app_path}/tmp/pids/unicorn.pid"
#ポート番号を指定
listen 3000
#エラーのログを記録するファイルを指定
stderr_path "#{app_path}/log/unicorn.stderr.log"
#通常のログを記録するファイルを指定
stdout_path "#{app_path}/log/unicorn.stdout.log"
#Railsアプリケーションの応答を待つ上限時間を設定
timeout 60
#以下は応用的な設定なので説明は割愛
preload_app true
GC.respond_to?(:copy_on_write_friendly=) && GC.copy_on_write_friendly = true
check_client_connection false
run_once = true
before_fork do |server, worker|
defined?(ActiveRecord::Base) &&
ActiveRecord::Base.connection.disconnect!
if run_once
run_once = false # prevent from firing again
end
old_pid = "#{server.config[:pid]}.oldbin"
if File.exist?(old_pid) && server.pid != old_pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH => e
logger.error e
end
end
end
after_fork do |_server, _worker|
defined?(ActiveRecord::Base) && ActiveRecord::Base.establish_connection
end
|
上記のファイルの中で、重要な設定とそれにまつわる概念について。
worker(ワーカー)
Unicornは、プロセスを分裂させることができる。この分裂したプロセス全てをworkerと呼ぶ。プロセスを分裂させることで、リクエストに対してのレスポンスを高速にすることができる。後述するworker_processesという設定項目で、workerの数を決定する。
ブラウザなどからリクエストが来ると、UnicornのworkerがRailsアプリケーションを動かす。Railsは、リクエストの内容とルーティングを照らし合わせ最終的に適切なビュー(HTML)もしくはJSONをレスポンスする。レスポンスを受け取ったUnicornは、それをブラウザに返す。一連の動きはおよそ0.1 ~ 0.5秒程度で行われる。常にそれ以上のスピードでリクエストが頻発するようなアプリケーションだと、1つのworkerだけでは処理が追いつかず、レスポンスまで長い時間がかかってしまったり最悪サーバがストップしてしまう。そんな時、worker_processesの数を 2,3,4と増やすことでアプリケーションからのレスポンスを早くすることができる。
Unicornの設定
設定項目 | 詳細 |
---|---|
worker_processes | リクエストを受け付けレスポンスを生成するworker(ワーカー) の数を決める。 |
working_directory | UnicornがRailsのコードを動かす際、ルーティングなど実際に参照するファイルを探すディレクトリを指定する。 |
pid | Unicornは、起動する際にプロセスidが書かれたファイルを生成します。その場所を指定する。 |
listen | どのポート番号のリクエストを受け付けることにするかを決定する。今回は、3000番ポートを指定している。 |
ここまで変更できたら、ファイルをコミットし、Githubにpushしておく。ブランチを切っている場合は、masterブランチにmergeもしておく。
デプロイ時にエラーの原因となる記述の対策
Uglifierというgemがあり、これはJavaScriptを軽量化するためのもの。しかし、ChatSpaceのJavaScriptで使用しているテンプレートリテラル記法(`)に対応していない。そのため、デプロイ時にエラーの原因となる。
そこで、この部分をコメントアウトすることで対策する。
Uglifierについての記述をコメントアウトする
1 |
config.assets.js_compressor = :uglifier
|
1 |
# config.assets.js_compressor = :uglifier
|
なお、ChatSpace程度のjsの記述量であれば、軽量化をしてもしなくても違いはほとんどありません。
変更修正をリモートリポジトリに反映する
変更修正をコミットしてプッシュ
GitHub Desktopからコミットしてプッシュ。この時必ず、masterブランチで行う。もし、別ブランチでコミット&プッシュした場合は、リモートリポジトリでプルリクエストを作成し、ブランチをmasterへマージする。
Githubからコードをクローンする
続いて、Unicornの設定を済ませたコードをEC2インスタンスにクローンする。
まず、以下のコマンドを入力して、ディレクトリを作成。今回は、ここで作成したディレクトリにアプリケーションを設置する。
1. /var/wwwディレクトリを作成し、権限をec2-userに変更
1 2 3 4 |
2. Githubから「リポジトリURL」を取得
3. 取得した「リポジトリURL」を使って、コードをクローン
1 2 |
[ec2-user@ip-172-31-23-189 ~]$ cd /var/www/
[ec2-user@ip-172-31-23-189 www]$ git clone https://github.com/<リポジトリ名>.git
|
上記の入力でエラーがでなければ、先に進む。
本番環境での設定
サービスを公開するための設定を行う。
※これ以降、特に指示がない場合、作業は/var/www/chat-space
で行うので注意。
EC2の能力を拡張する
現状動かしているEC2のインスタンスではコンピューターの能力が足りず、Gemのインストール時などにエラーが発生する可能性がある。具体的には、コンピューターの処理能力に関係するメモリというものが足りない。これは、無料で動かせるインスタンスの限界であるため仕方ない。そこで、メモリを増強する処理を行う。
Swap(スワップ)領域
コンピュータが処理を行う際、メモリと呼ばれる場所に処理内容が一時的に記録される。メモリは容量が決まっており、容量を超えてしまうとエラーで処理が止まってしまう。Swap領域は、メモリが使い切られそうになった時にメモリの容量を一時的に増やすために準備されるファイル。
EC2はデフォルトではSwap領域を用意していないため、これを準備することでメモリ不足の処理エラーを防ぐ。
Swap領域を用意する
まずは、EC2にログインしてホームディレクトリに移動。
1 2 |
#ホームディレクトリに移動
[ec2-user@ip-172-31-25-189 ~]$ cd
|
続いて、以下の順番でコマンドを実行。
1 2 3 4 5 6 |
#処理に時間がかかる可能性があるコマンドです
[ec2-user@ip-172-31-25-189 ~]$ sudo dd if=/dev/zero of=/swapfile1 bs=1M count=512
# しばらく待って、以下のように表示されれば成功
512+0 レコード入力
512+0 レコード出力
536870912 バイト (537 MB) コピーされました、 7.35077 秒、 73.0 MB/秒
|
1 |
[ec2-user@ip-172-31-25-189 ~]$ sudo chmod 600 /swapfile1
|
1 2 3 4 |
[ec2-user@ip-172-31-25-189 ~]$ sudo mkswap /swapfile1
# 以下のように表示されれば成功
スワップ空間バージョン1を設定します、サイズ = 524284 KiB
ラベルはありません, UUID=74a961ba-7a33-4c18-b1cd-9779bcda8ab1
|
1 |
[ec2-user@ip-172-31-25-189 ~]$ sudo swapon /swapfile1
|
1 2 |
[ec2-user@ip-172-31-25-189 ~]$ sudo sh -c 'echo "/swapfile1 none swap sw 0 0" >> /etc/fstab'
|
最後のコードは見づらいが、「/swapfile1 none」より右に続きがあるので注意
これで、Swap領域を確保することができた。
gemをインストール
クローンしたアプリケーションを起動するために必要なgemを以下のコマンドでインストールする。
1. クローンしたディレクトリに移動し、 rbenv
でインストールされたRubyが使われているかチェックする
1 2 3 |
ruby 2.5.1 ...
となっていれば成功。そうでない場合は、もともと用意されているRubyが利用されているので、Rubyのインストールが成功しているか確認。
2.本番環境でgemを管理するためのbundler
をインストールして、bundle install
を実行
まず今まで開発環境(ローカル)で開発してきたChatSpaceにおいて、どのバージョンのbundlerが使われていたのか確認。
1 2 3 4 |
#ChatSpaceのディレクトリで以下を実行
$ bundler -v
Bundler version 2.0.1
# 開発環境によってバージョンは異なります。
|
開発環境で仕様しているbundlerのバージョンがわかったので、同じバージョンのものをEC2サーバ側にも導入。上記の場合では、bundler 2.0.1のバージョンを導入して bundle install
を実行。
1 2 3 4 |
環境変数を設定
データベースのパスワードなどセキュリティのためにGithubにアップロードすることができない情報は、環境変数というものを利用して設定する。
環境変数は、Railsからは ENV['<環境変数名>']
という記述でその値を利用することができる。
config/secrets.yml
と config/database.yml
を見てみる。
例えば <%= ENV["SECRET_KEY_BASE"] %>
と書かれている部分は、 SECRET_KEY_BASE
という環境変数の値になる。
secret_key_base
secret_key_base
とは、Cookieの暗号化に用いられる文字列。Railsアプリケーションを動作させる際は必ず用意する必要がある。また、外部に漏らしてはいけない値であるため、こちらも環境変数から参照する。
secret_key_base
は以下のコマンドを打つことで生成できる。
1. secret_key_baseを作成
1 2 |
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ rake secret
69619d9a75b78f2e1c87ec5e07541b42f23efeb6a54e97da3723de06fe74af29d5718adff77d2b04b2805d3a1e143fa61baacfbf4ca2c6fcc608cff8d5a28e8d
|
この長い英数の羅列は、この後利用するのでコピーしておく。
2. 以下の指示にしたがって、環境変数を設定。
環境変数は /etc/environment
というファイルに保存することで、サーバ全体に適用される。環境変数の書き込みはvimコマンドを使用して行う。
1 |
[ec2-user@ip-172-31-23-189 ~]$ sudo vim /etc/environment
|
上記の様な画面になれば、iと打ち込んで入力モードに切り替えた後、下記の記述を打ち込む。=
の前後にスペースは入れない。
1 2 3 |
3. 設定した環境変数を反映させるために、一度本番環境をログアウトする
書き込みができたら esc(エスケープキー)を押下後、:wq
と入力して内容を保存。保存できたら環境変数を適用するために一旦ログアウトする。
1 2 3 |
[ec2-user@ip-172-31-23-189 ~]$ exit
logout
Connection to 52.xx.xx.xx closed.
|
4. もう一度本番環境へログイン
exitでログアウトすると、ローカル環境となる。再度SSHし直す。
1 2 |
5. 設定した環境変数が本当に適用されているか確認
SSHし直したら、 env
というコマンドと grep
を組み合わせて、先程設定した環境変数が適用されているか確認。
1 2 3 4 5 |
ポートの解放
立ち上げたばかりのEC2インスタンスはSSHでアクセスすることはできるが、HTTPなどの他の通信方法では一切つながらないようになっている。そのため、WEBサーバとして利用するEC2インスタンスは事前にHTTPがつながるように「ポート」を開放する必要がある。
config/unicorn.rb
に listen 3000
と記述したが、これはRailsのサーバを3000番ポートで起動するということを意味する。
セキュリティグループについて
ポートの設定をするためにはEC2の「セキュリティグループ」という設定を変更する必要がある。
セキュリティグループとは、EC2サーバが属するまとまりのようなもので、複数のEC2インスタンスのネットワーク設定を一括で行うためのもの。
セキュリティグループのポートを設定
下図の手順に従って、セキュリティグループのポートを設定する。
まず、EC2インスタンス一覧画面から、対象のインスタンスを選択し、「セキュリティグループ」のリンク(図中では「launch-wizard-1」)をクリック。
すると、インスタンスの属するセキュリティグループの設定画面に移動するので、「インバウンド」タブの中の「編集」をクリック。
モーダルが開くので、「ルールの追加」をクリック。
タイプを「カスタムTCPルール」、プロトコルを「TCP」、ポート範囲を「3000」、送信元を「カスタム」「0.0.0.0/0」に設定する。
「0.0.0.0」は「全てのアクセスを許可する」という意味。
以上で、ポートの開放が完了。
この作業が終わっていないと、起動したRailsにアクセスできないので注意。
Railsを起動する
本番環境でRailsを起動
unicorn_railsコマンド
-c config/unicorn.rb
は設定ファイルの指定、 -E production
は環境を「本番モードとして動作させる」ことを示す。-D
は「Daemon(デーモン)」の略で、プログラムを起動させつつターミナルで別のコマンドを打てるようにするオプション。
1.ユニコーンを起動させてみる
unicorn
のgemをインストールしていると unicorn_rails
というコマンドが使えるようになっている。これは、ローカル環境でrails s
を行うのと同じように利用する。EC2サーバにて、以下のコマンドを実行。
1 2 |
このコマンドを実行すると、以下のようにすぐにコマンドが終了してしまう。
1 2 |
これはもう一つ必要な作業をしていないからで、原因を調査するために、エラーログを確認する。エラーログの確認は、どんなエラーに対してもまずはじめにすべきこと。
2. Unicornのエラーログを確認
先程の config/unicorn.rb
をもう一度確認してみると、 stderr_path "#{app_path}/log/unicorn.stderr.log"
という記述がある。これは、「Unicorn関係で起きたエラーをlog/unicorn.stderr.log
」に記録するという指定になっている。
log/unicorn.stderr.log
を確認。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ less log/unicorn.stderr.log
I, [2016-12-21T04:01:19.135154 #18813] INFO -- : Refreshing Gem list
I, [2016-12-21T04:01:20.732521 #18813] INFO -- : listening on addr=0.0.0.0:3000 fd=10
E, [2016-12-21T04:01:20.734067 #18813] ERROR -- : Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/mysql2_adapter.rb:29:in `rescue in mysql2_connection'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/mysql2_adapter.rb:12:in `mysql2_connection'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:721:in `new_connection'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:765:in `checkout_new_connection'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:744:in `try_to_checkout_new_connection'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:705:in `acquire_connection'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:501:in `checkout'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:364:in `connection'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:875:in `retrieve_connection'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.0.0.1/lib/active_record/connection_handling.rb:128:in `retrieve_connection'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.0.0.1/lib/active_record/connection_handling.rb:91:in `connection'
config/unicorn.rb:36:in `block in reload'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/unicorn-5.1.0/lib/unicorn/http_server.rb:502:in `spawn_missing_workers'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/unicorn-5.1.0/lib/unicorn/http_server.rb:132:in `start'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/unicorn-5.1.0/bin/unicorn_rails:209:in `<top (required)>'
/home/ec2-user/.rbenv/versions/2.5.1/bin/unicorn_rails:23:in `load'
/home/ec2-user/.rbenv/versions/2.5.1/bin/unicorn_rails:23:in `<main>'
|
このERROR
という行を見てみると、これは本番環境でインストールするmysqlの設定がローカルとは異なるため、mysqlへ接続できなくなっている状態。
3. database.ymlの本番環境の設定を編集
本番環境のmysqlの設定に合わせるため、ローカルのdatabase.ymlを以下のように編集する。
1 2 3 4 5 6 |
4. ローカルでの編集をコミットして、GitHubにプッシュする
リモートリポジトリが更新されたため、サーバ上のアプリケーションにも反映させる。
先ほどはgit clone
コマンドを利用したが、今回はすでにEC2とGithubは接続できているため、git pull
コマンドを利用する。
サーバのアプリケーションのあるディレクトリで以下のようにコマンドを実行する。
※別にブランチを切っている場合は、masterブランチにmergeしてから実行。
1 |
[ec2-user@ip-172-31-23-189 <リポジトリ名>] git pull origin master
|
5. データベースを作成しマイグレーションを実行し直す
1 2 3 |
もしここでMysql2::Error: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'
というエラーが起こった場合、mysqlが起動していない可能性がある。sudo service mysqld start
というコマンドをターミナルから打ち込み、mysqlの起動を試してみる。
6. 再度Railsを起動させる
これでデータベースの準備が整ったので、再びRailsを起動する。
1 |
今度はエラーが出ることなくコマンドが終了したなら成功。
7. ブラウザで http://<サーバに紐付けたElastic IP>:3000/ にアクセス
ブラウザにCSSの反映されていない(ビューが崩れている)画面が表示されていれば成功。
アセットファイルをコンパイルする
無事Railsが起動できたが、今のままではレイアウトが崩れてしまっている。
開発中には正常に表示されていたのに、本番ではうまく表示されないのは、開発中にはアクセス毎にアセットファイル(画像・CSS・JSファイルの総称)を自動的にコンパイル(圧縮)する仕組みが備わっているが、本番モードのときにはパフォーマンスのためアクセス毎には実行されないようになっているためである。
1. アセットコンパイルを実行
本番モードでは、事前にアセットをコンパイルする必要がある。そのために次のコマンドを実行。
2. Unicornのプロセスを確認
コンパイルが成功したら反映を確認するため、Railsを再起動する。しかし、まずは今動いているUnicornをストップする。そのために、Unicornのプロセスを確認し、プロセスを止める。ターミナルからプロセスを確認するにはps
コマンドを利用する。
psコマンド
psコマンドは、現在動いているプロセスを確認するためのコマンド。
3. psコマンドを入力してUnicornのプロセスを確認
EC2のターミナルから以下のように入力する。「aux」と打っているのは、psコマンドのオプション。表示結果を見やすくしてくれる。また、| grep unicorn
としているのはpsコマンドの結果からunicorn関連のプロセスのみを抽出するため。
すると、以下のようにプロセスが表示されるはず。
1 2 3 |
ec2-user 17877 0.4 18.1 588472 182840 ? Sl 01:55 0:02 unicorn_rails master -c config/unicorn.rb -E production -D
ec2-user 17881 0.0 17.3 589088 175164 ? Sl 01:55 0:00 unicorn_rails worker[0] -c config/unicorn.rb -E production -D
ec2-user 17911 0.0 0.2 110532 2180 pts/0 S+ 02:05 0:00 grep --color=auto unicorn
|
大事なのは左から2番目の列。ここに表示されるのがプロセスのid、つまりPIDになる。
「unicorn_rails master」と表示されているプロセスがUnicornのプロセス本体。この時のPIDは、17877となっている。
4. UnicornのプロセスをKillする
ターミナルからプロセスをストップするにはkill
コマンドを利用する。
killコマンド
killコマンドは、現在動いているプロセスを停止させるためのコマンド。
5. killコマンドを入力してUnicornのプロセスを停止する
EC2のターミナルから以下のように入力。
再度、プロセスを表示させ終了できていることを確認。
1 2 3 |
実行結果が上記のようになっていればUnicornを停止が完了。ローカルで行なっていた、ctrl + cでサーバをストップするという作業と同じことをしたことになる。
プロセスが終了できない場合
下記の2行が表示が消えていない場合はプロセスが終了できていないことになる。
1 2 |
そのような場合は、プロセスを強制終了する。オプション-9をkillコマンドにつけると強制終了を実行できる。通常のkillコマンドで削除できない場合はこちらを使用する。
1 2 3 |
$ kill -9 [プロセスID]
#プロセスIDはpsコマンドで検索した結果の数字に置き換えてください。上記であれば17877です。
|
6. 先頭にRAILS_SERVE_STATIC_FILES=1をつけて、unicornを起動
続いて再びunicornを起動する。このとき RAILS_SERVE_STATIC_FILES=1
という指定を先頭に追加。これは、コンパイルされたアセットをRailsが見つけられるような指定になる。
1 2 |
7.ブラウザで確認
もう一度、ブラウザで http://<Elastic IP>:3000/ にアクセスしてみる。今度はレイアウト崩れも無くサイトが正常に表示されているはず。
通常のログの確認方法
アプリケーションが上手に起動している際はログを気にする事はないかもしれないが、以下のようにコマンドを実行する事で正常に動いている際のログも確認することができる。
1 2 |
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$tail -f log/production.log
...
|
実行すると、アプリケーションにアクセスがあった場合にリアルタイムにログが流れることが確認できる。
tail コマンド
指定したファイルの最後の行を表示するコマンド。-f
オプションを追加することで、そのままリアルタイムに更新されるようになる。
tail -f
コマンドによる表示を終了したい場合は、ctrl + c
で中断できる。
Railsの起動がうまくできなかった時
上記のコマンドを実行してもRailsが起動しないときや、起動できてもIPアドレス:3000にアクセスするとエラーが表示されていることがある。その際は、以下の点を確認してみる。
- pushのし忘れ、またはEC2サーバ側でのpullのし忘れは無いか
- EC2サーバ側で、
/var/www/<リポジトリ名>/log/unicorn.stderr.log
をless
またはcat
コマンドで確認し、エラーが出ていないか確認する(下に行くほど最新のログです。時刻表記がUTCであることに注意) - カリキュラム通りの記載ができているか
- ローカルでの編集のpushやEC2でのgit pullを忘れていないか
- 前カリキュラムで実施した、mysqlの起動は正しく行えているか
- EC2サーバ側のSECRET_KEY_BASE等は正しく設定できているか
- EC2インスタンスの再起動を行ってみる
まとめ
- EC2インスタンスからGithubへアクセスできるようにする
- Githubからコードをクローンする
- アプリケーションサーバ Unicorn をインストールし設定する
- データベースを作成しマイグレーションを実行する
- アセットをコンパイルする
- Railsを起動する
ついにRailsを起動することに成功!
デプロイの手順を図でまとめると、以下のようになる。