Railsを本番環境にデプロイ(with Unicorn, Nginx, EC2, MySQL, Capistrano, Elastic IP)
こちらの記事をほぼまるまんまなのですが、少し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必要パッケージのインストールと設定
# 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
パッケージはこうなっていればいいらしい
(yを入力してEnterを押下する際にインストールパッケージとリポジトリが下記の様になっていることを確認する。)
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
ログの確認
- 下記コマンドを実行してMySQLのlogファイルを開く
$ sudo less /var/log/mysqld.log
- 開いたファイル内で下記の様な一行を見つける。
/var/log/mysqld.logYYYY-MM-DDTHH:MM:SS.260490Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: XXXXXXXXXXXX
- ファイルに記載された行のXXXXXXXXXXXXの部分がrootユーザの初期パスワードとなる。
MySQLログイン確認
- 開いているmysqld.logファイルを閉じる。
- 下記コマンドを実行してmysqldを停止する。
$ sudo service mysqld stop
- 下記コマンドを実行してmysqldを起動する。
$ sudo service mysqld start
- 下記コマンドを実行してmysqlにrootユーザでログインする。
- 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ユーザのパスワードが条件を満たしていない。)
パスワードの再設定
- 先の方法で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@とか
- 下記を実行して一旦MySQLからログアウトする。
mysql> exit
DBの作成
- 下記コマンドを実行してMySQLにrootユーザでログインする。(ログイン時のパスワードが先に設定し直したパスワードを入力する。)
$ mysql -u root -p
- MySQLログイン後下記を実行して「test」という名前のDBを作成する。
mysql> create database test;
- 下記を実行して「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
- 下記が表示されるので、エンターを押す
Enter file in which to save the key (/home/ec2-user/.ssh/id_rsa):
- さらにエンターを押す(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 | +-----------------+
- SSH公開鍵を表示し、値をコピーするため、下記コマンドを実装
[ec2-user@ip-172-31-23-189 ~]$ cat ~/.ssh/id_rsa.pub
- 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にアクセス
エラー「Key is invalid. You must supply a key in OpenSSH public key format」が表示された場合、 貼り付けたコードに『 ssh-rsa 』が含まれているかご確認ください
[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)領域の作成
アプリケーションサーバの性能を決定する
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がつながるように「ポート」を開放する必要があります。
手順
EC2を開く
『実行中のインスタンス』を開く
インスタンスを選択
セキュリティグループの『launch-wizard-*』をクリック
インバウンドルール が表示される
『 インバウンド 』を選択
『 編集 』をクリック
左下の『ルールの追加』をクリック
タイプ:「カスタムTCPルール」、プロトコルを「TCP」、ポート範囲を「3000」、送信元を「カスタム」「0.0.0.0/0」に設定
画面左下の『 保存 』をクリック
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)
これでサイトが表示されず、下記が表示されたら、、、、、、、、、
もう一度、下記をやり直してください。
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; }
そうするとうまく行った。