#EC2インスタンスの作成
AWSのサーバーであるEC2インスタンスの作成をしていきます。
AWSアカウントのリージョン設定をしよう
リージョンとは、AWSの物理的なサーバの場所を指定するものです。リージョンは世界各地に10箇所以上存在し、そのうちの一つは東京にあります。
リージョンを東京に設定していきましょう
手順
EC2インスタンスを作成
「サーバーを生成する」といっても、AWSが全てのサーバを物理的に用意しているわけではなく、実際には「仮想マシン」と呼ばれるソフトウェアを利用しています。
この「仮想マシン」のことをAWSでは「EC2インスタンス」と呼んでいます。
手順
-
AWSにアクセス
-
「 Amazon Linux2 AMI 」ではなく、「 Amazon Linux AMI 」を選択してください。
(上から2番目にあります)
-
無料枠で利用できる「t2.micro」を選択し、画面右下の 『確認と作成』 をクリック
( EC2インスタンスのタイプを選択します。EC2ではさまざまなインスタンスタイプが用意されており、CPUやメモリなどのスペックを柔軟に指定することができます。) -
キーペア名を入力(空白NG)
-
キーペアのダウンロード(ファイル名.pem)
🚨注意:こちらはインスタンスにSSHでログインする際に必要となる「秘密鍵」です。これがないとEC2インスタンスにログインできないので、必ずダウンロードしてパソコンに保存しておきましょう。また、間違って他人に渡さないよう気をつけてください。
ダウンロードしたpemキー(ファイル名.pem)のsshフォルダに移行する
$ cd ~
#ターミナルをスタート地点に戻す
$ mkdir ~/.ssh
#.sshというディレクトリを作成
# エラー『 mkdir: /Users/owner/.ssh: File exists 』と表示の場合、すでに存在します
$ mv Downloads/ファイル名.pem .ssh/
# mvコマンドで、移動させたい対象(ファイル名.pem) → .sshディレクトリに移動します。
$ cd .ssh/
$ ls
# pemファイルが存在するか確認します
12.画面右下の『インスタンスの作成』をクリック
13. 作成完了(反映に時間がかかる場合があります)
14.次のインスタンスの作成がされました: 『 i- 』のインスタンスIDをクリック
15. 作成したインスタンスがrunningと表示されて、稼働している
完了
次は『 Elastic IPの作成と紐付け 』をしよう
先ほど作成したEC2インスタンスには、作成時にIPアドレスが自動で割り振られています。これをパブリックIPと言います。しかし、サーバーを再起動させるたびにこのパブリックIPが変わってしまうという欠点を持っています。
次回はその欠点を改善するために、『 Elastic IPの作成と紐付け 』をしていきましょう。
#EC2インスタンスをElastic IPで固定
作成したEC2インスタンスには、作成時にIPアドレスが""自動""で割り振られています。
これをパブリックIP(一般公開用のID)と言います。
しかし、""サーバーを再起動させるたびにこのパブリックIPが変わってしまうという欠点""を持っています。
そのため、パブリックIDを固定して、いちいち更新しないようにします。
この固定化したパブリックIDを『 Elastic IP 』と呼びます。
今回はその欠点を改善するために、『 EC2インスンタンスとElastic IP紐付け 』をしていきましょう。
Elastic IPの作成
EC2インスタンスのパブリックIPアドレスをElastic IPに固定する。
Elastic IPとは、AWSから割り振られた固定したパブリックIPアドレス。
このパブリックIPアドレスをEC2インスタンスに紐付けることで、インスタンスの起動、停止に関わらず常に同じIPアドレスで通信をすることが可能になります
手順
-
AWSのサイドナビにある、『Elastic IP』をクリック。こちらからでも進めます
Elastic IPアドレスは、パブリック IPv4 アドレスの項目にも記載されています(公開するわけにはいかないので伏せています)
Elastic IPアドレスとEC2インスタンスと紐付け
ここからEC2インスタンスとElastic IPアドレスを紐付けします。
紐付けが完了すれば、EC2インスタンスのパブリックIPは、Elastic IPアドレスで固定されます
手順
-
Elastic IPアドレスを選択✅
-
作成したEC2インスタンスを選択
補足:上の画像のようにインスタンスを選択すると、その下にあるプライベートIPアドレスが自動で選択されます。なのでプライベートIPアドレスは空白で大丈夫です
無事に関連づけられたインスタンスに『i- (EC2インスタンスID)』が表示されています
次は AWS セキュリティグループの設定
立ち上げたばかりのEC2インスタンスはSSHでアクセスすることはできますが、HTTPなどの他の接続は一切つながらないようになっています。そのため、WEBサーバとして利用するEC2インスタンスは事前にHTTPがつながるように「ポート」を開放する必要があります
次回はポート解放の操作をお伝えしていきたいと思います。
AWSセキュリティグループの設定
前回までの流れ
作成したEC2インスタンスとElastic IPを紐付けして、パブリックIPを固定にした。
今回の流れ
###現状
現時点において、HTTP(www.サイトURL)で接続することはできない。
(ターミナルでEC2とSSH接続は可能。)
つまり、一般ユーザーは閲覧することはできない状態である。
なので、今回はHTTP接続(www.)を解放して、URLでサイトを閲覧できるようにしていく。
現実で比喩
従業員は店舗に入れるけど、お店は開店させていないので、お客さんは入店できない。
>入り口を解放する必要がある
ポート(入り口)の解放
このHTTP接続(www.)の入り口となるのが、「ポート」(扉)と呼ばれます。IPアドレスが住所「家」であれば、ポートは外に出る・外から入る「扉(ドア)」に該当します。
ポートの設定をするためには、「セキュリティグループ」という設定を変更していきましょう
本題、セキュリティグループの設定
セキュリティグループとは、AWSのファイアウォール機能の一つ。
プロトコル、ポート範囲、送信元/送信先IPアドレスによるパケットフィルターが可能。
インスタンス単位に適用することができる。
手順
-
セキュリティグループの『launch-wizard-3』をクリック
補足: インバウンドルール(この後追加します)
そのセキュリティグループに関連付けられたインスタンスにアクセスできるトラフィックを規制する。『インバウンドルールの表示』をクリックすると下記が表示される。
補足: アウトバウンドルール(この後追加します)
そのセキュリティグループに関連付けられたインスタンスからどの送信先にトラフィックを送信できるか(トラフィックの送信先と送信先ポート)を制御するルール
『アウトバウンドルールの表示』をクリックすると下記が表示される。
(ここから、セキュリティグループの『launch-wizard-3』をクリック後に続く)
5. 下記の画面が表示される
6.『 インバウンド 』を選択
7. 『 編集 』をクリック
8. 左下の『ルールの追加』をクリック
9. タイプ:『 HTTP 』を選択
10. 画面左下の『 保存 』をクリック
11. 完了
これでIPアドレス、WWW.やドメインでのWEB閲覧が可能となります。
次はEC2にSSHログインしていきましょう!
ここまで、お疲れ様でした。
なかなか慣れない作業で疲れたのではないでしょうか?
セキュリティグループについては、下記記載のAWSのセキュリティグループリファレンスを参照してみるといいかもしれません。
次回は自身で作成したWEBアプリとEC2サーバーを紐づけていくために、SSHログインしましょう
次回の記事はこちら!
はじめてAWSでデプロイする方法④(EC2にSSHログイン)
参考
【AWS】セキュリティグループを設定してみた
AWS公式-セキュリティグループのルールのリファレンス
#EC2インスンタンスにSSHログイン
EC2インスタンス(サーバー)を作成し、パブリックIPをElastic IPで固定。
一般ユーザーがアクセスできるように、セキュリティグループの設定を追加(入り口を作成)
ざっくり説明すると、こんなところです。
今回実施すること
今回はEC2上にRailsやMySQLなどをインストールする、つまり環境構築をするために、SSH接続でEC2にログインをしていきます。
EC2にログインするにはどうすればいいのか?
IDとPWが必要です。
ID = Elastic IP(パブリックIP)
PW = pemキー(EC2インスタンス作成時にダウンロードしたファイル)
上記2点を利用して、ログインしていきますが、その方法を解説していきます
EC2インスタンスにログインする
ここからは、実際にログインする説明をしていきます。
始める前の前提条件
EC2インスタンスを作成すると、ec2-userというユーザーと対応するSSH秘密鍵が生成されます。
このアカウントは管理者権限が強いので、本来であればこのec2-userではなく、権限を小さいアカウント使って運用します。
まずは基本を掴むために、このec2-userを使って作業を進めていきます。
保存しておいた(ファイル名.pem)のアクセス権限の制限
SSH接続でログインをするために、暗号化キーである,ファイル名.pemを保護したいと思います。
pemキー(ファイル名.pem)は,
はじめてAWSでデプロイする方法①(インスタンスの作成)でインスタンス作成時にダウンロードしたファイルです
このファイルに秘密鍵が記載されるので、不正利用されないように、アクセス制限をかけます。
このファイルは、、他者に閲覧されないように制限をかけることが目的です。このファイルやディレクトリのアクセス権の設定することをパーミッション(許諾)と呼びます。
パーミッション(ファイルのアクセス制限)をするには、 $ chmod コマンドを利用します。
手順
$ cd ~/.ssh
$ ls
# pemファイルが存在するか確認しましょう
# ない場合は、『はじめてAWSでデプロイする方法①(インスタンスの作成)』を振り返ってください
$ chmod 600 ダウンロードした鍵の名前.pem
この$ chmod 600の解説をしたいと思います。
まず、chmodはアクセス制限をかけるパーミッションを設定するためのコマンドとお伝えしました。600は『 誰に 』どんな権限を与えるのか設定しています。
誰に?は下記になります。
- 100桁は『所有者の権限設定』
- 10桁は『グループの権限設定』
- 1桁は『その他のユーザーの権限設定』
$ chmod 600の場合
6 = 『所有者の権限設定』
0 = 『グループの権限設定』
0 = 『その他のユーザーの権限設定』
『 どんな権限を与えるのか? 』は下記になります
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
--- | --x | -w- | -wx | r-- | r-x | rw- | rwx |
r = read = 読む(閲覧)権限
w = write = 書く(入力、編集)権限
x = 実行する権限
6 はrw 読み書きの権限を与えます。
0は一切の権限がありません。
$ chmod 600の場合
『所有者の権限設定』 = 6 = rw- = 読み書き
『グループの権限設定』 = 0 = --- = 権限なし
『その他のユーザーの権限設定』 = 0 = --- = 権限なし
もう一度見てみましょう
$chmod 600 webapp.pem
webapp.pemは、
『所有者権限』 6 = rw = 読み書きが可能
『グループ権限』 0 = 権限なし
『他ユーザの権限』 0 = 権限なし
#注意:この操作をしていないと、sshでログインができません。
(xの実行を入れていないのは、ファイル名.pemが何かのプログラムを実行するファイルではないため。700でも可能)
詳細については、下記の記事を参考にしてください
Macターミナルコマンド「chmod」の使い方
参考:chmod コマンド
ファイル名.pemに制限をかけたところで、安心してログインしていきましょう!
SSH接続による、ログイン
pemキーの制限をかけたところで、ログインを実際にしていきます。
$ cd ~/.ssh
# .sshディレクトリに移行
.ssh $ ls
# .sshディレクトリに無事にpemキーが入っているのか確認
.ssh $ ssh -i ファイル名.pem ec2-user@Elastic IP(EC2インスタンスと紐付けた)
#例
# 条件: 『 pemキー = webapp.pem 』、 『 Elastic IP = 123.456.789 』 であれば
# 実行コマンド: ssh -i webapp.pem ec2-user@123.456.789
# pemキーはlsコマンドで、ファイルの一覧が表示されるので、そこからコピーしましょう
Elastic IPの確認
- EC2を開く
- 実行中のインスタスを開く
3. 下記写真の右下に、『 Elastic IP: 』と記載されているのでコピー
これでログイン完了です👍
お疲れ様でした!!!
エラーが出る場合は、下記を確認ください。
エラーが表示された場合
エラー「-bash: shh: command not found」が表示された場合
Elastic IPの「●●.●●●.●●●.●●●*」の最後のアスタリスクは不要
下記写真の右下に、『 Elastic IP: 』と記載されているので、ここでコピーしましょう!
エラー「WARNING: UNPROTECTED PRIVATE KEY FILE!」 の場合
答え2: pemキーがchmodでパーミッションされていません。
>操作手順を上に戻って、chmodコマンドでパーミッションを実施してください。
エラー「Warning: Identity file : No such file or directory.Permission denied (publickey).」
答え: sshコマンドを実施する場所が間違っている
>sshディレクトリ上で実施する必要があるが、sshディレクトリをターミナルで開いていない。
$cd ~/.ssh
.ssh $ ssh -i ファイル名.pem ec2-user@Elastic IP(EC2インスタンスと紐付けた)
#例
# 条件: 『 pemキー = webapp.pem 』、 『 Elastic IP = 123.456.789 』 であれば
# 実行コマンド: $ shh -i webapp.pem ec2-user@123.456.789
# pemキーはlsコマンドで、ファイルの一覧が表示されるので、そこからコピーしましょう
次回はログイン後の環境構築を実施していきましょう!
ここまで、お疲れ様でした
ログインできた達成感を味わっていただけましたか?
次回は、EC2にログイン後の操作(環境構築)をしていきたいと思います
EC2の環境構築(Ruby, MySQL, etc)
EC2インスタンス(サーバー)を作成し、パブリックIPをElastic IPで固定。
一般ユーザーがアクセスできるように、セキュリティグループの設定を追加(入り口を作成)
IDとPWを使って、EC2にログイン
ざっくり説明すると、こんなところです。
今回の内容
ssh接続でログインをして、環境構築をする。
[ec2-user@ip-172-31-25-189 ~]$ sudo yum -y update
[ec2-user@ip-172-31-25-189 ~]$ sudo yum -y install git make gcc-c++ patch libyaml-devel libffi-devel libicu-devel zlib-devel readline-devel libxml2-devel libxslt-devel ImageMagick ImageMagick-devel openssl-devel
Node.jsをインストール
[ec2-user@ip-172-31-25-189 ~]$ sudo curl -sL https://rpm.nodesource.com/setup_6.x | sudo bash -
※追記:下記の表示が出ますが、setup_6.xのサポートが終了したので、別のバージョンを推奨する表示となります。
[ec2-user@ip-172-31-25-189 ~]$ sudo yum -y install nodejs
rbenvとruby-buildをインストール
[ec2-user@ip-172-31-25-189 ~]$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
[ec2-user@ip-172-31-25-189 ~]$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
[ec2-user@ip-172-31-25-189 ~]$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
[ec2-user@ip-172-31-25-189 ~]$ source .bash_profile
上記をしないと エラー『 -bash: rbenv: コマンドが見つかりません 』が表示
[ec2-user@ip-172-31-25-189 ~]$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
[ec2-user@ip-172-31-25-189 ~]$ rbenv rehash
Rubyをインストール
[ec2-user@ip-172-31-25-189 ~]$ rbenv install 2.5.1
ここでエラー
「-bash: rbenv: コマンドが見つかりません」が表示された場合、
rbenvとruby-buildをインストールを見直してください。
[ec2-user@ip-172-31-25-189 ~]$ rbenv global 2.5.1
[ec2-user@ip-172-31-25-189 ~]$ rbenv rehash
[ec2-user@ip-172-31-25-189 ~]$ ruby -v
無事にインストールされています
MySQLをインストール
[ec2-user@ip-172-31-25-189 ~]$ sudo yum -y install mysql56-server mysql56-devel mysql56
(mysql56は、MySQLのバージョン5.6をインストールすることを意味)
MySQLを起動
[ec2-user@ip-172-31-25-189 ~]$ sudo service mysqld start
MySQLの起動確認
[ec2-user@ip-172-31-25-189 ~]$ sudo service mysqld status
MySQLのrootパスワードの設定
この操作はPW設定をします
>PWを入力してから、コマンドを実行してください
[ec2-user@ip-172-31-25-189 ~]$ sudo /usr/libexec/mysql56/mysqladmin -u root password 'PWを入力'
Warning: Using a password on the command line interface can be insecure.
翻訳「警告:コマンドラインインターフェイスでパスワードを使用することは安全ではありません。」
これに関しては下記の資料をご確認ください
資料1
資料2
ここでエラーが表示された場合
EC2 MySQL 初期設定 root にパスワードの設定
MySQLに接続(ターミナルでコマンド操作可能)
[ec2-user@ip-172-31-25-189 ~]$ mysql -u root -p
ここでPWが要求されます。
>登録したPWを入力してみて、無事に開かれるか確認しましょう!
PWが正しく登録できたことを確認できたので、
$ exit
でMySQLの接続を解除しましょう
EC2インスタンスにAppをクローンしてアップロード
EC2インスタンス(サーバー)を作成し、パブリックIPをElastic IPで固定。
一般ユーザーがアクセスできるように、セキュリティグループの設定を追加(入り口を作成)
IDとPWを使って、EC2にログインして、環境構築をしました。
ざっくり説明すると、こんなところです。
今回はWEB AppをEC2インスタンスにアップロードしていきます。
WEB AppをEC2にクローンする
現段階
EC2サーバにアプリケーションのコードをクローンしようとしてもpermission deniedとエラーが出てしまいます。
原因
Githubから見てこの許可していないEC2インスタンスを拒否する
対策
EC2インスタンスのSSH公開鍵をGithubに登録する。
SSH鍵をGithubに登録すると、Githubはそれを認証してクローンを許可をだす
作業
EC2サーバのSSH鍵ペアを作成
- EC2にログイン
- キーペア作成のためコマンドを入力
[ec2-user@ip-172-31-23-189 ~]$ ssh-keygen -t rsa -b 4096
3.下記が表示されるので、エンターを押す
Enter file in which to save the key (/home/ec2-user/.ssh/id_rsa):
4.さらにエンターを押す(2回)
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 |
+-----------------+
5.SSH公開鍵を表示し、値をコピーするため、下記コマンドを実装
[ec2-user@ip-172-31-23-189 ~]$ cat ~/.ssh/id_rsa.pub
コピーした公開鍵をGithubにアクセスして登録する
2. 画面右上の緑色の『 NEW SSH KEY 』をクリック
3. タイトルを記入する(なんでも可能)
4. 公開鍵(ssh-rsaから)を貼り付け
エラー「Key is invalid. You must supply a key in OpenSSH public key format」が表示された場合、
貼り付けたコードに『 ssh-rsa 』が含まれているかご確認ください
5. 『 Add SSH KEY 』をクリックして保存。
6. GithubのPWを入力
7. 完了
8. 登録できているか確認
[ec2-user@ip-172-31-23-189 ~]$ ssh -T git@github.com
下記の表示が出た場合: 『 yes 』を選択
The authenticity of host 'github.com (IP ADDRESS)' can't be established.
RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)?
この際に
Warning: Permanently added the RSA host key for IP address '52.111.11.11' to the list of known hosts.
と表示された場合は, EC2に入り直しましょう。更新されたのでエラーなく入れます。
成功すると、下記の表示になるはずです。
または、下記が表示された場合: 『 yes 』を選択
The authenticity of host 'github.com (IP ADDRESS)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)?
成功すると下記の表示が出る
[ec2-user@ip-172-31-23-189 ~]$ ssh -T git@github.com
Hi <Githubユーザー名>! You've successfully authenticated, but GitHub does not provide shell access.
App側でUnicornのインストール
EC2にGit クローンする前に、準備としてUnicornをインストールさせましょう
Gemfileにgem'unicorn'を追加
group :production do
gem 'unicorn', '5.4.1'
end
bundle installでインストール
$ bundle install
config/unicorn.rbを作成
追加した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
production.rbを開き、下記の記述をコメントアウトする
config.assets.js_compressor = :uglifier
#config.assets.js_compressor = :uglifier
アプリケーションの保存先となるディレクトリを作成
ディレクトリの作成
#/var/wwwディレクトリを作成(後述するCapistranoの初期値がwwwなので、ディレクトリをwwwに設定しています)
[ec2-user@ip-172-31-23-189 ~]$ sudo mkdir /var/www/
作成したディレクトリをchownコマンドで権限設定
#作成したwwwディレクトリの権限をec2-userに変更
[ec2-user@ip-172-31-23-189 ~]$ sudo chown ec2-user /var/www/
作成したディレクトリに移行
[ec2-user@ip-172-31-23-189 ~]$ cd /var/www/
git clone でAppをEC2にダウンロード
GithubからGit cloneするためのリポジトリURLを取得
git clone で作成したディレクトリにappをクローン
[ec2-user@ip-172-31-23-189 www]$ git clone リポジトリURL
Githubのアカウント名とPWを入力し、
ダウロードが開始される
remote: Enumerating objects: 298, done.
remote: Counting objects: 100% (298/298), done.
remote: Compressing objects: 100% (190/190), done.
remote: Total 298 (delta 109), reused 274 (delta 86), pack-reused 0
Receiving objects: 100% (298/298), 58.53 KiB | 365.00 KiB/s, done.
Resolving deltas: 100% (109/109), done.
完了
これで、EC2にAppがクローンされています。
EC2にgemをインストール
EC2のメモリを増強する
Swap(スワップ)領域を設定
Swapは、EC2のメモリが限界に達したとき、補う形でメモリの容量を増やす機能です。
デフォルトではSwap領域が設定されていないので、設定しましょう
手順
ホームディレクトリに移行
[ec2-user@ip-172-31-25-189 ~]$ cd
下記のコマンドを実行
[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) コピーされました、 5.19011 秒、 103 MB/秒
次は権限に制限をかけましょう(chmodコマンド)
[ec2-user@ip-172-31-25-189 ~]$ sudo chmod 600 /swapfile1
スワップ(swap)領域を作成する - mkswap
[ec2-user@ip-172-31-25-189 ~]$ sudo mkswap /swapfile1
#成功すると下記の表示が出ます
スワップ空間バージョン1を設定します、サイズ = 524284 KiB
ラベルはありません, UUID=74a961ba-7a33-4c18-b1cd-9779bcda8ab1
スワップ(swap)領域を有効化する - swapon
[ec2-user@ip-172-31-25-189 ~]$ sudo swapon /swapfile1
エラーが出なければ成功です。
エラー「swapon: /swapfile1: スワップヘッダの読み込みに失敗しました: 無効な引数です」が表示された場合は、一つ前の手順に戻ってmkswapコマンドを実施してください。
下記のコマンドを実施してください。
🚨長いので、気をつけてください
[ec2-user@ip-172-31-25-189 ~]$ sudo sh -c 'echo "/swapfile1 none swap sw 0 0" >> /etc/fstab'
これで完了
gemのインストール
まずは、EC2にダウンロードしたWEB Appを開く
[ec2-user@ip-172-31-23-189 www]$ cd /var/www(作成したディレクトリ)/アプリ名
Rubyのバージョンを確認する
[ec2-user@ip-172-31-23-189 <アプリ名>]$ ruby -v
指定したrubyのバージョンが表示されれば成功です。
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
ローカル上のターミナルでbundlerのバージョンを確認する
EC2ではなく、ローカル環境のWEB Appを開き、下記コマンドを実施
$ bundler -v
するとバージョンが表示されます
Bundler version 2.0.2
これと同じバージョンをEC2で入れます。
🚨下記のバージョンをそのまま (2.0.1)を入れるとエラーが発生するので注意
[ec2-user@ip-172-31-23-189 <アプリ名>]$ gem install bundler -v 2.0.1
EC2でbundle installをして、gemをインストール
[ec2-user@ip-172-31-23-189 <アプリ名>]$ bundle install
エラーがなければ、gemのインストール完了です。
エラーが発生した場合
下記のエラーが表示された場合、インストールするべき bundler -vが間違っています
Traceback (most recent call last):
2: from /home/ec2-user/.rbenv/versions/2.5.1/bin/bundle:23:in `<main>'
1: from /home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:308:in `activate_bin_path'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)
エラーがある場合は、アプリ側の bundlerのバージョンを確認してください
$ bundler -v
>Bundler version 2.0.2
[ec2-user@ip-172-31-23-189 <アプリ名>]$ bundler -v
>Bundler version 2.0.1
>バージョンが違うので、エラーがおきます
インストール完了後、下記の表示があった場合
Post-install message from chromedriver-helper:
+--------------------------------------------------------------------+
| |
| NOTICE: chromedriver-helper is deprecated after 2019-03-31. |
| |
| Please update to use the 'webdrivers' gem instead. |
| See https://github.com/flavorjones/chromedriver-helper/issues/83 |
| |
+--------------------------------------------------------------------+
gem'chromedriver-helper'のサポートが終了しているので、代わりとなるgem 'webdrivers'をインストールすることを推奨しているメッセージとなります。
group :test do
# ...
- gem 'chromedriver-helper'
+ gem 'webdrivers'
環境変数の設定
前回までの流れ
EC2インスタンスを作成
Elastic IP でEC2インスタンスのパブリックIPを固定
セキュリティグループを編集して、HTTPでWEBサイトの入り口を作る。
EC2にRails等をインストールして、環境設定をする
いよいよAppをEC2にダウンロード(クローン)
gemをインストール
今回の内容
環境変数を設定する。
環境変数とは何か?
環境変数は簡単に説明すると、PWを公開しないための変数と思ってください。
Githubは開発するに際に非常に便利です
コードのバックアップのような役割も担うし、他の開発チームとコードを共有することができる。
しかし、PWは公開したくないはずです。
このPW(パスワード)などの公開したくない情報を環境変数というもので隠してしまいます。
変数はX=3のように 文字(X)の意味(3)を定義します。
環境変数の場合、環境変数 = 'PW' のように、パスワードを変数の値とします。
こうすることで、コードに記述されている環境変数だけでは、パスワードを特定できないので、
悪用されない仕組みとなります。
環境変数で定義したPWは、開発者のみが’鍵(暗号化を解除するための数値)’を持っており、鍵を持っている人間しか、実際の値をみることができません。
secret_key_baseの取得
secret_key_baseは「railsアプリ」でクッキーを暗号化するものになります。
クッキーとは、webを参照した時の履歴のようなものを残し、次回から素早くアクセスできるものになります。
クッキーは外部から参照されるとよくないので暗号化します。
[ec2-user@ip-172-31-23-189 <アプリ名>]$ rake secret
# うまくいくと、
cdfasdfadgfsadfdgc314751a8dadfadf7c8b9a1dc888e...
という感じで表示されます。
これをコピーしておきましょう
環境変数を設定
環境変数を記述する場所を開きましょう
[ec2-user@ip-172-31-23-189 <アプリ名>]$ sudo vim /etc/environment
すると 『 -- 挿入 -- 』と表示されるので、入力が可能となります。
では、環境変数を定義していきましょう
DATABASE_PASSWORD='MySQLのrootユーザーのパスワード'
SECRET_KEY_BASE='先程コピーしたsecret_key_base'
入力が完了したら、キーボード左上にある『 esc 』を押します。
すると挿入の表示が消えます。
保存するために 『 :wq 』 と入力しましょう
設定した環境変数を反映させるために、一度本番環境をログアウトしましょう。
[ec2-user@ip-172-31-23-189 ~]$ exit
もう一度EC2にログイン
(ターミナル上で↑を押すと、入力してきたコマンドが出てくるので、それでssh -iを見つけてエンターすれば大丈夫です)
$ ssh -i ファイル名.pem ec2-user@[Elastic IPの値]
環境変数が無事に設定されているか確認
[ec2-user@ip-172-31-23-189 ~]$ env | grep SECRET_KEY_BASE
SECRET_KEY_BASE='secret_key_base'
[ec2-user@ip-172-31-23-189 ~]$ env | grep DATABASE_PASSWORD
DATABASE_PASSWORD='MySQLのrootユーザーのパスワード'
これで以上です。
何かAPIを導入したい際は、APIの秘密鍵を同じようにして環境変数として設定します。
#Railsの起動
ポートの解放
config/unicorn.rb に listen 3000 と記述しましたが、これはRailsのサーバを3000番ポートで起動するということを意味するのでした。
HTTPがつながるように「ポート」を開放する必要があります。
手順
1.EC2を開く
2. 『実行中のインスタンス』を開く
3. インスタンスを選択
4. セキュリティグループの『launch-wizard-3』をクリック
5. 下記の画面が表示される
6.『 インバウンド 』を選択
7. 『 編集 』をクリック
8. 左下の『ルールの追加』をクリック
9. タイプ:「カスタムTCPルール」、プロトコルを「TCP」、ポート範囲を「3000」、送信元を「カスタム」「0.0.0.0/0」に設定
10. 画面左下の『 保存 』をクリック
Railsの起動
Rails 5.1以前の場合
database.ymlに下記を追加します
production:
<<: *default
database: アプリ名
username: root
password: <%= ENV['DATABASE_PASSWORD'] %>
socket: /var/lib/mysql/mysql.sock
追記が完了したら、EC2でも反映させます。
EC2とGithubは接続できているため、git pullコマンドを利用します。
[ec2-user@ip-172-31-23-189 <アプリ名>] git pull origin master
データベースの作成をする
[ec2-user@ip-172-31-23-189 <アプリ名>]$ rails db:create RAILS_ENV=production
Created database '<データベース名>'
アプリのディレクトリを開いてからコマンドを実行しましょう
#うまくいかない = アプリ名を指定していない
[ec2-user@ip-172-31-23-189 ~( ここが指定されていない )]$ rails db:create RAILS_ENV=production
Created database '<データベース名>'
#アプリ名(リポジトリ)を指定しているのでちゃんと処理がされる
[ec2-user@ip-172-31-23-189 <アプリ名>]$ rails db:create RAILS_ENV=production
Created database '<データベース名>'
rails db:migrateを実行して、migrationを完了させる。
[ec2-user@ip-172-31-23-189 <アプリ名>]$ rails db:migrate RAILS_ENV=production
エラーが出る場合
Mysql2::Error: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'というエラーが起こった場合、mysqlが起動していない可能性があります。
sudo service mysqld start
#再起動をさせたい場合は、
sudo service mysqld restart
というコマンドをターミナルから打ち込み、mysqlの起動を試してみましょう。
参考記事
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
ユニコーンを起動
[ec2-user@ip-172-31-23-189 ~]$ cd /var/www/[リポジトリ]
[ec2-user@ip-172-31-23-189 <app名>]$ bundle exec unicorn_rails -c config/unicorn.rb -E production -D
Rails5.2以降の場合
credentials.ymlの設定
アプリ名 $ EDITOR=vim bin/rails credentials:edit
すると編集画面が表示されます。
しかし文字入力ができないので、
『 i 』を押して、----INSERT----モードに変更します
下記を入力します。
db:
database: アプリ名
username: root
password: 設定したPW
socket: /var/lib/mysql/mysql.sock
passwordははじめてAWSでデプロイする方法⑤(EC2の環境構築、Ruby, MySQL)の『MySQLのrootパスワードの設定』で設定しています。
次に、database.ymlにcredential.ymlで設定した環境変数を記述します
production:
<<: *default
database: <%= Rails.application.credentials.db[:database] %>
username: <%= Rails.application.credentials.db[:username] %>
password: <%= Rails.application.credentials.db[:password] %>
socket: <%= Rails.application.credentials.db[:socket] %>
本番環境のshared/configにmaster.keyを作成
ローカル環境にある,master.keyの中身を確認する
rails newで作成された、ローカルのmaster.keyを確認する。
$ vi config/master.key
すると下記のようにmaster.keyの中身が表示されます。
fadfdfdgaf44623535y....
この表示された、master.keyの値をコピーしましょう
表示されたmaster.keyをコピーします。
これを本番環境で貼り付けていきます。
本番環境でmaster.keyを作成
EC2のアプリのconfigを開きましょう
#本番環境
[ec2-user@ip-172-31-23-189 ~]$ cd /var/ここはそれぞれ違います/[アプリ名]
[ec2-user@ip-172-31-23-189 <アプリ名>]$ cd shared/config
そうしたら、本番環境上でmaster.keyを作成します
[ec2-user@ip-172-31-23-189 config]$ vi master.key
# ローカル環境のmaster.keyの値を入力
fsdgagaf08deg424~~~~~
画像だと下記のような画面になります。
『 i 』を押すと----INSERT-----と表示がされて、文字入力ができます。
ここにコピーしたローカルのmaster.keyの値を貼り付けします。
『 esc 』ボタンを押した入力モードを終了
『 :wq 』入力して保存します
これで本番環境でもmaster.keyが設定されています。
ユニコーンを起動
[ec2-user@ip-172-31-23-189 ~]$ cd /var/www/[リポジトリ]
[ec2-user@ip-172-31-23-189 <app名>]$ bundle exec unicorn_rails -c config/unicorn.rb -E production -D
エラーが発生した場合
can't find gem bundler (>= 0.a) with executable bundle
can't find gem bundler (>= 0.a) with executable bundle 対応
原因:bundlerのバージョンが、gitcloneしたAppとEC2で異なるため失敗している。
解決策
$ bundle -v
Bundler version 2.0.2
これで2.0.2のバージョンを利用しているとわかる。
[ec2-user@ip-172-31-23-189 <app名>]$ gem install bundler -v 2.0.2
これで最後にbundle installをして完了
[ec2-user@ip-172-31-23-189 <app名>]$ bundle install
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
Mysql2::Error: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock'というエラーが起こった場合、mysqlが起動していない可能性があります。
sudo service mysqld start
#再起動をさせたい場合は、
sudo service mysqld restart
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (13)
database.ymlとcredentials.ymlの中身に漏れがないか確認をしてください
db:
database: アプリ名
username: root
password: 設定したPW
socket: /var/lib/mysql/mysql.sock
production:
<<: *default
database: <%= Rails.application.credentials.db[:database] %>
username: <%= Rails.application.credentials.db[:username] %>
password: <%= Rails.application.credentials.db[:password] %>
socket: <%= Rails.application.credentials.db[:socket] %>
#ここのsocketが抜けていないか???
サイトにアクセスしてみる
ブラウザで http://<サーバに紐付けたElastic IP>:3000/ にアクセスしてみましょう
ブラウザにCSSの反映されていない(ビューが崩れている)画面が表示されていれば成功です。
アセットコンパイルする
レイアウトが崩れてしまっているでしょう。
開発中には正常に表示されていたのに、本番ではうまく表示されないのはなぜでしょうか?
これは、開発中はアクセス毎にアセットファイル(画像・CSS・JSファイルの総称)を自動的にコンパイル(圧縮)する仕組みが備わっていますが、本番モードのときにはパフォーマンスのためアクセス毎には実行されないようになっているためです。
[ec2-user@ip-172-31-23-189 <アプリ名>]$ rails assets:precompile RAILS_ENV=production
Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install
I, [2020-01-18T12:51:01.4345644 #1265] INFO -- : Writing /var/app/web-share/public/assets/member_photo_noimage_thumb-224a733c50d48aba6d9fdaded809788bbeb5ea5f6d6b8368adaebb95e58bcf53.png
I, [2020-01-18T12:51:02.2615123#1265] INFO -- : Writing /var/app/appname/public/assets/application-bc071e28a78e2b63c9313afed5ad3476e00e3f0e5b12445c37214d1f1317be48.js
I, [2020-01-18T12:51:02.2626434 #1265] INFO -- : Writing /var/app/appname/public/assets/application-bc071e28a78e2b63c9313afed5ad3476e00e3f0e5b12445c37214d1f1317be48.js.gz
I, [2020-01-18T12:51:08.484546 #1265] INFO -- : Writing /var/app/appname/public/assets/application-8549fb9a804686e593d5c0f90a2412a39de85908e5fb58fdf6681d4b0073d891.css
I, [2020-01-18T12:51:08.485454 #1265] INFO -- : Writing /var/app/appname/public/assets/application-8549fb9a804686e593d5c0f90a2412a39de85908e5fb58fdf6681d4b0073d891.css.gz
エラーが出る場合
ActiveRecord::AdapterNotSpecified: 'production' database is not configured. Available: ["default", "development", "test", "database", "username", "password", "socket"]
下記を修正してください
production:
<<: *default # ここが抜けているはず
database: <%= Rails.application.credentials.db[:database] %>
username: <%= Rails.application.credentials.db[:username] %>
password: <%= Rails.application.credentials.db[:password] %>
socket: <%= Rails.application.credentials.db[:socket] %>
追記したら
[ec2-user@ip-172-31-23-189 <アプリ名>] git pull origin master
再度
[ec2-user@ip-172-31-23-189 <アプリ名>]$ rails assets:precompile RAILS_ENV=production
今度は成功するはずです
Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/install
I, [2020-01-18T12:51:01.4345644 #1265] INFO -- : Writing /var/app/web-share/public/assets/member_photo_noimage_thumb-224a733c50d48aba6d9fdaded809788bbeb5ea5f6d6b8368adaebb95e58bcf53.png
I, [2020-01-18T12:51:02.2615123#1265] INFO -- : Writing /var/app/appname/public/assets/application-bc071e28a78e2b63c9313afed5ad3476e00e3f0e5b12445c37214d1f1317be48.js
I, [2020-01-18T12:51:02.2626434 #1265] INFO -- : Writing /var/app/appname/public/assets/application-bc071e28a78e2b63c9313afed5ad3476e00e3f0e5b12445c37214d1f1317be48.js.gz
I, [2020-01-18T12:51:08.484546 #1265] INFO -- : Writing /var/app/appname/public/assets/application-8549fb9a804686e593d5c0f90a2412a39de85908e5fb58fdf6681d4b0073d891.css
I, [2020-01-18T12:51:08.485454 #1265] INFO -- : Writing /var/app/appname/public/assets/application-8549fb9a804686e593d5c0f90a2412a39de85908e5fb58fdf6681d4b0073d891.css.gz
Railsの再起動
コンパイルが成功したら反映を確認するため、Railsを再起動します。しかし、まずは今動いているUnicornをストップします。
EC2のターミナルから以下のように入力します。「aux」と打っているのは、psコマンドのオプションです。表示結果を見やすくしてくれます。また、| grep unicornとしているのはpsコマンドの結果からunicorn関連のプロセスのみを抽出するためです。
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ps aux | grep unicorn
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となっています。
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill <確認したunicorn rails masterのPID>
killコマンド:現在動いているプロセスを停止させるためのコマンドです
再度、プロセスを表示させ終了できていることを確認しましょう。
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ps aux | grep unicorn
...
ec2-user 17911 0.0 0.2 110532 2180 pts/0 S+ 02:05 0:00 grep --color=auto unicorn
3つあった項目が一つになっています
では、Railsを起動させましょう!
[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/ にアクセスしてみましょう。今度はレイアウト崩れも無くサイトが正常に表示されていることでしょう。
参考
【Rails5.2】credentials.yml.encとmaster.keyでのデプロイによる今までとの変更点
【備忘録】credentials.yml.encにdatabase設定を保存する
#Nginxのインストールと設定
Nginx
Webサーバの一種であるNginxの導入と設定を行います。
nginxは静的コンテンツ(つまりサーバ上のファイル)を高速に配信するように設計されている。
ユーザーのリクエストに対して静的コンテンツの取り出し処理を行い、そして動的コンテンツの生成をアプリケーションサーバに依頼することが可能
Nginxをインストール
下記のコマンドでインストール
[ec2-user@ip-172-31-25-189 ~]$ sudo yum -y install nginx
Nginxの設定ファイルを編集
Nginxにアクセスされたときの動作を記載する設定ファイルを作成する。
設定ファイルは、/etc/nginx/conf.dフォルダ配下に作成する。拡張子が.confのものがすべて読み込まれる設定になっている。
https://koooza.net/post-382
[ec2-user@ip-172-31-25-189 ~]$ sudo vim /etc/nginx/conf.d/rails.conf
下記を貼り付ける
(ディレクトリの場所などは、自分にあった場所を指定してください)
upstream app_server {
# Unicornと連携させるための設定。
# アプリケーション名を自身のアプリ名に書き換えることに注意。今回であればおそらく
server unix:/var/〇〇〇(アプリをまとめているディレクトリ)/〇〇〇〇〇〇<アプリケーション名>/tmp/sockets/unicorn.sock;
}
# {}で囲った部分をブロックと呼ぶ。サーバの設定ができる
server {
# このプログラムが接続を受け付けるポート番号
listen 80;
# 接続を受け付けるリクエストURL ここに書いていないURLではアクセスできない
server_name 18.〇〇〇.〇〇〇.〇〇(Elastic IP);
# クライアントからアップロードされてくるファイルの容量の上限を2ギガに設定。デフォルトは1メガなので大きめにしておく
client_max_body_size 2g;
# 接続が来た際のrootディレクトリ
root /var/www/〇〇〇〇〇<アプリケーション名>/public;
# assetsファイル(CSSやJavaScriptのファイルなど)にアクセスが来た際に適用される設定
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri @unicorn;
location @unicorn {
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;
}
error_page 500 502 503 504 /500.html;
}
- 3行目の<アプリケーション名> となっている箇所は、ご自身のものに変更してください。
- 11行目の<Elastic IP>となっている箇所も同様に、ご自身のものに変更してください。
- 14行目の<アプリケーション名> となっている箇所は、ご自身のものに変更してください。
Nginxの権限を変更
POSTメソッドでもエラーが出ないようにするために、下記のコマンドも実行してください。
[ec2-user@ip-172-31-25-189 ~]$ cd /var/lib
[ec2-user@ip-172-31-25-189 lib]$ sudo chmod -R 775 nginx
Nginxを再起動して設定ファイルを再読み込み
[ec2-user@ip-172-31-25-189 lib]$ cd ~
[ec2-user@ip-172-31-25-189 ~]$ sudo service nginx restart
ローカルでunicorn.rb修正
listen 3000
↓以下のように修正
listen "#{app_path}/tmp/sockets/unicorn.sock"
Githubで変更点をpushしたら、本番環境でも反映させます。
[ec2-user@ip-172-31-25-189 ~]$ cd /var/www/アプリ名
[ec2-user@ip-172-31-23-189 <アプリ名>]$ git pull origin master
Unicornを再起動
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ps aux | grep unicorn
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
続いて、unicorn_rails master(一番上)のプロセスをkillします。
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill <確認したunicorn rails masterのPID(上のコードでは17877)>
unicornを起動します
[ec2-user@ip-172-31-23-189 <アプリ名>]$ RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -D
ブラウザからElastic IPでアクセス
https:// (Elastic IP)
これでサイトが表示されず、下記が表示されたら、、、、、、、、、
もう一度、下記をやり直してください。
Nginxの設定ファイルを編集
[ec2-user@ip-172-31-25-189 ~]$ sudo vim /etc/nginx/conf.d/rails.conf
下記を貼り付ける
(ディレクトリの場所などは、自分にあった場所を指定してください)
upstream app_server {
# Unicornと連携させるための設定。
# アプリケーション名を自身のアプリ名に書き換えることに注意。今回であればおそらく
server unix:/var/〇〇〇(アプリをまとめているディレクトリ)/〇〇〇〇〇〇<アプリケーション名>/tmp/sockets/unicorn.sock;
}
# {}で囲った部分をブロックと呼ぶ。サーバの設定ができる
server {
# このプログラムが接続を受け付けるポート番号
listen 80;
# 接続を受け付けるリクエストURL ここに書いていないURLではアクセスできない
server_name 18.〇〇〇.〇〇〇.〇〇(Elastic IP);
# クライアントからアップロードされてくるファイルの容量の上限を2ギガに設定。デフォルトは1メガなので大きめにしておく
client_max_body_size 2g;
# 接続が来た際のrootディレクトリ
root /var/www/〇〇〇〇〇<アプリケーション名>/public;
# assetsファイル(CSSやJavaScriptのファイルなど)にアクセスが来た際に適用される設定
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri @unicorn;
location @unicorn {
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;
}
error_page 500 502 503 504 /500.html;
}
これで無事にサイトが表示されたら、完了です!
#capistranoとは?からインストール、自動デプロイ
自動でデプロイさせて負担を軽減する
デプロイの作業は非常に手間です。
いちいちその作業をすれば、随分な時間が取られてしまいます。
煩わしいので、自動化させましょう
これまでのデプロイまでの流れを振り返る
ここまでデプロイするための作業をしましたが、簡単に流れを振り返りましょう
- git push
- git pull
- SSH接続
- アセットコンパイル
- Unicorn再起動
この一連の流れをすれば、デプロイが完了されます。
なお、この一連の流れをまだしたことがない、自信がないという人は
詳しく解説している下記の記事を閲覧してください。
EC2インスタンスを立ち上げるまでの記事はシリーズ化しているので、こちらをどうぞ
独学ではじめてAWSのEC2にデプロイする方法①~⑩(インスタンスの作成)
capistranoとは
この一連のデプロイ作業を自動化させる、様々のツールの一つにcapistranoがあります。
capistranoを利用することでサーバーにログインしなくても"" コマンド一つで ””デプロイできちゃうのですから、非常に楽です。
一度Capistranoにデプロイが成功すれば、簡略してエラーなしにデプロイができます。
Capistranoの導入
Gemのインストール
ローカルのwebappにCapistranoのgemを追加しましょう
group :development, :test do
gem 'capistrano'
gem 'capistrano-rbenv'
gem 'capistrano-bundler'
gem 'capistrano-rails'
gem 'capistrano3-unicorn'
end
続いて、インストールします
$ bundle install
gemがインストールできたところで、Capistranoの下記のコマンドを実施
$ bundle exec cap install
するとファイルが作成されます。
railsルート
├─ Capfile
├─ config
│ ├─ deploy
│ │ ├─production.rb
│ │ └─staging.rb
│ └─deploy.rb
└─ lib
└─capistrano
└─tasks
これらのファイル説明は作業しながら学びましょう
Capfileを編集
一度ファイルの中身を全部消して、下記のように編集しましょう
require "capistrano/setup"
require "capistrano/deploy"
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano3/unicorn'
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
production.rbを編集
production.rbですが2つファイルがあります
❌ config/environment/production.rb
⭕️ config/deploy/production.rb
今回作業はするのはconfig/deploy/production.rbです
実際に開くと下記の画面が出ます。
このファイルを下記を追記しましょう!(元が全部コメントアウトなので、どこでも可能)
server '18.○○○.○○.○○○(Elastic IP)', user: 'ec2-user', roles: %w{app db web}
deploy.rbを編集
下記を追加します
# config valid only for current version of Capistrano
# capistranoのバージョンを記載。固定のバージョンを利用し続け、バージョン変更によるトラブルを防止する
lock '○.○○.○(Capistranoのバージョン)'
# Capistranoのログの表示に利用する
set :application, '○○○(自身のアプリケーション名)'
set :deploy_to, '/var/○○○(アプリを入れているディレクトリ)/○○○(アプリ名)'
# どのリポジトリからアプリをpullするかを指定する
set :repo_url, 'git@github.com:○○○(Githubのユーザー名)/○○○(レポジトリ名.git'
# バージョンが変わっても共通で参照するディレクトリを指定
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads')
set :rbenv_type, :user
set :rbenv_ruby, '○.○.○(rubyのバージョン)' #カリキュラム通りに進めた場合、2.5.1か2.3.1です
# どの公開鍵を利用してデプロイするか
set :ssh_options, auth_methods: ['publickey'],
keys: ['~/.ssh/○○○○○.pem(ローカルPCのEC2インスタンスのSSH鍵(pem)へのパス 例:~/.ssh/key_pem.pem))']
# プロセス番号を記載したファイルの場所
set :unicorn_pid, -> { "#{shared_path}/tmp/pids/unicorn.pid" }
# Unicornの設定ファイルの場所
set :unicorn_config_path, -> { "#{current_path}/config/unicorn.rb" }
set :keep_releases, 5
# デプロイ処理が終わった後、Unicornを再起動するための記述
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
task :restart do
invoke 'unicorn:restart'
end
end
貼り付けたテンプレートの一部を修正しましょう
lock '<Capistranoのバージョン>'
Capistranoのバージョンを確認するために、Gemfile.lockを開きましょう
capistrano (3.11.1)
airbrussh (>= 1.0.0)
i18n
rake (>= 10.0.0)
sshkit (>= 1.9.0)
これでCapistranoのバージョンが(3.11.1)とわかりました。
ではdeploy.rbを修正しましょう
lock '3.11.1'
rubyのバージョン確認
set :rbenv_ruby, '○.○.○(rubyのバージョン)'
ターミナルで下記を実行しましょう
$ ruby -v
> ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin18]
○○○のところは、アプリ名などを入れる必要があるので、穴埋めしてください
set :application, '○○○(自身のアプリケーション名)'
set :repo_url, 'git@github.com:○○○(Githubのユーザー名)/○○○(レポジトリ名.git'
keys: ['~/.ssh/○○○○○.pem(ローカルPCのEC2インスタンスのSSH鍵(pem)へのパス 例:~/.ssh/key_pem.pem))']
unicorn.rbを編集
app_path = File.expand_path('../../', __FILE__)
worker_processes 1
working_directory app_path
pid "#{app_path}/tmp/pids/unicorn.pid"
listen "#{app_path}/tmp/sockets/unicorn.sock"
stderr_path "#{app_path}/log/unicorn.stderr.log"
stdout_path "#{app_path}/log/unicorn.stdout.log"
上記のunicorn.rbの記述を下記に変更
# ../が一つ増えている
app_path = File.expand_path('../../../', __FILE__)
worker_processes 1
# currentを指定
working_directory "#{app_path}/current"
# それぞれ、sharedの中を参照するよう変更
listen "#{app_path}/shared/tmp/sockets/unicorn.sock"
pid "#{app_path}/shared/tmp/pids/unicorn.pid"
stderr_path "#{app_path}/shared/log/unicorn.stderr.log"
stdout_path "#{app_path}/shared/log/unicorn.stdout.log"
Nginxの設定ファイルを編集
ec2-user@ip-17-242-2-2 アプリ名$ sudo vim /etc/nginx/conf.d/rails.conf
そして、capistranoに合わせた参照先に変更します。(詳細はコメントアウトで解説しています。)
upstream app_server {
# sharedの中を参照するよう変更(/shared/tmp/sockets/unicorn.sock;)
server unix:/var/○○○(アプリをまとめているディレクトリ)/○○○○○(アプリケーション名)/shared/tmp/sockets/unicorn.sock;
}
server {
listen 80;
server_name 18.○○○.○○(Elastic IP);
# currentの中を参照するよう変更(/current/public;)
root /var/○○○(アプリをまとめているディレクトリ)/○○○○○(アプリケーション名)/current/public;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
# currentの中を参照するよう変更(/current/public;)
root /var/○○○/○○○○○○(アプリケーション名)/current/public;
}
try_files $uri/index.html $uri @unicorn;
location @unicorn {
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;
}
error_page 500 502 503 504 /500.html;
}
Nginxの設定を変更したら、忘れずに再読込・再起動
[ec2-user@ip-172-31-25-189 ~]$ sudo service nginx reload
[ec2-user@ip-172-31-25-189 ~]$ sudo service nginx restart
MySQLの起動を確認
[ec2-user@ip-172-31-25-189 ~]$ sudo service mysqld restart
unicornのプロセスをkillしよう
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ps aux | grep unicorn
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
一番上のunicorn_rails masterをkillしたいので、下記を実施
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill 17877
ローカルでの修正を全てmasterにpushしてください
自動デプロイの実施
# アプリケーションのディレクトリで実行する
$ bundle exec cap production deploy
エラーが発生する場合
ディレクトリ `/var/www' を作成できません: 許可がありません
mkdir stdout: Nothing written
mkdir stderr: mkdir: ディレクトリ `/var/www' を作成できません: 許可がありません
mkdir: ディレクトリ `/var/www' を作成できません: 許可がありません
ヒヤリング:手動デプロイはできていたか?
・YES:Capistranoの設定の問題(ここまで進めている以上、できているはず)
・NO:もう一度手動デプロイを確認する必要があるかもしれません。
設定の見直し
rails.confとdeploy.rbのパスの確認をしてください。
var/www/アプリ名で設定しているか?
・ディレクトリはwwwの場合、入力間違いがないか???
・ディレクトリは"wwwでない"場合、capistranoのデフォルト設定を変更する必要がある。
EC2でのアプリの保存場所が『 var/www/アプリ名 』でない場合、、
[参考](https://capistranorb.com/documentation/getting-started/configuration/)
deplory.rbに下記を追加してください。
set :deploy_to, '/var/○○○/アプリ名'
capistranoのデフォルト設定では、/var/www/アプリ名が設定されているため、これを変更する必要がある。
そのオプション設定がset :deploy_to, '/var/○○○/アプリ名'である。
Master.keyがないエラー( Missing encryption key to decrypt file with. Ask your team for your master key and write it to )
このエラーが表示されたということは、『 本番環境にあるmaster.keyをうまく読み込めていない 』ことを意味します。
rake stdout: Nothing written
rake stderr: Missing encryption key to decrypt file with. Ask your team for your master key and write it to /var/○○○(アプリを格納しているディレクトリ名)/○○○(アプリ名)/releases/20200121124714/config/master.key or put it in the ENV['RAILS_MASTER_KEY'].
なので現状として可能性は二つです。
- master.keyを作成していない。
- master.keyを作成する場所が間違っている。
ここまで作業を進めている人は,master.keyを作成しているはずです。
>つまり、master.keyの作成場所をまちがている可能性が高いです。
# 誤解が生まれやすいmaster.keyの作成場所
✖︎ アプリ名>config>master.key
○ アプリ名>shared>config>master.key
おそらく、上記のようにmaster.keyの作成場所に誤りがある可能性が高いです。
ですから、
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ cd shared
[ec2-user@ip-172-31-23-189 shared ]$ cd config
[ec2-user@ip-172-31-23-189 config ]$ ls
>ここでmaster.keyがない場合、 master.keyを作成してください。
master.keyを作成する場合、、、
アプリ名 $ vi config/master.key
>master.keyを中身がわかります。
>間違っても編集しないようにしましょう
ローカル環境のmaster.keyをコピーしたら、EC2にmaster.keyを作成しましょう
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ cd shared/config
[ec2-user@ip-172-31-23-189 config ]$ vi master.key
>編集画面が出るので
>ローカルのmaster.keyをコピペします。
>:wpで保存しましょう
master.keyを読み込ませるために、deploy.rbに
下記を追加してください
set :linked_files, fetch(:linked_files, []).push("config/master.key")
再度自動デプロイしましょう
# アプリケーションのディレクトリで実行する
$ bundle exec cap production deploy
今度はうまくいくはずです。
参考:Rails5.2から追加された credentials.yml.enc のキホン
最後に
転職活動にお悩みの方のために、最高の教材を作成しました。
この方法で知り合いはほぼ全員内定を獲得して、エンジニアとして現在活躍しています。
ぜひチェックしてみください
https://note.com/gyu_outputs/n/nfd80b9dab981