LoginSignup
1
3

More than 1 year has passed since last update.

詳しいことはさておき爆速でRailsアプリをAWSにてデプロイする方法

Last updated at Posted at 2021-07-14

詳しい概念や、説明はさておき、とにかくRailsアプリをAWSにデプロイする方法を解説します。

EC2の設定

リージョンの確認

Image from Gyazo

右上のサポートの横が東京になっていればOKです。

EC2インスタンスの作成

EC2をクリックして

Image from Gyazo

画面下部のインスタンスを起動をクリック

AMIを選択

「 Amazon Linux 2 AMI 」という、AWSが独自にカスタマイズしたAMIを利用
多分一番上です。

インスタンスタイプは無料枠で使用できる「t2.micro」を選択して、「確認と作成」をクリック

次の画面では「起動」をクリック

キーペアの作成

起動をクリックするとキーペアの選択画面になります。

Image from Gyazo

キーペアはアプリごとに作成しても良いし、一つだけでも良いですが、アプリごとに作成する方法で解説します。

新しいキーペアの作成を選択してキーペア名を入力。
そしてキーペアのダウンロードをしてください。

注意点はこのpemファイルは絶対に削除しないこと。
キーペア名はスペースを含めないこと。

インスタンスの確認

Image from Gyazo

インスタンス名をクリックして、インスタンスIDをコピーしておきましょう。

Elastic IPの作成

Image from Gyazo

左側のメニューからElastic IPを選択

Image from Gyazo

右上のElastic IPの割り当てをクリック

Image from Gyazo

画面が遷移したら、「Amazon の IPv4 アドレスプール」にチェックが入ってることを確認。
確認後、「割り当て」をクリック。

Image from Gyazo

Elastic IPの紐付け

先ほどの画面の右上からアクションをクリック
表示されたプルダウンから「Elastic IP アドレスの関連付け」を選択

Image from Gyazo

先ほどメモしたインスタンスIDを選択

あとは空欄で関連付けるをクリック

Image from Gyazo

先ほどは空欄だったElastic IPにアドレスが割り当てられてます。

EC2の設定変更

立ち上げたばかりのEC2はsshでしか接続できない。
HTTP通信では接続できないので、サーバーとして使用する場合はHTTP通信を許可するためにポートの開放が必要。
そのための設定変更をします。

セキュリティグループのポートを設定

Image from Gyazo

インスタンスの概要の下部のセキュリティをクリック
セキュリティグループをクリック

Image from Gyazo

インバウンドルールの右上のEdit~をクリック

Image from Gyazo

これで設定が完了

EC2インスタンスへログイン

ターミナル

% cd ~

% mkdir ~/.ssh
# .sshというディレクトリを作成

% mv Downloads/ダウンロードした鍵の名前.pem .ssh/
# mvコマンドで、ダウンロードしたpemファイルを、ダウンロードディレクトリから、.sshディレクトリに移動します。

% cd .ssh/

% ls
# pemファイルが存在するか確認しましょう

% chmod 600 ダウンロードした鍵の名前.pem

% ssh -i ダウンロードした鍵の名前.pem ec2-user@作成したEC2インスタンスに紐付けたElastic IP

これで

% ssh -i aws_key.pem ec2-user@52.68.~~~~~~
The authenticity of host '52.68.~~~~~~ (52.68.~~~~~~)' can't be established.
RSA key fingerprint is eb:7a:bd:e6:aa:da:~~~~~~~~~~~~~~~~~~~~~~~~.
Are you sure you want to continue connecting (yes/no)? 

(ここで「yes」を入力し、実行する)

Image from Gyazo

この画像になればOK

設定に必要なツールのインストール

ターミナルで下記を実行

[ec2-user@ip-172-31-25-*** ~]$ 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 libcurl libcurl-devel curl

EC2上でJavaScriptを動かす設定

[ec2-user@ip-172-31-25-189 ~]$ sudo curl -sL https://rpm.nodesource.com/setup_10.x | sudo bash -
[ec2-user@ip-172-31-25-189 ~]$ sudo yum -y install nodejs

Yarnのインストール

[ec2-user@ip-172-31-25-189 ~]$ sudo yum -y install wget
[ec2-user@ip-172-31-25-189 ~]$ sudo wget https://dl.yarnpkg.com/rpm/yarn.repo -O /etc/yum.repos.d/yarn.repo
[ec2-user@ip-172-31-25-189 ~]$ sudo yum -y install yarn

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

