zatsu na benkyou matome saito

勉強したことをまとめるだけのサイト、数学、プログラミング、機械学習とか

Railsを本番環境にデプロイ(with Unicorn, Nginx, EC2, MySQL, Capistrano, Elastic IP)

qiita.com

こちらの記事をほぼまるまんまなのですが、少しMySQLの箇所が違ったので自分用にです。
@gyu_outputsさんの記事を参考にやるだけで十分環境構築できるので、そちらを参照されると良いと。
というか本家の方が圧倒的にまとめられているので...

AWS EC2 Linux2 Rails 本番環境構築

参考: 独学向けRailsアプリをAWSにデプロイする方法まとめ【入門】 - Qiita 消されたとき用のファイル https://drive.google.com/drive/folders/1jI_nABae3a2nghEJ-hl7wavbfHuWbr1J?usp=sharing

$ sudo yum remove mariadb-libs

# Node.jsをインストール
$ [ec2-user@ip-172-31-25-189 ~]$ sudo yum -y install nodejs

rbenvとruby-buildをインストール

$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

$ source .bash_profile
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ rbenv rehash

Rubyをインストール

$ rbenv install --list
# でインストールできるものを確認
$ rbenv install 2.7.0

$ rbenv global 2.5.1
$ rbenv rehash
$ ruby -v

MySQLをインストール

