Rails アプリを EC2 にデプロイしよう！（環境構築編）

Rails アプリを Amazon Web Service を使ってデプロイするまでの手順をまとめました。
次の順番でデプロイまで持っていきます。

1, 準備編
2, サーバー構築編
3, 環境構築編
4, デプロイ編

今回は「環境構築編」です。
「[準備編](https://qiita.com/tao066/items/9eb25b840694f8805221)」と「[サーバー構築編](https://qiita.com/tao066/items/11575932e6aa05c3afdd)」を読んでない方は先に読んでください。

# EC2 にログインする
まずは、作成したインスタンスが起動しているのを確認してください。
下記画像の欄が緑文字で「running」となっていればOKです。
<img width="800" alt="EC2 ログイン" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530541/23d6ba83-85d1-e57e-2595-bcf24d831cb6.png">
このインスタンスにアクセスしましょう。
アクセスするにはパブリックDNSを使用します。

パブリックDNSとは、インターネットを通じてアクセスするための住所といったイメージです。
例えば http://yahoo.co.jp と打ち込むと「Yahoo Japan!」のページに飛ぶことができますが、
http://118.151.235.191/ と打ち込んでも、同様のページにアクセスすることができます。

これは何故かというと、DNS(Domain Name System)というものが
`118.151.~~~.~~~`というIPアドレスと`yahoo.co.jp`というドメインを紐付けているからです。つまり、一旦ドメインでのアクセスをDNSが受け付けて、受け付けたドメインと対応するIPアドレスを探して表示させているという流れになります。

このDNSの場所が上記に記載されているといった形です。

---
**パブリック DNS が表示されていない場合**
パブリックDNSが割り当てられていないとインスタンスにアクセスできないので、
次の手順で解決を行ってください。
1. コンソール画面から検索するなりして「VPC」をクリックしてください。
2. 左のメニューバーから「VPC」をクリックしてください。
3. 左上辺りにある「アクション」から「DNS ホスト名の編集」を選択してください。
4. 「DNS ホスト名」にチェックを入れて「有効化」してください。

参考元：[AWSでPublic DNS(パブリックDNS)が割り当てられない時の解決法](https://qiita.com/sunadoridotnet/items/4ea689ce9f206e78a523)

---
ここでやっと、ターミナル画面を使っていきます（長かった）...
今回は Mac を想定して記述していきます。

## 下準備
今回は`openssh`を使用するので、インストールしていない方はインストールしましょう。

```terminal:~
$ brew install openssh
```

SSH? という方は次の記事を一読ください。
[初心者がSSHについて学ぶ(´･ω･`)](https://qiita.com/Pana/items/70cc74cd20c8b5b4fe15)

今回はSSHを簡素に使用するので、よりセキュアに設定したい（しなければならない）方は
こちらの記事を一読するなどして、勉強しましょう。
[インフラエンジニアじゃなくても押さえておきたいSSHの基礎知識](https://qiita.com/tag1216/items/5d06bad7468f731f590e)

## インスタンスへのログイン設定
先ほど作成したインスタンスにログインをしていきます。

EC2インスタンスにログインできるユーザーとして、
AWSでは、デフォルトでec2-userという名のユーザーが用意されています。

次の流れで進めていきたいと思います。
1. ec2-userでログイン
2. 新たなユーザーの作成
3. 作成したユーザーにec2-userと同様の権限を付与
4. 新たなユーザーで再度ログイン

打ち込むコマンドは次の通りです。

```terminal:~
# 前回作成した公開鍵を .ssh ディレクトリに移動する
$ mv Downloads/SampleApp_ConsoleKeyRsa.pem ~/.ssh

# .ssh ディレクトリに移動
$ cd ~/.ssh
```
```terminal:~/.ssh
# 公開鍵に600番で定義されたアクセス権を付与する
$ chmod 600 SampleApp_ConsoleKeyRsa.pem

# 公開鍵を利用してec2-userとしてログイン
$ ssh -i SampleApp_ConsoleKeyRsa.pem ec2-user@52.198.194.39

# 信頼性について警告を受けますが「yes」と入力しましょう。
The authenticity of host '52.198.194.39 (52.198.194.39)' can't be established.
ECDSA key fingerprint is SHA256:**************************************************.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
```
※ アクセス権について知っておきたい方は、次の URL を参考にするなどして予習しましょう
[chmod? chown? よくわからんって人のための、ファイル権限系まとめ](https://qiita.com/t-a-run/items/239ed690ece7a011804a)

これでEC2にアクセスすることができました。

```terminal:~/.ssh
Warning: Permanently added '52.198.194.39' (ECDSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
7 package(s) needed for security, out of 11 available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-192-168-10-49 ~]$ 
```

## 新たなユーザーの作成
続いて、新たなユーザーを作成し、作成したユーザーにマスター権限を与えていきます。

```
# 新規ユーザー名の登録
[ec2-user@ip-192-168-10-49 ~]$ sudo adduser minato

# 新規ユーザー名のパスワードを登録
[ec2-user@ip-192-168-10-49 ~]$ sudo passwd minato
Changing password for user minato.
New password: 
Retype new password: 
passwd: all authentication tokens updated successfully.

# 作成したユーザーに root 権限を追加する
# 1. rootに関する権限の記述箇所
#       root    ALL=(ALL)       ALL
#    を探す。
# 2. 「i」を入力することで「-- INSERT --」（入力）モードに移行する
# 3. その下に「作成したユーザーに権限を追加する」記述
#       minato  ALL=(ALL)       ALL
#    を追加する
# 4. esc を押して Input モードを終了
# 5. 「:wq」で保存&編集完了
[ec2-user@ip-192-168-10-49 ~]$ sudo visudo
```
`$ sudo visudo` では Vim というものを使用しています。
Vim とは主にコンソールから文字列を扱う`vi`というテキストエディタを拡張したものです。
Amazon Linux においては`vi`コマンドを使用すると`vim`を使用するようにエイリアス設定がされています。

```
[ec2-user@ip-192-168-10-49 ~]$ which vi
alias vi='vim'
	/usr/bin/vim
```

vim の使い方については次の記事が非常に参考になります。
[Vim初心者に捧ぐ実践的入門](https://qiita.com/okamos/items/c97970ab34ff55ff3167)

編集が完了したら、次のコマンドでユーザーの切り替えを行ってください。

```
[ec2-user@ip-192-168-10-49 ~]$ sudo su - minato
[minato@ip-192-168-10-49 ~]$ 
```

無事に`ec2-user`が`minato`（作成したユーザー名）と切り替わればOKです。

## SSH通信によるインスタンスへのログイン
続いては、先ほど作成したユーザーを使用してインスタンスにログインしていきます。

次の流れで進めていきたいと思います。
1. ローカルで鍵の生成
2. その鍵をどの通信の認証時に使用するか設定
3. サーバーとの認証処理を行う。
4. 実際に新ユーザーでログイン

では早速作業していきますが、
ここからしばらくは、ローカル（あなたが使っているパソコン）での作業になるので、
次のコマンドでローカル環境に戻りましょう。
（別のターミナルを立ち上げて作業を行ってもOKです）

```
[minato@ip-192-168-10-49 ~]$ exit
logout
[ec2-user@ip-192-168-10-49 ~]$ exit
logout
Connection to 52.198.194.39 closed.
```

次のコマンドで、ローカルで鍵の生成を行います。
`~/.ssh` 配下などで作業を行ってください。

```terminal:~/.ssh
# 秘密鍵と公開鍵を作成
# 「Enter file in which to save the key」
# で、秘密鍵ファイルと公開鍵ファイルの名前を記述する
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/minato/.ssh/id_rsa): SampleApp_MinatoKeyRsa
Enter passphrase (empty for no passphrase): # そのままエンター
Enter same passphrase again: # そのままエンター
Your identification has been saved in SampleApp_MinatoKeyRsa.
Your public key has been saved in SampleApp_MinatoKeyRsa.pub.
The key fingerprint is:
SHA256:**************************************************
The key's randomart image is:
**********
**********
**********
**********
**********

# 秘密鍵と公開鍵が生成されたことを確認
$ ls
SampleApp_MinatoKeyRsa
SampleApp_MinatoKeyRsa.pem

# Vim を起動して設定ファイルを編集する
# 以下を追記します。
# ########################################
# Host SampleApp_MinatoKeyRsa
#     Hostname 52.198.194.39 # Elastic IP
#     Port 22     # ポート番号
#     User minato # サーバーで作成したユーザー名
#     IdentityFile ~/.ssh/SampleApp_MinatoKeyRsa # 秘密鍵の場所
# ########################################
$ vim config

# 公開鍵の中身をターミナル上に出力して、出力されたもの全てコピーしておく
$ cat SampleApp_MinatoKeyRsa.pub
ssh-rsa **************************************************
```

上記により、
1. ローカルで鍵の生成
2. その鍵をどの通信の認証時に使用するか設定
ここまでが完了しました。

次はサーバー側で作業を進めます。

```terminal:~/.ssh
$ ssh -i SampleApp_ConsoleKeyRsa.pem ec2-user@52.198.194.39
[ec2-user@ip-192-168-10-49 ~]$ sudo su - minato
```
サーバーに公開鍵を登録します。

```
# 鍵を入れるためのディレクトリを作成、権限の付与を行い、
# そのディレクトリに移動する
[minato@ip-192-168-10-49 ~]$ mkdir .ssh
[minato@ip-192-168-10-49 ~]$ chmod 700 .ssh
[minato@ip-192-168-10-49 ~]$ cd .ssh

# 公開鍵ファイルを作成する
# 公開鍵の中身をコピペしましょう
[minato@ip-192-168-10-49 .ssh]$ vim authorized_keys

# 権限を設定する
[minato@ip-192-168-10-49 .ssh]$ chmod 600 authorized_keys

# ログアウトする
[minato@ip-192-168-10-49 .ssh]$ exit
[ec2-user@ip-192-168-10-49 ~]$ exit
```

これで新ユーザーでログインできるようになりました。
ローカルで下記コマンドを入力して、実際にログインできるか試してみましょう。

```terminal:~
$ ssh SampleApp_MinatoKeyRsa

Last login: Sat Mar 21 16:54:32 2020

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
7 package(s) needed for security, out of 11 available
Run "sudo yum update" to apply all updates.
[minato@ip-192-168-10-49 ~]$ 
```

ログインできれば、無事ユーザー設定は終了です。

# EC2インスタンスの環境構築

次は、作成したEC2インスタンス内で`Ruby`やその他の環境が動くよう設定していきます。
「自身のPCで開発を始めるときに環境構築を行う」要領で、AWS内に新しく作成したパソコン（＝EC2インスタンス）でも同様に環境構築を行なっていく感じです。

## yum を使って環境を構築
まずは `yum` を使って幾つかの実行環境を構築していきます。

`yum` は「Yellowdog Updater Modified」の略で、環境を構築するときに使用する「パッケージ」を管理・運用することができるものです。
これを使って環境構築していきます。

EC2 には既に `yum` が入っているので、
まずは `yum` でインストールされているパッケージを最新の状態に更新しましょう。

```terminal
# yum 内のパッケージを更新する
# パスワードが要求された際は入力する
# 「これだけインストールしますけど大丈夫ですか？」というような警告が出てきますが、
# 「y」を入力して承認してください。
[minato@ip-192-168-10-49 ~]$ sudo yum update
```

次に、今回使用するパッケージを一気にインストールしていきます。

```terminal
# 今回使用するパッケージを一気にインストール。
# 各パッケージの説明は割愛しますが、
# C++、openssl、mysql、ImageMagick などをインストールしています。
[minato@ip-192-168-10-49 ~]$ sudo yum install \
git make gcc-c++ patch \
openssl-devel \
libyaml-devel libffi-devel libicu-devel \
libxml2 libxslt libxml2-devel libxslt-devel \
zlib-devel readline-devel \
mysql mysql-server mysql-devel \
ImageMagick ImageMagick-devel \
epel-release
```
`Complete!` が最後に表示されればOKです。

## Ruby の実行環境
次に、EC2インスタンスに `Ruby` の実行環境を作成していきます。

`Ruby` をインストールするのに `rbenv` を使用します。
`rbenv` とは、簡単に `Ruby` のバージョンの切り替えを行うためのツールです。

次の手順で `rbenv` をインストールしていきます。

```terminal
# rbenv をインストール
[minato@ip-192-168-10-49 ~]$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv

# ~/.bash_profile に bin の位置を登録する
[minato@ip-192-168-10-49 ~]$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile

# ~/.bash_profile に rbenv コマンドが使えるように登録する
[minato@ip-192-168-10-49 ~]$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

# 先ほど設定したものを再読み込みする
[minato@ip-192-168-10-49 ~]$ exec $SHELL -l

# rbenv のバージョンを確認する
[minato@ip-192-168-10-49 ~]$ rbenv --version
rbenv 1.1.2-28-gc2cfbd1

# ruby-build をインストール
[minato@ip-192-168-10-49 ~]$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

# rehash を行う
[minato@ip-192-168-10-49 ~]$ rbenv rehash
```

そしていよいよ、`Ruby` のインストールです。

```terminal
# rbenv のバージョンのリストを確認する
[minato@ip-192-168-10-49 ~]$ rbenv install --list
1.8.5-p52
1.8.5-p113
1.8.5-p114
...

# 2.6.5 をインストールする（バージョンは適宜変更してください）
[minato@ip-192-168-10-49 ~]$ rbenv install -v 2.6.5

# 2.6.5 を使用するように設定する
[minato@ip-192-168-10-49 ~]$ rbenv global 2.6.5

# rehash を行う
[minato@ip-192-168-10-49 ~]$ rbenv rehash

# ruby のバージョンを確認する
[minato@ip-192-168-10-49 ~]$ ruby -v
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]
```

しっかりと `Ruby` のバージョンが表示されれば成功です。

## Node.js の実行環境
次に、EC2インスタンスに `Node.js` の実行環境を作成していきます。

`Node.js` をインストールするのに `nvm` を使用します。
`nvm` は、簡単に `Node.js` のバージョンの切り替えを行うためのツールです。
`rbenv` と同じ立ち位置ですが、

次の手順で `nvm` をインストールしていきます。

```terminal
# nvm をインストール
[minato@ip-192-168-10-49 ~]$ git clone https://github.com/creationix/nvm.git ~/.nvm

# ~/.bash_profile に nvm.sh を読み込むように設定する
[minato@ip-192-168-10-49 ~]$ echo -e "if [[ -s ~/.nvm/nvm.sh ]]; then \nsource ~/.nvm/nvm.sh\nfi" >> ~/.bash_profile

# インストール可能な　Node.js　バージョンの確認
[minato@ip-192-168-10-49 ~]$ nvm --version
```
そしていよいよ、`Node.js` のインストールです。

```terminal
# インストール可能な Node.js バージョンの確認
[minato@ip-192-168-10-49 ~]$ nvm ls-remote

# v12.16.1 をインストールする（バージョンは適宜変更してください）
[minato@ip-192-168-10-49 ~]$ nvm install v12.16.1

# Node.js のバージョンを確認する
[minato@ip-192-168-10-49 ~]$ node -v
```

しっかりと `Node.js` のバージョンが表示されれば成功です。

別のバージョンをデフォルトで使用するよう設定する場合は次のコマンドを使用してください。
`$ nvm alias default v12.16.1`

# Rails アプリのクローン
今回の最後に、作成したアプリを git からクローンしてEC2インスタンス内に配置していきます。

## git の設定ファイルを作成
まずは `vim` コマンドで `.gitconfig` という git に関する設定ファイルを生成します。

```terminal
[minato@ip-192-168-10-49 ~]$ vim .gitconfig
```

次のように設定しましょう。

```vim:~/.gitconfig
# git のユーザー情報
[user]
    name  = minato         # git に登録した自分の名前
    email = hoge@hoge.com  # git に登録した自分のメールアドレス

# 色付け
[color]
    ui = true

# githubの場合
# pull と push のための設定
[url "github:"]
    InsteadOf = https://github.com/
    InsteadOf = git@github.com:

# bitbucketの場合
[url "bitbucket:"]
    InsteadOf = https://minato@bitbucket.org/ # minato はあなたのユーザー名に置き換えてください
    InsteadOf = git@bitbucket.org:
```

完了したらファイルを保存しましょう

## アプリを配置するディレクトリの作成

次は、アプリを配置するディレクトリを作成していきます。

```
# / に移動
[minato@ip-192-168-10-49 ~]$ cd /

# var ディレクトリの所有者を minato にする
[minato@ip-192-168-10-49 /]$ sudo chown minato var
[sudo] password for minato: 

# var 配下に www ディレクトリを作成し、所有者を minato にする
[minato@ip-192-168-10-49 /]$ cd var; sudo mkdir www; sudo chown minato www

# www 配下に rails ディレクトリを作成し、所有者を minato にする
[minato@ip-192-168-10-49 var]$ cd www; sudo mkdir rails; sudo chown minato rails
```

mkdirコマンドでフォルダを作成し、chownコマンドで作成したフォルダの所有者を変更しています。

## git と連携
いよいよ git と連携していきます。

まずは次のコマンドを打ち込んで、
git と連携する用の秘密鍵と公開鍵を作成しましょう。

```terminal
[minato@ip-192-168-10-49 www]$ cd ~
[minato@ip-192-168-10-49 ~]$ chmod 700 .ssh
[minato@ip-192-168-10-49 ~]$ cd .ssh
[minato@ip-192-168-10-49 .ssh]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/minato/.ssh/id_rsa): SampleApp_GitKeyRsa
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in SampleApp_GitKeyRsa.
Your public key has been saved in SampleApp_GitKeyRsa.pub.
The key fingerprint is:
SHA256:**************************************************
The key's randomart image is:
**********
**********
**********
**********
**********

[minato@ip-192-168-10-49 .ssh]$ ls
authorized_keys  SampleApp_GitKeyRsa  SampleApp_GitKeyRsa.pub
```

秘密鍵と公開鍵が作成されているか確認できればOKです。

次は `vim` を起動して設定ファイルを編集しましょう。

```terminal
[minato@ip-192-168-10-49 .ssh]$ vim config
```

次のように設定してください。

```vim:~/.ssh/config
# github の場合
Host github
    Hostname github.com
    User git
    IdentityFile ~/.ssh/SampleApp_GitKeyRsa 

# bitbucket の場合
Host bitbucket
    Hostname bitbucket.org
    User git
    IdentityFIle ~/.ssh/SampleApp_GitKeyRsa
```

保存したら config に権限も設定しましょう。

```terminal
[minato@ip-192-168-10-49 .ssh]$ chmod 600 config
```

次に、公開鍵を出力します。

```terminal
[minato@ip-192-168-10-49 .ssh]$ cat SampleApp_GitKeyRsa.pub
ssh-rsa **************************************************
```

一度インスタンスとの接続で行った鍵の作成の流れなので、大丈夫だと思います。
そして cat で表示させた公開鍵を github または bitbucket に登録します。

**GitHub の場合**
1. GitHubにログインして、右上のメニューから Settings を選択
2. SSH and GPG keys を選択
3. New SSH Key を押す
4. Title（自由）、Key（コピーした内容をペースト）を入力して Add SSH key を押す

**Bitbucket の場合**
1. Bitbucket にログインして、左下の自身のアイコンから View Profile を選択
2. メニューから「設定」を選択
3. メニューから「SSH 鍵」を選択
4. 「鍵を追加」を押す
5. Label（自由）、Key（コピーした内容をペースト）を入力して「鍵を追加」を押す

登録が完了したら接続を試してみましょう

```terminal
# github の場合
[minato@ip-192-168-10-49 .ssh]$ ssh -T github
Hi MinatoTachibana! You've succwwwessfully authenticated, but GitHub does not provide shell access.

# bitbucket の場合
[minato@ip-192-168-10-49 .ssh]$ ssh -T bitbucket
The authenticity of host 'bitbucket.org (18.205.93.2)' can't be established.
RSA key fingerprint is ******************************.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'bitbucket.org,18.205.93.2' (RSA) to the list of known hosts.
logged in as minato

You can use git or hg to connect to Bitbucket. Shell access is disabled
```

このように表示されれば接続成功です。
登録が済んだら、いよいよクローンです。

```terminal
[minato@ip-192-168-10-49 .ssh]$ cd /var/www/rails
[minato@ip-192-168-10-49 rails]$ git clone git@bitbucket.org:minato/sample_app.git
[minato@ip-192-168-10-49 rails]$ ls
sample_app
```

自身で作成した Rails アプリが表示されていれば OK です。

# 最後に
今回は「環境構築編」でした。
次回が最終回になります（長い...）

それでは最終回「[デプロイ編](https://qiita.com/tao066/items/d37ad77e11367d4e753a)」お楽しみに。