# ①rbenvのインストール
[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 

# ③rbenvを呼び出すための記述
[ec2-user@ip-172-31-25-189 ~]$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

# ④.bash_profileの読み込み
[ec2-user@ip-172-31-25-189 ~]$ source .bash_profile

# ⑤ruby-buildのインストール
[ec2-user@ip-172-31-25-189 ~]$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

# ⑥rehashを行う
[ec2-user@ip-172-31-25-189 ~]$ rbenv rehash 

Rubyのインストール

# Ruby 2.6.5のバージョンをインストール
[ec2-user@ip-172-31-25-189 ~]$ rbenv install 2.6.5

# EC2インスタンス内で使用するRubyのバージョンを決める
[ec2-user@ip-172-31-25-189 ~]$ rbenv global 2.6.5

# rehashを行う
[ec2-user@ip-172-31-25-189 ~]$ rbenv rehash  

# Rubyのバージョンを確認
[ec2-user@ip-172-31-25-189 ~]$ ruby -v 

バージョンはお使いのバージョンに合わせてください。

データベース

MariaDBを起動

「MariaDB」とは、MySQLの派生として開発されているオープンソースソフトウェアです。MySQLとの互換性があります。
基本的にMariaDBとMySQLは同様のものと考えていただいて差し支えありません。

MariaDBをインストール

[ec2-user@ip-172-31-25-189 ~]$ sudo yum -y install  mariadb-server mysql-devel

データベースの起動

[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl start mariadb
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl status mariadb
#起動したか確認するコマンド

「active (running) 」と緑色の表示がされれば、データベースの起動は成功

データベースのrootパスワードの設定

[ec2-user@ip-172-31-25-189 ~]$ sudo /usr/bin/mysql_secure_installation

ここでやること

  • Enter current password for root (enter for none): 」と表示されたらEnterキーを押す
  • 「Set root password? [Y/n]」と表示されたら「Y」を入力してEnterキーを押す
  • 「New password:」と表示されたら自身で決めたパスワードを入力(※とくに画面には何も表示されません)
  • 「Re-enter new password:」と表示されたら、同じパスワードを入力
  • 「... Success!」と表示されればパスワードの設定自体は完了
  • 「Remove anonymous users? [Y/n]」と表示されたら「Y」を入力してEnterキーを押す
  • 「Disallow root login remotely? [Y/n]」と表示されたら「Y」を入力してEnterキーを押す
  • 「Remove test database and access to it? [Y/n]」と表示されたら「Y」を入力してEnterキーを押す
  • 「Reload privilege tables now? [Y/n]」と表示されたら「Y」を入力してEnterキーを押す

これでOKです。

EC2上でRailsを起動

EC2サーバーのssh鍵のペアを作成し、GitHubにssh鍵を登録

[ec2-user@ip-172-31-23-189 ~]$ ssh-keygen -t rsa -b 4096

#途中で「passphrase」など3段階ほど入力を求められることがありますが、すべて何も入力せずにEnterキーを押して進んでください。

Generating public/private rsa key pair.
Enter file in which to save the key (/home/ec2-user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/ec2-user/.ssh/id_rsa.
Your public key has been saved in /home/ec2-user/.ssh/id_rsa.pub.
The key fingerprint is:
3a:8c:1d:d1:a9:22:c7:6e:6b:43:22:31:0f:ca:63:fa ec2-user@ip-172-31-23-189
The key's randomart image is:
+--[ RSA 4096]----+
|    +            |
| . . =           |
|  = . o .        |
| * o . o         |
|= *     S        |
|.* +     .       |
|  * +            |
| .E+ .           |
| .o              |
+-----------------+

ssh公開鍵の値を確認し、GitHubに登録

[ec2-user@ip-172-31-23-189 ~]$ cat ~/.ssh/id_rsa.pub

#実行結果
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDLwt......

この実行結果を全てコピーしてください

コピーした公開鍵をGitHubに登録

このリンクの右上のNew SSHから追加できます。

タイトルは空欄でもOKですが、複数アプリ作るなら任意の名前をつけてください。
その下の欄に先ほどコピーしたSSH公開鍵を登録してください。

Githubで設定がきちんと反映されているか確認しましょう。

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

#途中でこのまま続けるかどうか、「Yes/No」または「y/n」などの選択肢で聞かれることがあります。
その場合は「Yes」または「y」を入力をし、Enterキーを押下して進んでください。

アプリケーションサーバーの設定

今回はUnicornを使用します。
rails sとローカルサーバーを立ち上げるときにログにpumaと出ると思いますが、これがアプリケーションサーバーです。

で、当然EC2上でもアプリケーションサーバーを設定しなければいけません。

そこで使用するのがUnicornです。

Unicornのインストール

group :production do
  gem 'unicorn', '5.4.1'
end

でいつも通りbundle install

「config/unicorn.rb」を作成

config/unicorn.rb
#サーバ上でのアプリケーションコードが設置されているディレクトリを変数に入れておく
app_path = File.expand_path('../../', __FILE__)

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

#アプリケーションの設置されているディレクトリを指定
working_directory app_path

#Unicornの起動に必要なファイルの設置場所を指定
pid "#{app_path}/tmp/pids/unicorn.pid"

#ポート番号を指定
listen 3000

#エラーのログを記録するファイルを指定
stderr_path "#{app_path}/log/unicorn.stderr.log"

#通常のログを記録するファイルを指定
stdout_path "#{app_path}/log/unicorn.stdout.log"

#Railsアプリケーションの応答を待つ上限時間を設定
timeout 60

#以下は応用的な設定なので説明は割愛

preload_app true
GC.respond_to?(:copy_on_write_friendly=) && GC.copy_on_write_friendly = true

check_client_connection false

run_once = true

before_fork do |server, worker|
  defined?(ActiveRecord::Base) &&
    ActiveRecord::Base.connection.disconnect!

  if run_once
    run_once = false # prevent from firing again
  end

  old_pid = "#{server.config[:pid]}.oldbin"
  if File.exist?(old_pid) && server.pid != old_pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH => e
      logger.error e
    end
  end
end

after_fork do |_server, _worker|
  defined?(ActiveRecord::Base) && ActiveRecord::Base.establish_connection
end

そのままコピペでOKです。

リモートリポジトリに「commit→push」

EC2上にリポジトリの情報を反映

#mkdirコマンドで新たにディレクトリを作成
[ec2-user@ip-172-31-23-189 ~]$ sudo mkdir /var/www/

#作成したwwwディレクトリの権限をec2-userに変更
[ec2-user@ip-172-31-23-189 ~]$ sudo chown ec2-user /var/www/

GitHubから「リポジトリURL」を取得

[ec2-user@ip-172-31-23-189 ~]$ cd /var/www/
[ec2-user@ip-172-31-23-189 www]$ git clone コピーしたURLを貼り付ける

これでエラーが出なければOK

EC2の能力を拡張

Swapファイルの領域を広げます。
「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) コピーされました、 7.35077 秒、 73.0 MB/秒
[ec2-user@ip-172-31-25-189 ~]$ sudo chmod 600 /swapfile1

[ec2-user@ip-172-31-25-189 ~]$ sudo mkswap /swapfile1

# 以下のように表示されれば成功
スワップ空間バージョン1を設定します、サイズ = 524284 KiB
ラベルはありません, UUID=74a961ba-7a33-4c18-b1cd-9779bcda8ab1

[ec2-user@ip-172-31-25-189 ~]$ sudo swapon /swapfile1

[ec2-user@ip-172-31-25-189 ~]$ sudo sh -c 'echo "/swapfile1  none        swap    sw              0   0" >> /etc/fstab'

EC2内でgemをインストール

# クローンしたディレクトリに移動
[ec2-user@ip-172-31-23-189 www]$ cd  /var/www/開発中のアプリケーション

# rubyのバージョンを確認
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ruby -v
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]

ローカルで開発してきたアプリケーションでどのバージョンのbundlerが使われていたのか確認

# 開発中のアプリケーションのディレクトリで実行

% bundler -v
Bundler version 2.1.4
# 「2.1.4」の箇所は、ローカルで確認したbundlerのバージョンを導入します
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ gem install bundler -v 2.1.4

# 以下のコマンドは、処理に数分以上かかる場合があります
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ bundle install

環境変数を設定

secret_key_baseを作成

[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ rake secret
69619d9a75b78f2e1c87ec5e07541b42f23efeb6a54e97da3723de0.....

出力結果はどこかにメモしといてください。

[ec2-user@ip-172-31-23-189 ~]$ sudo vim /etc/environment

何も表示されない画面に変わると思うので、「i」を入力して挿入モードにする

DATABASE_PASSWORD='先ほど設定したパスワード'
SECRET_KEY_BASE='rake secretの出力結果'
AWS_ACCESS_KEY_ID='ご自身のアクセスキー'
AWS_SECRET_ACCESS_KEY='ご自身のシークレットキー'

#その他環境変数に設定したいキーがあれば入力してください。
自分はGoogleのAPIを使用しているので、Googleを付け加えました。
[ec2-user@ip-172-31-23-189 ~]$ exit

一度ログアウト

$ ssh -i [ダウンロードした鍵の名前].pem ec2-user@[作成したEC2インスタンスと紐付けたElastic IP]

#環境変数が設定されているか確認

[ec2-user@ip-172-31-23-189 ~]$ env | grep SECRET_KEY_BASE

#こんな感じで確認してください。

ポートを解放

セキュリティグループのポートを設定

Image from Gyazo

AWSのインスタンスの詳細画面で、画面下部のセキュリティをクリックして、セキュリティグループのリンクをクリック

Image from Gyazo

インバウンドルールの右上のEdit~をクリック

タイプ:カスタムTCP
プロトコル:TCP
ポート範囲:3000
送信元:カスタム/0.0.0.0/0

Railsを起動

本番環境でRailsを起動

config/database.yml
production:
  <<: *default
  database: #編集しない
#下記を編集
  username: root
  password: <%= ENV['DATABASE_PASSWORD'] %>
  socket: /var/lib/mysql/mysql.sock

Githubでマスターをマージして

[ec2-user@ip-172-31-23-189 <リポジトリ名>] git pull origin master

DBの作成とマイグレーション、Railsの起動

[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ rails db:create RAILS_ENV=production
Created database '<データベース名>'
[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'」
というエラーが起こった場合、データベースが起動していない可能性がある
「sudo systemctl start mariadb」というコマンドをターミナルから打ち込み、mysqlの起動を試してみましょう。
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ bundle exec unicorn_rails -c config/unicorn.rb -E production -D

アセットファイルのコンパイル

[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ rails assets:precompile RAILS_ENV=production

Railsの再起動が必要なので、Railsを再起動する

[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

[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill <確認したunicorn rails masterのプロセスid>

[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -D

RAILS_SERVE_STATIC_FILES=1でRailsがコンパイルされたアセットを見つけられるように指定する役割があります。

このコマンドを実行したときにエラーが出ることがあります。
エラーの内容次第ですが、パターンは3つになります。

①rbenvをrehash

rbenv rehash

②Githubにマージされてない

マージした後に

git push -u origin master

③master failed to start, check stderr log for detailsと出た

ログを見ましょう

[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ less log/unicorn.stderr.log

これを実行するとファイル名が並ぶので、

「一番下から最新のログ」を確認する。

アクセスする

http://<Elastic IP>:3000/

にアクセスすると、無事表示されます。

WEBサーバーの設定

Nginxを導入

[ec2-user@ip-172-31-25-189 ~]$ sudo amazon-linux-extras install nginx1

Is this ok [y/d/N]:と出てきたら、yを選択して決定

Nginxの設定ファイルを編集

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

ファイルが開けたら「i」を押して、インサートモードにします。

/etc/nginx/conf.d/rails.conf
upstream app_server {
  # Unicornと連携させるための設定
  server unix:/var/www/リポジトリ名/tmp/sockets/unicorn.sock;
}

# {}で囲った部分をブロックと呼ぶ。サーバの設定ができる
server {
  # このプログラムが接続を受け付けるポート番号
  listen 80;
  # 接続を受け付けるリクエストURL ここに書いていないURLではアクセスできない
  server_name 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;
}

リポジトリ名とElastic IPはご自身のものに変更してください。

[ec2-user@ip-172-31-25-189 ~]$ cd /var/lib
[ec2-user@ip-172-31-25-189 lib]$ sudo chmod -R 775 nginx
[ec2-user@ip-172-31-25-189 lib]$ cd ~
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl reload nginx
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl start nginx

これで設定変更が完了です!

Unicornの設定を変更

config/unicorn.rb
(省略)

listen 3000

(省略)
config/unicorn.rb
listen "#{app_path}/tmp/sockets/unicorn.sock"

こちらに変更して、commitしてpushしてください。

# 開発中のアプリケーションに移動
[ec2-user@ip-172-31-25-189 ~]$ cd /var/www/開発中のアプリケーション

# GitHubの内容をEC2に反映させる
[ec2-user@ip-172-31-23-189 <レポジトリ名>]$ git pull origin master

#Unicornの再起動
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ps aux | grep unicorn
#killするプロセスIDを確認
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill プロセスID
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -D

ここまで完了したら

http://<Elastic IP>

にアクセスする

これで手動デプロイの完了です。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3