アプリの公開!
EC2のサーバにアプリのコードをクローン
・GithubにSSH鍵を登録
EC2サーバにアプリケーションのコードをクローンしようとしても、
エラーが出る。Githubから見てこのEC2インスタンスが何者かわからない。SSH鍵をGithubに登録すると、認証に利用しコードのクローンを許可する。
・EC2サーバのSSH鍵ペアを作成
ターミナル(EC2サーバ)
$ ssh-keygen -t rsa -b 4096
# 途中で passphrase など3段階ほど入力を求められることがあるが、何も入力せずにEnterキーで進む。
$ cat ~/.ssh/id_rsa.pub
# SSH公開鍵を表示。ssh-rsaで始まる長い公開鍵をコピー。
・catコマンド Linuxのコマンドの一つ。
①URLにアクセス → https://github.com/settings/keys
②画面右上の緑 New SSH key をクリック。
③上記画面になれば Title 内を自由に記載する。
④key 内にコピーしたssh-rsaで始まる公開鍵を貼り付ける。
⑤左下緑 Add SSH key をクリック。
$ ssh -T git@github.com
# SSH接続できるか確認。途中で続けるか聞かれることがあるが、Yesで進む。
Hi <Githubユーザー名>! You've successfully authenticated, but GitHub does not provide shell access.
# 上記メッセージが出れば成功。
アプリケーションサーバの設定
・アプリケーションサーバ
Webサーバから受け取ったリクエストをもとに、Javaやphp、Rubyなどを
実行し、Webサーバに結果を返す。全世界に公開するEC2サーバ上も
アプリケーションサーバを動かす必要がある。
Ruby on Rails環境のアプリケーションサーバ
Unicorn、Thin、Rainbows、Pumaが有名。
・Webサーバ
Apache、nginx 、IIS(Internet Information Services)が有名。
楽天ではapache、Yahooではnginx、MicrosoftではIISが利用されている。
ユニコーン
良く利用されるアプリケーションサーバ。
rails sコマンドの代わりにunicorn_railsコマンドで起動。
・Unicornをインストール
Gemfile を編集
group :production do
gem 'unicorn', '5.4.1'
end
# このgroup :production do ~ endの間に記述されたgemは本番環境のみ読み込まれる。
# Unicornは本番環境で必要なので、ローカルでは不要。
ターミナル(ローカル)
$ bundle install
#自分でconfigディレクトリ以下に作成。
config/unicorn.rb を編集
# サーバ上でのアプリケーションコードが設置されているディレクトリを変数に入れる
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
# ここで githubにpush & masterにmerge
・worker(ワーカー)
Unicornはプロセスを分裂させる。分裂したプロセス全てをworkerと呼ぶ。プロセスを分裂させると、リクエストに対しレスポンスを高速にする。
・プロセス
PC(サーバ)上で動く全プログラムの実行時の単位。プログラムは、ブラウザや音楽再生ソフト、GUIや、Rubyなどのスクリプト言語の実行など。
プログラムが動いている数だけ、プロセスが存在する。
Macではアクティビモニタでプロセスを確認できる。
PID(プロセスアイディー) プロセスを識別する数字
・worker_processes
リクエストを受けレスポンスを生成するworker(ワーカー)の数を決める。
・working_directory
UnicornがRailsのコードを動かす際、ルーティングなど実際に参照する
ファイルを探すディレクトリを指定。
・pid
Unicornは、起動する際にプロセスidが書かれたファイルを生成。
その場所を指定。
・listen
どのポート番号のリクエストを受け付けることにするかを決定。
上記は3000番ポートを指定している。
デプロイ時にエラーの原因となる記述の対策
config/environments/production.rb を編集
# JavaScriptを軽量化するもの。JavaScriptで使用しているテンプレートリテラル記法に対応していないため、
# デプロイ時にエラーの原因となる。コメントアウトで対策する。
config.assets.js_compressor = :uglifier をコメントアウト
# 完了後 githubにpush & masterにmerge
Githubからコードをクローン
ターミナル(EC2サーバ)
# mkdirコマンドで新たにディレクトリを作成
$ sudo mkdir /var/www/
# 作成したwwwディレクトリの権限をec2-userに変更
$ sudo chown ec2-user /var/www/
Githubから「リポジトリURL」を取得。
ページ右側緑ボタン Clone or download をクリック後、URLをコピー。
ターミナル(EC2サーバ)
$ cd /var/www/
# http以降は先ほどコピーしたURL
$ git clone https://github.com/<ユーザー名>/<リポジトリ名>.git
本番環境での設定
・Swap(スワップ)領域
コンピュータが処理を行う際、メモリと呼ばれる場所に処理内容が一時的に記録される。メモリは容量が決まっており、容量を超えるとエラーで処理が止まる。Swap領域は、メモリの不足時に容量を一時的に増やすファイル。EC2はデフォルトでSwap領域を用意していないため、準備することでメモリ不足のエラーを防ぐ。
ターミナル(EC2サーバ)
$ cd
# 処理に時間がかかる可能性があるコマンド
$ sudo dd if=/dev/zero of=/swapfile1 bs=1M count=512
# しばらく待って、以下のように表示されれば成功
512+0 レコード入力
512+0 レコード出力
536870912 バイト (537 MB) コピーされました、 7.35077 秒、 73.0 MB/秒
$ sudo chmod 600 /swapfile1
$ sudo mkswap /swapfile1
# 以下のように表示されれば成功
スワップ空間バージョン1を設定します、サイズ = 524284 KiB
ラベルはありません, UUID=74a961ba-7a33-4c18-b1cd-9779bcda8ab1
$ sudo swapon /swapfile1
$ sudo sh -c 'echo "/swapfile1 none swap sw 0 0" >> /etc/fstab'
・クローンしたアプリケーションを起動するためにgemをインストール。
ターミナル(EC2サーバ)
# クローンしたディレクトリに移動し、 rbenvでインストールされたRubyが使われているかチェック
[ec2-user@ip-172-31-45-306 www]$ cd /var/www/<リポジトリ名>
[ec2-user@ip-172-31-45-306 <リポジトリ名>]$ ruby -v
ruby 2.5.1p112 (2016-04-26 revision 54768) [x86_64-linux]
ターミナル(ローカル)
# 開発環境(ローカル)て、どのバージョンのbundlerが使われていたか確認。<リポジトリ名>のディレクトリで以下を実行
$ bundler -v
# 開発環境によってバージョンは異なります。
Bundler version 2.0.1
ターミナル(EC2サーバ)
# 同じバージョンのものをEC2サーバ側にも導入。
[ec2-user@ip-172-31-45-306 <リポジトリ名>]$ gem install bundler -v 2.0.1
# 上記コマンドは、数分以上かかる場合もある。
[ec2-user@ip-172-31-45-306 <リポジトリ名>]$ bundle install
環境変数の設定
データベースのパスワードなどセキュリティのためにGithubに
アップロードすることができない情報は、環境変数を利用して設定。
・環境変数
Railsは ENV['<環境変数名>'] で利用できる。
config / secrets.yml と config / database.yml を確認。
<%= ENV ["SECRET_KEY_BASE"]%> は、
SECRET_KEY_BASE という環境変数。
・secret_key_baseを作成
secret_key_baseは、Cookieの暗号化に用いられる文字列。
Railsアプリケーションを動作させる際は必ず用意する。外部に漏らしては
いけない値であるため、こちらも環境変数から参照する。
ターミナル(EC2サーバ)
# 実行後に表示される英数の羅列をコピー
[ec2-user@ip-172-31-45-306 <リポジトリ名>]$ rake secret
# EC2インスタンスに環境変数を設定。 /etc/environment に保存することで、サーバ全体に適用される
[ec2-user@ip-172-31-45-306 ~]$ sudo vim /etc/environment
vimコマンドについてはこちらの記事
画面が変更されたら i で挿入モードに切り替える。
/etc/environment を編集
# 下記を入力
DATABASE_PASSWORD='MySQLのrootユーザーのパスワード'
SECRET_KEY_BASE='先程コピーしたsecret_key_base'
esc(エスケープキー)を押して、 :wq を入力して保存&終了。
ターミナル(EC2サーバ)
# 環境変数を適用するため,ログアウト
[ec2-user@ip-172-31-45-306 ~]$ exit
# EC2にログイン
$ ssh -i 〇〇.pem ec2-user@[作成したEC2インスタンスと紐付けたElastic IP]
# 環境変数が適用されているか確認。
[ec2-user@ip-172-31-45-306 ~]$ env | grep SECRET_KEY_BASE
SECRET_KEY_BASE='secret_key_base'
[ec2-user@ip-172-31-45-306 ~]$ env | grep DATABASE_PASSWORD
DATABASE_PASSWORD='MySQLのrootユーザーのパスワード'
ポートの解放
EC2インスタンスはSSHでアクセスできるが、HTTP等、他の通信方法では
繋がりません。なのでWEBサーバとして事前にHTTPがつながるように
ポートを開放する必要があります。config/unicorn.rb に listen 3000 と
記述があります、これはRailsのサーバを3000番ポートで起動する意味。
・セキュリティグループのポートを設定
①EC2インスタンス一覧画面から、インスタンスを選択し、
セキュリティグループすぐ横のリンクをクリック。
②インバウンドルールをクリック。
③インバウンドのルールの編集をクリック。
④下記のように カスタムTCP を追加、保存。
本番環境でRailsを起動
ターミナル(EC2サーバ)
# ユニコーンを起動
[ec2-user@ip-172-31-45-306 ~]$ cd /var/www/[リポジトリ]
# 実行すると、以下のようにすぐにコマンドが終了する。
[ec2-user@ip-172-31-45-306 <リポジトリ名>]$ bundle exec unicorn_rails -c config/unicorn.rb -E production -D
master failed to start, check stderr log for details
# エラーログの確認。mysqlへ接続できなくなっている状態。
[ec2-user@ip-172-31-45-306 <リポジトリ名>]$ less log/unicorn.stderr.log
ERROR -- : Can't connect to local MySQL server through socket '/tmp/mysql.sock'
config/database.yml を編集
production:
<<: *default
database: ~~~(ここは編集しない)
username: root
password: <%= ENV['DATABASE_PASSWORD'] %>
socket: /var/lib/mysql/mysql.sock
ターミナル(EC2サーバ)
[ec2-user@ip-172-31-45-306 <リポジトリ名>] git pull origin master
# データベース作成
[ec2-user@ip-172-31-45-306 <リポジトリ名>]$ rails db:create RAILS_ENV=production
Created database '<データベース名>'
# マイグレーション実行
[ec2-user@ip-172-31-45-306 <リポジトリ名>]$ rails db:migrate RAILS_ENV=production
# 上記コマンドでエラーが出た場合。mysqlが起動していない可能性があるので下記を実行。
$ sudo service mysqld start
# Railsを再起動
[ec2-user@ip-172-31-45-306 <リポジトリ名>]$ bundle exec unicorn_rails -c config/unicorn.rb -E production -Dブラウザで http://<サーバに紐付けたElastic IP>:3000/ にアクセス
・ブラウザで http: // <Elastic IP>:3000 / にアクセス。
ビューが崩れている画面が表示されればOK。
ターミナル(EC2サーバ)
# 事前にアセットをコンパイルする必要があるので実行。
[ec2-user@ip-172-31-45-306 <リポジトリ名>]$ rails assets:precompile RAILS_ENV=production
# unicornのプロセスを確認。 psコマンド は、プロセス確認コマンド。 aux psコマンドのオプション。
# | grep unicorn はunicorn関連のプロセスを抽出。
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ps aux | grep unicorn
# 左から2番目がPID。unicorn_rails masterがプロセス本体。本体のPIDをコピー。
ec2-user 21515 0.4 15.1 588442 180840 ? Sl 01:09 0:06 unicorn_rails master -c config/unicorn.rb -E production -D
ec2-user 21529 0.0 13.3 589068 170164 ? Sl 01:00 0:06 unicorn_rails worker[0] -c config/unicorn.rb -E production -D
ec2-user 21622 0.0 0.2 110535 2185 pts/0 S+ 08:05 0:00 grep --color=auto unicorn
# killコマンドはプロセスを停止させる。
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill <上記PID>
# 再度プロセス確認。下記成功例。
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ps aux | grep unicorn
ec2-user 21622 0.0 0.2 110535 2185 pts/0 S+ 08:05 0:00 grep --color=auto unicorn
# 下記が残っていれば停止失敗
ec2-user 21515 0.4 15.1 588442 180840 ? Sl 01:09 0:06 unicorn_rails master -c config/unicorn.rb -E production -D
ec2-user 21529 0.0 13.3 589068 170164 ? Sl 01:00 0:06 unicorn_rails worker[0] -c config/unicorn.rb -E production -D
# 下記で強制終了
$ kill -9 [PID]
ターミナル(EC2サーバ)
# unicorn再起動
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -D
http://<Elastic IP>:3000/ アクセスでビューが崩れがなければOK。
通常のログの確認方法
ターミナル(EC2サーバ)
# 正常に動いているログも確認できる。 tailコマンド 指定したファイルの最後の行を表示する。
-fオプションを追加すると、リアルタイムに更新される。 tail -fコマンドの終了は ctrl+c。
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$tail -f log/production.log
次回は Nginx の導入。
この記事が気に入ったらサポートをしてみませんか?