MySQLのインストール 独学向けRailsアプリをAWSにデプロイする方法まとめ【入門】 - Qiitaじゃうまくいかなかった ので、こっちで(AWS EC2 AmazonLinux2 MySQLをインストールする - Qiita

手順はこうらしい。

概要

  1. MySQL必要パッケージのインストールと設定
  2. mysqldのステータス確認
  3. rootアカウントにてMySQLにログイン

1. MySQL必要パッケージのインストールと設定

# 1.    sshを使用してインスタンスにログインする。

# 2. yum update
$ sudo yum update

# 3. 下記コマンドを実行してインスタンス作成初期からインストールされているMariaDB用パッケージを削除する。
$ sudo yum remove mariadb-libs

# 4. 下記コマンドを実行してMySQLのリポジトリをyumに追加する。
$ sudo yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm

# 5. 下記コマンドを実行してMySQLに必要なパッケージ(mysql-community-server)を取得する。(yを入力してEnterを押下する際にインストールパッケージとリポジトリが下記の様になっていることを確認する。)

# これでOK↓
================================================================================
 Package                アーキテクチャー
                               バージョン               リポジトリー       容量
================================================================================
インストール中:
 mysql-community-server x86_64 8.0.21-1.el7             mysql80-community 499 M
依存性関連でのインストールをします:
 mysql-community-client x86_64 8.0.21-1.el7             mysql80-community  48 M
 mysql-community-common x86_64 8.0.21-1.el7             mysql80-community 617 k
 mysql-community-libs   x86_64 8.0.21-1.el7             mysql80-community 4.5 M
 ncurses-compat-libs    x86_64 6.0-8.20170212.amzn2.1.3 amzn2-core        308 k

トランザクションの要約
================================================================================
インストール  1 パッケージ (+4 個の依存関係のパッケージ)

$ sudo yum install --enablerepo=mysql80-community mysql-community-server

# 6. 下記コマンドを実行してMySQLに必要なパッケージ(mysql-community-devel)を取得する。(yを入力してEnterを押下する際にインストールパッケージとリポジトリが下記の様になっていることを確認する。)

# こうなった
===============================================================================================================================================
 Package                                  アーキテクチャー          バージョン                      リポジトリー                          容量
===============================================================================================================================================
インストール中:
 mysql-community-devel                    x86_64                    8.0.21-1.el7                    mysql80-community                    8.0 M

トランザクションの要約
===============================================================================================================================================
インストール  1 パッケージ

総ダウンロード容量: 8.0 M
インストール容量: 58 M
Is this ok [y/d/N]: 

$ sudo yum install --enablerepo=mysql80-community mysql-community-devel

# 7. 下記コマンドを実行してインストールされたMySQLに関係のあるパッケージを出力する。
$ yum list installed | grep mysql

# 8. 先のコマンドの結果が下記の様になれば必要パッケージのインストールは完了である。

[ec2-user@ip-172-31-30-254 ~]$ yum list installed | grep mysql
mysql-community-client.x86_64      8.0.21-1.el7                      @mysql80-community
mysql-community-common.x86_64      8.0.21-1.el7                      @mysql80-community
mysql-community-devel.x86_64       8.0.21-1.el7                      @mysql80-community
mysql-community-libs.x86_64        8.0.21-1.el7                      @mysql80-community
mysql-community-server.x86_64      8.0.21-1.el7                      @mysql80-community
mysql80-community-release.noarch   el7-3                             installed  


# 9. 下記コマンドを実行してlogファイルを作成する。
$ sudo touch /var/log/mysqld.log

# 10. 下記コマンドを実行してmysqldを起動する。
$ sudo service mysqld start


  1. パッケージはこうなっていればいいらしい f:id:dorcushopeino1:20200930101631p:plain

  2. (yを入力してEnterを押下する際にインストールパッケージとリポジトリが下記の様になっていることを確認する。) f:id:dorcushopeino1:20200930101642p:plain

2. mysqldのステータス確認

# 1. 下記コマンドを実行してmusqldの状態を確認する。
$ systemctl status mysqld.service

# こうなった
# 下記の様に出力されれば正常にmysqldが起動できている。

[ec2-user@ip-172-31-30-254 ~]$ systemctl status mysqld.service
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: active (running) since 火 2020-09-29 17:04:23 UTC; 1min 16s ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 14678 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 14751 (mysqld)
   Status: "Server is operational"
   CGroup: /system.slice/mysqld.service
           └─14751 /usr/sbin/mysqld

 9月 29 17:04:17 ip-172-31-30-254.ap-northeast-1.compute.internal systemd[1]: Starting MySQL Server...
 9月 29 17:04:23 ip-172-31-30-254.ap-northeast-1.compute.internal systemd[1]: Started MySQL Server.

# 3. 下記コマンドを実行してmysqldがインスタンスの起動と同時に起動するように設定する。
$ sudo chkconfig mysqld on

rootアカウントにてMySQLにログイン

別記事に書いてあるって。AWS EC2 AmazonLinux2 MySQL rootユーザの初期パスワードの確認方法 - Qiita

ログの確認

  1. 下記コマンドを実行してMySQLのlogファイルを開く
$ sudo less /var/log/mysqld.log
  1. 開いたファイル内で下記の様な一行を見つける。
/var/log/mysqld.logYYYY-MM-DDTHH:MM:SS.260490Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: XXXXXXXXXXXX
  1. ファイルに記載された行のXXXXXXXXXXXXの部分がrootユーザの初期パスワードとなる。

MySQLログイン確認

  1. 開いているmysqld.logファイルを閉じる。
  2. 下記コマンドを実行してmysqldを停止する。
$ sudo service mysqld stop
  1. 下記コマンドを実行してmysqldを起動する。
$ sudo service mysqld start
  1. 下記コマンドを実行してmysqlにrootユーザでログインする。
  2. Enter password: には 先ほどログファイルに出力されていたXXXXXXXXXXXXの部分を入力する。
$ mysql -u root -p

# 先ほどのパスワードで
$ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.21

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

※ 初期パスワードをリセットしたい方は下記を参照してパスワードを再設定する。:AWS EC2 AmazonLinux2 MySQLを使えるようにする 参考文献: MySQLの初期パスワードのありか

パスワードの再設定

AWS EC2 AmazonLinux2 MySQLを使えるようにする - Qiita

先の方法でMySQLにrootユーザでログイン後に下記を実行する。(ERROR 1819 (HY000): Your password does not satisfy the current policy requirementsの様なエラーが出た場合、入力されたrootユーザのパスワードが条件を満たしていない。)

パスワードの再設定

  1. 先の方法でMySQLにrootユーザでログイン後に下記を実行する。(ERROR 1819 (HY000): Your password does not satisfy the current policy requirementsの様なエラーが出た場合、入力されたrootユーザのパスワードが条件を満たしていない。)
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '大文字、小文字、特殊文字(アスタリスク等)を含む新しいrootユーザのパスワード’';
Query OK, 0 rows affected (0.00 sec)
# Password1111@とか
  1. 下記を実行して一旦MySQLからログアウトする。
mysql> exit

DBの作成

  1. 下記コマンドを実行してMySQLにrootユーザでログインする。(ログイン時のパスワードが先に設定し直したパスワードを入力する。)
$ mysql -u root -p
  1. MySQLログイン後下記を実行して「test」という名前のDBを作成する。
mysql> create database test;
  1. 下記を実行して「test」データベースが作成されたことを確認する。
mysql> show databases;

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

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
  1. 下記が表示されるので、エンターを押す
Enter file in which to save the key (/home/ec2-user/.ssh/id_rsa):
  1. さらにエンターを押す(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              |
+-----------------+
  1. SSH公開鍵を表示し、値をコピーするため、下記コマンドを実装
[ec2-user@ip-172-31-23-189 ~]$ cat ~/.ssh/id_rsa.pub
  1. catで表示させた公開鍵(長いテキスト)をコピー
[ec2-user@ip-172-31-30-254 tokyo_ecole]$ cat ~/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDK9o1p6yQ9U95dIfN4Mmhs9V6fPNZfJYStdm6/
(中略・・・)
NRJICEDar5OSjyTHyWF8x8e7CHE5E8bWX8A159rbSyv1Aqy7W4gcUSXcRNdeYSGwnyFNYMGXYJ6QPcGl3c5/JubFuK6VPsB8sZUt3joS1y96/unSYjdQ== ec2-user@ip-172-31-30-254.ap-northeast-1.compute.internal

コピーした公開鍵をGithubにアクセスして登録する https://github.com/settings/keysにアクセス

  1. 画面右上の緑色の『 NEW SSH KEY 』をクリック

  2. タイトルを記入する(なんでも可能)

  3. 公開鍵(ssh-rsaから)を貼り付け

エラー「Key is invalid. You must supply a key in OpenSSH public key format」が表示された場合、 貼り付けたコードに『 ssh-rsa 』が含まれているかご確認ください

  1. 『 Add SSH KEY 』をクリックして保存。
  2. GithubのPWを入力

  3. 完了

  4. 登録できているか確認

[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'を追加

::ここの時点で一回アプリをクローンしてしまう::

$ gem install unicorn, ‘5.4.1’

config/unicorn.rbを作成

追加した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/environments/production.rb
config.assets.js_compressor = :uglifier
config/environments/production.rb
#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
#成功すると下記の表示が出ます
Setting up swapspace version 1, size = 512 MiB (536866816 bytes)
no label, UUID=909ccec6-4533-4a64-aea1-06a28fc4e3a8

スワップ(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'

これで完了

参考になる記事:linux スワップ(swap)領域の作成

参考になる記事:linux スワップ(swap)領域の作成

アプリケーションサーバの性能を決定する

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/environments/production.rb
config.assets.js_compressor = :uglifier
config/environments/production.rb
#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/

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

編集をするために「i」を入力

すると 『 -- 挿入 -- 』と表示されるので、入力が可能となります。 では、環境変数を定義していきましょう

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-*』をクリック

  5. インバウンドルール が表示される

  6. 『 インバウンド 』を選択

  7. 『 編集 』をクリック

  8. 左下の『ルールの追加』をクリック

  9. タイプ:「カスタムTCPルール」、プロトコルを「TCP」、ポート範囲を「3000」、送信元を「カスタム」「0.0.0.0/0」に設定

  10. 画面左下の『 保存 』をクリック

Railsの起動

Rails 5.1以前の場合

database.ymlに下記を追加します

config/database.yml(ローカル)
production:
  <<: *default
  database: アプリ名
  username: root
  password: <%= ENV['DATABASE_PASSWORD'] %>
  socket: /var/lib/mysql/mysql.sock

追記が完了したら、EC2でも反映させます。 EC2とGithubは接続できているため、git pullコマンドを利用します。

ターミナル(EC2)

[ec2-user@ip-172-31-23-189 <アプリ名>] git pull origin master

データベースの作成をする

ターミナル(EC2)

[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)

[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が起動していない可能性があります。

ターミナル(EC2)

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----モードに変更します

下記を入力します。

credentials.yml
db:
  database: アプリ名
  username: root
  password: 設定したPW
  socket: /var/lib/mysql/mysql.sock

passwordははじめてAWSでデプロイする方法⑤(EC2の環境構築、Ruby, MySQL)の『MySQLのrootパスワードの設定』で設定しています。

次に、database.ymlにcredential.ymlで設定した環境変数を記述します

config/database.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で異なるため失敗している。 解決策

ローカルのbundlerを確認

$ bundle -v
Bundler version 2.0.2

これで2.0.2のバージョンを利用しているとわかる。

EC2

[ec2-user@ip-172-31-23-189 <app名>]$ gem install bundler -v 2.0.2

これで最後にbundle installをして完了

EC2

[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が起動していない可能性があります。

ターミナル(EC2)

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の中身に漏れがないか確認をしてください

credentials.yml
db:
  database: アプリ名
  username: root
  password: 設定したPW
  socket: /var/lib/mysql/mysql.sock
config/database.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] %>
 #ここのsocketが抜けていないか???

サイトにアクセスしてみる ブラウザで http://<サーバに紐付けたElastic IP>:3000/ にアクセスしてみましょう ブラウザにCSSの反映されていない(ビューが崩れている)画面が表示されていれば成功です。

アセットコンパイルする

レイアウトが崩れてしまっているでしょう。

開発中には正常に表示されていたのに、本番ではうまく表示されないのはなぜでしょうか?

これは、開発中はアクセス毎にアセットファイル(画像・CSS・JSファイルの総称)を自動的にコンパイル(圧縮)する仕組みが備わっていますが、本番モードのときにはパフォーマンスのためアクセス毎には実行されないようになっているためです。

ターミナル(EC2)

[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"]

下記を修正してください

config/database.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] %>

追記したら

ターミナル(EC2)

[ec2-user@ip-172-31-23-189 <アプリ名>] git pull origin master

再度

ターミナル(EC2)

[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をインストール 下記のコマンドでインストール(できなかった)

[ec2-user@ip-172-31-30-254 lib]$ sudo yum -y install nginx
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                                                                                                                                                                          | 3.7 kB  00:00:00     
35 packages excluded due to repository priority protections
No package nginx available.
Error: Nothing to do


nginx is available in Amazon Linux Extra topic "nginx1"

To use, run
# sudo amazon-linux-extras install nginx1

Learn more at
https://aws.amazon.com/amazon-linux-2/faqs/#Amazon_Linux_Extras

となってできなかったので、言われている通り、

[ec2-user@ip-172-31-30-254 lib]$ sudo amazon-linux-extras install nginx1
Installing nginx
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Cleaning repos: amzn2-core amzn2extra-docker amzn2extra-nginx1 mysql-connectors-community mysql-tools-community mysql80-community nodesource yarn
22 metadata files removed
14 sqlite files removed
0 metadata files removed
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                                                                                                                                                                          | 3.7 kB  00:00:00     
amzn2extra-docker                                                                                                                                                                                                   | 3.0 kB  00:00:00     
amzn2extra-nginx1                                                                                                                                                                                                   
・
・
・

で、できたっぽい

Nginxの設定ファイルを編集 Nginxにアクセスされたときの動作を記載する設定ファイルを作成する。 設定ファイルは、/etc/nginx/conf.dフォルダ配下に作成する。拡張子が.confのものがすべて読み込まれる設定になっている。 Rails5をNginx経由で接続させるためのNginxの設定。Nginx+Puma+Rails5 - プログラミングで遊ぶ!

[ec2-user@ip-172-31-25-189 ~]$ sudo vim /etc/nginx/conf.d/rails.conf

下記を貼り付ける (ディレクトリの場所などは、自分にあった場所を指定してください)

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)

[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)

これでサイトが表示されず、下記が表示されたら、、、、、、、、、

f:id:dorcushopeino1:20200930131047p:plain

もう一度、下記をやり直してください。

Nginxの設定ファイルを編集

[ec2-user@ip-172-31-25-189 ~]$ sudo vim /etc/nginx/conf.d/rails.conf

下記を貼り付ける (ディレクトリの場所などは、自分にあった場所を指定してください)

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;
}

これで無事にサイトが表示されたら、完了です!

自分はうまくいかなかったので[INETドメインなソケット]なるものを使用して設定した。それとSELinux = permissiveにした

www.slideshare.net

MySQL - 【AWS・Rails】nginxで(111: Connection refused)エラー。|teratail

UNIXドメインなソケットを利用する理由がなければ、INETドメインなソケットを利用されてみてはいかがでしょうか。 私はUNIXドメインソケットについて、トラブルが多いので利用を避けています。

*/var/www/projects/{アプリ名}/config/unicorn.conf.rb 

listen  = 3000

/etc/nginx/conf.d/{アプリ名}.conf

upstream unicorn_server {
      server 127.0.0.1:3000;
}

そうするとうまく行った。