甘党エンジニアのkanjiです。
前回に引き続き、AWSを用いたデプロイ・本番環境の構築の流れついて順を追って書いていく。
第1弾では「AWSのアカウント作成」から「データベースの設定」までをまとめた。

今回は「開発したアプリケーションを全世界に公開(デプロイ)する手順」を設定する所までがゴールである。
GithubにSSH鍵を登録する
EC2インスタンスからGithubにアクセスするために、作成したEC2インスタンスのSSH公開鍵をGithubに登録する必要がある。
GitHubに公開鍵を登録することで身分提示(私は〇〇のEC2インスタンスです)となり、コードのクローンを許可してくれるようになる。
まずは以下のコマンド入力して、EC2サーバのSSH鍵ペアを作成する。
※途中で 「passphrase」 というものの入力を求めらるが、空のままで大丈夫。
[ec2-user@ip-555-432-111 ~]$ 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公開鍵を表示し、値(2行目以下)をコピーする。
[ec2-user@ip-555-432-111 ~]$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2E..............
以下GitHubのURLにアクセスし、先程catコマンドで表示させた公開鍵を登録する。
https://github.com/settings/keys
2.Key:公開鍵を貼り付ける
3.「Add SSH Key」を押して保存
Githubに鍵を登録できたら、以下のコマンドでSSH接続できるか確認。
下記の表示がされていればOK
[ec2-user@ip-555-432-111 ~]$ ssh -T git@github.com
Hi <Githubユーザー名>/<リポジトリ名>! You've successfully authenticated, but GitHub does not provide shell access.
アプリケーションサーバ※の設定
全世界からアクセスできるように設定するために、unicorn_railsコマンドで起動する。
まずはUnicornをインストールするため、Gemfileを下記のように編集
group :production do
gem 'unicorn', '5.4.1'
end
編集後はターミナルからbundle installコマンドを打つ。
次に、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を行う。
続いて、Unicornの設定を済ませたコードをEC2インスタンスにクローンする。
以下のコマンドを入力して、ディレクトリを作成。ディレクトリ内にアプリケーションを設置する。
(※必ずしもこの場所じゃなくてOK)
#mkdirコマンドで新たにディレクトリを作成
[ec2-user@ip-555-432-111 ~]$ sudo mkdir /var/www/
#作成したwwwディレクトリの権限をec2-userに変更
[ec2-user@ip-555-432-111 ~]$ sudo chown ec2-user /var/www/
完了したら、Githubから「リポジトリURL」を取得。
取得した「リポジトリURL」を使って、コードをクローンする。
[ec2-user@ip-555-432-111 ~]$ cd /var/www/
[ec2-user@ip-555-432-111 www]$ git clone https://github.com/<リポジトリ名>.git
本番環境での設定
アプリケーションのコードをEC2サーバにクローン出来たので、サービスを公開するための設定を行っていく。
まずはローカルのアプリでbundlerのバージョンを確認する。
#ローカルのアプリのディレクトリで以下を実行
$ bundler -v
Bundler version 2.0.2
# 開発環境によってバージョンは異なります。
開発環境で仕様しているbundlerのバージョンがわかった後は、同じバージョンのものをEC2サーバ側にも導入する。
bundlerをインストールする
※上記の場合では、bundler 2.0.2のバージョンを導入して bundle install を実行。
[ec2-user@ip-555-432-111 <リポジトリ名>]$ gem install bundler -v 2.0.2
# ローカルで確認したbundlerのバージョンを導入する
[ec2-user@ip-555-432-111 <リポジトリ名>]$ bundle install
環境変数の設定
データベースのパスワードなどGithubに公開したくない情報は、環境変数を利用して設定する。
環境変数は、Railsからは ENV[’<環境変数名>’] という記述でその値を利用することができる。
例えば <%= ENV[“SECRET_KEY_BASE”] %> と書かれている部分は、 SECRET_KEY_BASE という環境変数の値になる。
また外部に漏らしてはいけない値であるため、こちらも環境変数から参照する。
以下のコマンドを打ち、secret_key_baseを生成・コピーする。
[ec2-user@ip-555-432-111 <リポジトリ名>]$ rake secret
37158d8a7ea4i55bf2e1c87ec5e04341f42f23eba8e54e97da54813ab06dc89af29d5718eacc45d2b90b3511d3e1c143fc61baacfbf4ca2c6fea608cbc8a4a35e8a
このsecret_key_baseを、EC2インスタンスに設定する。
今回は/etc/environmentというファイルに保存することで、サーバ全体に適用される。
環境変数の書き込みはvimコマンドを使用して行う。
以下のコマンドを打ち、環境変数を設定する。
[ec2-user@ip-555-432-111 〜]$ sudo vim /etc/environment
vimの画面になれば、「i」と打ち込んで入力モードに切り替えた後、下記の記述を打ち込む。
#前章で設定したMySQLのrootユーザーのパスワードを入力
DATABASE_PASSWORD='MySQLのrootユーザーのパスワード'
SECRET_KEY_BASE='先程コピーしたsecret_key_base'
書き込みができたら 「esc(エスケープキー)→:wq」と入力して内容を保存し、保存できたら環境変数を適用するために一旦ログアウトする。
[ec2-user@ip-555-432-111 〜]$ exit
logout
Connection to 52.xx.xx.xx closed.
ログアウトした後は再度SSHし直し、env というコマンドと grep を組み合わせて、先程設定した環境変数が適用されているか確認する。
$ ssh -i [ダウンロードした鍵の名前].pem ec2-user@[作成したEC2インスタンスと紐付けたElastic IP]
(ダウンロードした鍵を用いて、ec2-userとしてログイン)
[ec2-user@ip-555-432-111 ~]$ env | grep SECRET_KEY_BASE
SECRET_KEY_BASE='secret_key_base'
[ec2-user@ip-555-432-111 ~]$ env | grep DATABASE_PASSWORD
DATABASE_PASSWORD='MySQLのrootユーザーのパスワード'
ポートの解放
立ち上げたばかりのEC2インスタンスは、HTTPなどの他の通信方法ではつながらないようになっている。
そのため、WEBサーバとして利用するEC2インスタンスが事前にHTTPがつながるよう、「ポート」を開放する設定を行う。
ポートの設定をするためにはEC2の「セキュリティグループ」という設定を変更する。
1.AWSのインスタンス画面から「セキュリティグループのリンク」をクリック
2.「インバウンド」タブの中の「編集」をクリック
3.モーダルが開くので、「ルールの追加」をクリック
タイプを「カスタムTCPルール」、プロトコルを「TCP」、ポート範囲を「3000」、送信元を「カスタム / 0.0.0.0」に設定する。
Railsを起動する
unicorn_rails というコマンドが使えるようになっているので、以下のコマンド(EC2サーバ)を実行する。
[ec2-user@ip-555-432-111 〜]$ cd /var/www/[リポジトリ]
[ec2-user@ip-555-432-111 <リポジトリ名>]$ unicorn_rails -c config/unicorn.rb -E production -D
しかし現状このコマンドを実行すると、以下のようにすぐにコマンドが終了してしまう。
[ec2-user@ip-555-432-111 [リポジトリ]]$ master failed to start, check stderr log for details
これはデータベースを作成していないことが起動しない原因となっているため、データベース作成の設定を行う。
データベース作成の前にアプリケーションのdatabase.ymlをローカル環境で編集する。
production:
<<: *default
database: ~~~(アプリケーション名によって異なる。こちらは編集しないこと)
username: root
password: <%= ENV['DATABASE_PASSWORD'] %>
socket: /var/lib/mysql/mysql.sock
ローカルでの編集をコミットして、GitHubにプッシュする。
リモートリポジトリが更新されたため、サーバ上のアプリケーションにも反映させる。
サーバのアプリケーションのあるディレクトリで以下のようにコマンドを実行する。
[ec2-user@ip-555-432-111 <リポジトリ名>]$ git pull origin master
続いてデータベースを作成しマイグレーションを実行し直す。
[ec2-user@ip-555-432-111 <リポジトリ名>]$ rails db:create
Created database '<データベース名>'
[ec2-user@ip-555-432-111 <リポジトリ名>]$ rails db:migrate RAILS_ENV=production
データベースの準備が整ったので、再びRailsを起動する。
[ec2-user@ip-555-432-111 <リポジトリ名>]$ unicorn_rails -c config/unicorn.rb -E production -D
ブラウザで http://<サーバに紐付けたElastic IP>:3000/ にアクセスし、ブラウザに画面が表示されていれば成功。
しかし現時点ではレイアウトが崩れているとので、アセットファイルのコンパイルを行う。
アセットファイルのコンパイル
本番モードで事前にアセットをコンパイルするため、次のコマンドを実行する。
[ec2-user@ip-555-432-111 <リポジトリ名>]$ rails assets:precompile
コンパイルが成功したらRailsを再起動する。
まずは「ps」コマンドを打ち込み、現在動いているプロセスの確認を行う。今回はunicornのプロセスのみを抽出するため、下記コマンドを入力。
[ec2-user@ip-555-432-111 <リポジトリ名>]$ ps aux | grep unicorn
下記のようにプロセスが表示(数字はバラバラ)されていれば成功
ec2-user 13544 0.4 18.1 588472 182840 ? Sl 01:55 0:02 unicorn_rails master -c config/unicorn.rb -E production -D
ec2-user 13548 0.0 17.3 589088 175164 ? Sl 01:55 0:00 unicorn_rails worker[0] -c config/unicorn.rb -E production -D
ec2-user 13555 0.0 0.2 110532 2180 pts/0 S+ 02:05 0:00 grep --color=auto unicorn
プロセスが確認できたら、「kill」コマンドを入力し現在動いているプロセスを停止させる。
[ec2-user@ip-555-432-111 <リポジトリ名>]$ kill -9 <確認したunicorn rails masterのPID>
これはローカルで行なっていたctrl + cでサーバをストップする作業と同じことをしたことになる。
Unicornを停止することができたら、再びunicornを起動させる。
このとき 「RAILS_SERVE_STATIC_FILES=1」 という指定を先頭に追加する。
こうすることで、コンパイルされたアセットをRailsが見つけられるような指定になる。
[ec2-user@ip-555-432-111 <リポジトリ名>]$ RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -D
...
再度ブラウザで http://<Elastic IP>:3000/ にアクセスし、レイアウト崩れなくサイトが正常に表示されていれば成功。
次回(3)はここまでの流れを自動化するための「自動デプロイ」についてまとめたので、(2)が終わった方はお進み頂きたい。

コメントを残す