search
LoginSignup
4
Help us understand the problem. What are the problem?

posted at

updated at

Webアプリデプロイ方法(AWS EC2編)

目次

1.はじめに
2.前提
3.新規ユーザ作成
4.各種ソフトウェアインストール
5.githubからのアプリクローン
6.アプリのシークレット設定
7.webサーバ設定
8.applicationサーバ設定
9.db設定
10.アプリ起動
11.まとめ
12.参考

はじめに

前回の記事「Webアプリ公開のためのインフラ環境をCloudFormationで構築してみた」を通し、Webアプリデプロイ用のインフラ環境を準備することができました。今回は作成したAWS EC2上に、RailsのWebアプリをデプロイしましたので、大まかな手順を整理します。

前提

前回、CloudFormationで構築した以下のAWS構成にて、EC2上にRailsのWebアプリをデプロイしていきます。
全体.png

■ デプロイするWebアプリ
個人的に以下、学習系のWebアプリを開発してみましたので、こちらをデプロイしてみます。

  • WebアプリURL : https://www.memory-tank.tk/
    (PC推奨)

  • Rails:6.0.3

  • Ruby:2.6.5

  • 概要
    効率的なナレッジ蓄積と知識定着を支援するアプリ。
    ユーザは様々なWord(単語)や自作の四択問題をカテゴリ別に管理した上で蓄積することができる。
    また、蓄積したWordや四択問題はユーザ自身の定着率/正答率に応じて、習得済と未習得の2つのカテゴリに分割して自動管理される。

以降、実際のデプロイの手順を記載していきますが、まずは全体像、大まかな流れをまとめます。

             
作業概要 内容
新規ユーザ作成アプリ管理用のOSユーザを作成する
各種ソフトウェアインストール プラグイン/MySQL/Node.js/rbenv/ruby-build/Rubyをインストールする
GitHubからのアプリクローンGitHubからEC2上にアプリをクローン/配置する
アプリのシークレット設定アプリのシークレットを生成し、設定する
Webサーバ設定Nginxの設定ファイルを修正する
Applicationサーバ設定Unicornの設定ファイルを修正する
DB設定DBへのアクセスに関わる設定ファイルを修正する
アプリ起動Nginx/Unicornを起動する

新規ユーザ作成

AWSのEC2インスタンスを作成するとデフォルトユーザ「ec2-user」が使えますが、複数人でアプリを管理していくことを想定し、ここでもう1つの管理用OSユーザを作成しておきます。

  • EC2へのログイン
ローカル環境
#ローカル環境で、EC2インスタンスの秘密鍵が格納されたパスに移動する
$ cd ~/.ssh
#秘密鍵を指定し、ec2-userでEC2にログインする (yes/noを聞かれるので、yesと入力する)
$ ssh -i 秘密鍵の名前.pem ec2-user@EC2のElasticIPアドレス
  • 新規ユーザの作成
EC2
#adduserの後ろに、作成したいユーザのユーザ名を指定する
$ sudo adduser ユーザ名
  • 新規ユーザのパスワード設定
EC2
#以下のコマンドを実行後、設定したいパスワードを求められるので入力する
$ sudo passwd ユーザ名
  • 新規ユーザのsudo権限を設定
EC2
#visudoファイルを編集する
$ sudo visudo

1. 以下の、rootに関する権限の記述箇所を探す
  root    ALL=(ALL)       ALL
2. 「i」を入力して、入力モードに切り替える
3. 1で探した行の下に以下の記述を追記する ※ 新規作成ユーザの権限設定
  ユーザ名   ALL=(ALL)       ALL 
4. 「esc」を押して入力モードを終了する
5. 「:wq」を入力後、エンターを押して編集を完了する
  • 新規ユーザへの切り替えができることの確認
EC2
#以下を実行後、プロンプトの[ec2-user|の表示が新規作成のユーザ名に切り替わればOK
$ sudo su - ユーザ名
  • EC2へSSH接続をするための鍵をローカル環境で作成
ローカル環境
#.sshディレクトリに移動する
$ cd ~/.ssh
#以下のコマンドでSSHの鍵を作成する
$ ssh-keygen -t rsa
--------------------------------
#以下のメッセージが表示されるので、「任意の名前_key_rsa」を入力する
Enter file in which to save the key ():任意の名前_key_rsa

#何もせずにエンターを押す
Enter passphrase (empty for no passphrase):

#何もせずにエンターを押す
Enter same passphrase again:
--------------------------------
  • 秘密鍵/公開鍵が作成されたことの確認
ローカル環境
#lsコマンド実行後、秘密鍵「任意の名前_key_rsa」と公開鍵「任意の名前_key_rsa.pub」が表示されることを確認する
$ ls
  • ~/.ssh/config (SSH経由でリモートサーバーに接続する際に利用される設定ファイル)の編集
ローカル環境
# ~/.ssh/configファイルを編集する
$ vi config

1. 「i」を入力し、入力モードに切り替え、以下を追記する
--------------------------------
#Hostの後ろに、先ほど作成した秘密鍵の名前を記載する
Host 任意の名前_key_rsa
#Hostnameの後ろに、EC2のElastic IPアドレスを記載する
  Hostname EC2のElastic IPアドレス
#ポート番号22番を指定する
  Port 22
#Userの後ろに、先ほど作成した新規ユーザのユーザ名を記載する
  User ユーザ名 
#IdentityFileの後ろに、先ほど作成した秘密鍵のフルパスを記載する
  IdentityFile ~/.ssh/任意の名前_key_rsa
--------------------------------
2. 「esc」を押して入力モードを終了する
3. 「:wq」を入力後、エンターを押して編集を完了する
  • 公開鍵の中身をコピー
ローカル環境
#公開鍵の中身をcatコマンドで出力し、全文をコピーする
$ cat 任意の名前_key_rsa.pub
  • サーバ側で公開鍵を設定 (先ほど作成したユーザで実施する)
EC2
#公開鍵格納用のディレクトリを作成する
$ mkdir .ssh
#作成したディレクトリのアクセス権限を設定する
$ chmod 700 .ssh
#作成したディレクトリに移動する
$ cd .ssh
#公開鍵を記録するファイルを作成する
$ vi authorized_keys

1. 「i」を入力し、入力モードに切り替え、以下を追記する
----------------------------------------
ローカル環境でコピーした公開鍵の中身を貼り付ける
----------------------------------------
2. 「esc」を押して入力モードを終了する
3. 「:wq」を入力後、エンターを押して編集を完了する
#公開鍵を記録するファイルのアクセス権限を設定する
$ chmod 600 authorized_keys
#新規作成ユーザからサインアウトする
$ exit
#ec2-userからサインアウトする
$ exit
  • 新規作成ユーザでのSSH接続確認
ローカル環境
#作成した秘密鍵を指定し、EC2にSSH接続をする
$ ssh 任意の名前_key_rsa

無事にログインができたら、最初のステップ「新規ユーザ作成」は完了です。

各種ソフトウェアインストール

次に、Webアプリを動かす上で必要な各種ソフトウェアをインストールしていきます。
Nginxは前回記事のCloudFormationにて、EC2のユーザデータよりインストール済で自動起動設定もしてあります。

  • サーバのアップデート
EC2
#まずはEC2内のソフトウェアをアップデートしておきます。
$ sudo yum update -y
  • 各種プラグインのインストール
EC2
#Git/コンパイル用コマンド/コンパイラ/パッチ適用コマンド/OpenSSL用ファイル/Ruby用パッケージ/アプリ開発用ライブラリ
$ 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 5.7 のインストール
EC2
#MySQL公式のyumリポジトリを追加
$ sudo rpm -ivh http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
#MySQLをインストール
$ sudo yum install mysql-devel mysql57 mysql57-server
$ sudo yum install mysql mysql-server mysql-utilities
  • Node.js 15.5 のインストール
EC2
#Node.jsのバージョン管理ツールnvmをインストールする
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
#以下コマンド実行後、プロンプトに「nvm」と表示されることを確認する
$ command -v nvm
#上記で「nvm」が表示されなかった場合は以下を実行する
$ source ~/.bash_profile
#Node.jsをバージョン指定でインストールする
$ nvm install 15.5.0
  • rbenvのインストール
EC2
#rbenv (rubyのバージョン管理ツール)をインストールする
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
#パスを通す
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
#shims と autocompletion の有効化設定を追記
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
#設定ファイルを反映させる
$ source ~/.bash_profile
  • ruby-build のインストール
EC2
#ruby-build (rubyのビルドツール)をインストールする
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
# ~/.rbenv/versions/*/bin/ 以下のファイルを ~/.rbenv/shims/ 以下にコピーする
$ rbenv rehash
  • Rubyのインストール
EC2
#ローカル環境で開発したアプリのRubyバージョンと同じバージョンを指定し、インストールする
$ rbenv install -v 2.6.5
#使用するRubyのバージョンを指定する
$ rbenv global 2.6.5
# ~/.rbenv/versions/*/bin/ 以下のファイルを ~/.rbenv/shims/ 以下にコピーする
$ rbenv rehash
# Rubyのバージョンを表示し、インストールしたものと同じになっていることを確認する
$ ruby -v

ここまでで「各種ソフトウェアインストール」は完了です。

githubからのアプリクローン

次に、GitHubから、開発したアプリをEC2上にクローンしていきます。

  • 設定ファイルの作成
EC2
#ホームディレクトリに移動
$ cd ~
#gitの設定ファイルを作成する
$ vi .gitconfig

1. 「i」を入力し、入力モードに切り替え、以下を追記する
--------------------------------
[user]
  name = gitに登録した自分の名前
  email = git登録時の自分のメールアドレス

#pull、pushのための設定
[url "github:"]
    InsteadOf = https://github.com/
    InsteadOf = git@github.com:
--------------------------------
2. 「esc」を押して入力モードを終了する
3. 「:wq」を入力後、エンターを押して編集を完了する
  • アプリ配置のディレクトリ作成
EC2
#ルートディレクトリに移動
$ cd /
#var/wwwディレクトリを作成
$ sudo mkdir var/www
#var/www/railsディレクトリを作成
$ sudo mkdir var/www/rails
#varディレクトリの所有者を新規作成ユーザにする
$ sudo chown ユーザ名 var
#varディレクトリに移動する
$ cd var/
#www配下の所有者を新規作成ユーザにする
$ sudo chown -R ユーザ名 www
  • git接続用の鍵作成
EC2
#ホームディレクトリに移動する
$ cd ~
#.sshディレクトリの権限を設定する
$ chmod 700 .ssh
#.sshディレクトリに移動する
$ cd .ssh
#sshの鍵を作成する
$ ssh-keygen -t rsa
--------------------------------
以下のメッセージが表示されるので、「ec2_git_rsa」と入力する
Enter file in which to save the key ():ec2_git_rsa

何もせずにエンターを押す
Enter passphrase (empty for no passphrase):

何もせずにエンターを押す
Enter same passphrase again:
--------------------------------
#lsコマンドを実行後、秘密鍵「ec2_key_rsa」と公開鍵「ec2_key_rsa.pub」が表示されることを確認する
$ ls
#設定ファイルを作成する
$ vi config

1. 「i」を入力し、入力モードに切り替え、以下を追記する
-----------------------------
Host github github.com
  Hostname github.com
  User git
  IdentityFile ~/.ssh/ec2_git_rsa
-----------------------------
2. 「esc」を押して入力モードを終了する
3. 「:wq」を入力後、エンターを押して編集を完了する
#公開鍵の中身をcatコマンドで出力し、全文をコピーする
$ cat ec2_git_rsa.pub
  • 公開鍵をGitHubにアップ
  1. GitHubの「settings」→ 「SSH and GPG keys」を押下する
    スクリーンショット 2021-06-12 10.08.24.png

  2. 「New SSH key」を押下する
    スクリーンショット 2021-06-12 10.11.15.png

  3. 「Title」に先ほど作成した公開鍵名、「Key」に先ほどコピーした公開鍵の中身を入力し、「Add SSH key」を押下する
    スクリーンショット 2021-06-12 10.14.41.png

EC2
#ターミナルへ戻り設定ファイルの権限を変更しておく
$ chmod 600 config
  • GitHubからアプリをクローン
EC2
# /var/www/railsディレクトリに移動する
$ cd /var/www/rails
# アプリをクローンする
$ git clone クローンしたいアプリのGitHubのURL
#lsコマンド実行後、各自のアプリディレクトリ/ファイルが表示されればOK
$ ls
#アプリのディレクトリに移動する
$ cd アプリ名
#bundlerのインストール (バージョンはローカル環境と同じものを指定すること)
$ gem install bundler -v 2.2.14
#Gemのインストール
$ bundle install

※ アプリのURLはGitHubで「Code」→ 赤枠内のアイコンを押下するとコピーができる
スクリーンショット 2021-06-12 10.23.17.png

ここまでで「githubからのアプリクローン」は完了です。

アプリのシークレット設定

次にアプリのシークレット設定をしていきます。

  • マスターキーの作成
ローカル環境(開発したアプリのディレクトリ内で実施)
#以下を実行し、表示されるマスターキーコピーする
$ vi config/master.key

「:q!」を入力後、エンターを押して特に編集をせずに完了する
EC2(クローンしたアプリのディレクトリ内で実施)
#configディレクトリに移動
$ cd config
#マスターキーの作成
$ vi master.key

1. 「i」を入力し、入力モードに切り替え、以下を追記する
-----------------------------
先ほどコピーしたマスターキーの値
-----------------------------
2. 「esc」を押して入力モードを終了する
3. 「:wq」を入力後、エンターを押して編集を完了する
  • シークレットの作成
ローカル環境(開発したアプリのディレクトリ内で実施)
#以下コマンドで表示されたシークレットキーをコピーする
$ bundle exec rake secret
EC2(クローンしたアプリのディレクトリ内で実施)
#アプリのディレクトリ直下に移動する
$ cd /var/www/rails/アプリ名
#credentials.yml.encを編集する
$ EDITOR=vi bin/rails credentials:edit

1. 「i」を入力し、入力モードに切り替え、以下を編集する
-----------------------------
# aws:
#   access_key_id: 123
#   secret_access_key: 345

# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: 先ほどコピーしたシークレットキーをペースト
-----------------------------
2. 「esc」を押して入力モードを終了する
3. 「:wq」を入力後、エンターを押して編集を完了する

ここまでで「アプリのシークレット設定」は完了です。

webサーバ設定

次にWebサーバ設定として、Nginxの設定ファイルを編集していきます。

  • 設定ファイル編集
EC2(クローンしたアプリのディレクトリ内で実施)
#nginxのディレクトリに移動する
$ cd /etc/nginx/conf.d/
#設定ファイルを編集する ※ アプリ名の部分は各自、変えてください。
$ sudo vi アプリ名.conf

1. 「i」を入力し、入力モードに切り替え、以下を追記する
-----------------------------
# log directory
#エラーログのパス指定
error_log  /var/www/rails/アプリ名/log/nginx.error.log; 
#アクセスログのパス指定
access_log /var/www/rails/アプリ名/log/nginx.access.log; 
#unicornとの接続設定
upstream unicorn_server {
    server unix:/var/www/rails/アプリ名/tmp/sockets/.unicorn.sock fail_timeout=0; 
}

server {
    #受け付けるポート番号
    listen 80;
   # クライアントからアップロードされてくるファイル容量の最大値を指定
    client_max_body_size 4G;
   # 接続を許可するリクエストのURL
    server_name 各自のアプリのドメイン名
   #タイムアウト値
    keepalive_timeout 5;
    # 接続が来た際のrootディレクトリ
    root /var/www/rails/アプリ名/public; 
   # assetsファイル(CSSやJavaScriptのファイル)にアクセスが来た際に適用される設定
    location ~ ^/assets/ {
        root /var/www/rails/アプリ名/public; 
    }

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;

        if (!-f $request_filename) {
            proxy_pass http://unicorn_server;
            break;
        }
    }

    error_page 500 502 503 504 /500.html;
    location = /500.html {
        root /var/www/rails/アプリ名/public; 
    }
}
-----------------------------
2. 「esc」を押して入力モードを終了する
3. 「:wq」を入力後、エンターを押して編集を完了する

ここまでで「webサーバ設定」は完了です。

applicationサーバ設定

次にApplicationサーバ設定として、Unicornの設定ファイルを編集していきます。

  • Unicornのインストール
EC2(クローンしたアプリのディレクトリ内で実施)
#アプリのディレクトリ直下に移動する
$ cd /var/www/rails/アプリ名
#Gemfileを編集する
$ vi Gemfile

1. 「i」を入力し、入力モードに切り替え、以下を追記する
-----------------------------
group :production, :staging do
    gem 'unicorn'
end
----------------------------
2. 「esc」を押して入力モードを終了する
3. 「:wq」を入力後、エンターを押して編集を完了する
#Unicornをインストールする
$ gem install bundler
$ bundle install
  • 設定ファイルの編集
EC2(クローンしたアプリのディレクトリ内で実施)
#設定ファイルを編集する ※ アプリ名の部分は各自、変えてください。
$ vi config/unicorn.conf.rb

1. 「i」を入力し、入力モードに切り替え、以下を追記する
-----------------------------
  #アプリケーションサーバの性能
  $worker  = 2
  #Railsアプリケーションの応答を待つ上限時間
  $timeout = 30
  #アプリケーションコードが設置されているディレクトリ
  $app_dir = "/var/www/rails/アプリ名" 
  #待ち受けパス
  $listen  = File.expand_path 'tmp/sockets/.unicorn.sock', $app_dir
  #Unicornの起動に必要なファイルのパス
  $pid     = File.expand_path 'tmp/pids/unicorn.pid', $app_dir
  #ログのパス
  $std_log = File.expand_path 'log/unicorn.log', $app_dir

  #ワーカープロセス数の設定
  worker_processes  $worker
  #アプリケーションコードが設置されているディレクトリを設定
  working_directory $app_dir
  #エラーログの設定
  stderr_path $std_log
  #通常ログの設定
  stdout_path $std_log
  #タイムアウト値の設定
  timeout $timeout
  #待ち受けの設定
  listen  $listen
  #Unicornの起動に必要なファイルの設定
  pid $pid

  preload_app true
  # プロセス起動前処理
  before_fork do |server, worker|
    defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
    old_pid = "#{server.config[:pid]}.oldbin"
    if old_pid != server.pid
      begin
        Process.kill "QUIT", File.read(old_pid).to_i
      rescue Errno::ENOENT, Errno::ESRCH
      end
    end
  end
  # プロセス起動後処理
  after_fork do |server, worker|
    defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
  end
-----------------------------

2. 「esc」を押して入力モードを終了する
3. 「:wq」を入力後、エンターを押して編集を完了する

ここまでで「applicationサーバ設定」は完了です。

db設定

次にDBアクセスの設定をしていきます。

  • dotenv-rails (環境変数を管理するGem)の導入
EC2(クローンしたアプリのディレクトリ内で実施)
#Gemfileを編集する
$ vi Gemfile

1. 「i」を入力し、入力モードに切り替え、以下を追記する
-----------------------------
gem 'dotenv-rails'
----------------------------
2. 「esc」を押して入力モードを終了する
3. 「:wq」を入力後、エンターを押して編集を完了する
#dotenv-railsをインストールする
$ bundle install
#以下コマンドを実行し、表示されるシークレットキーをコピーする
$ bundle exec rake secret
#.envファイルの作成
$ touch .env
#.envファイルの編集
$ vi .env

1. 「i」を入力し、入力モードに切り替え、以下を追記する
-----------------------------
SECRET_KEY_BASE=先ほどコピーしたシークレットキー
DB_NAME=RDSのDB名
DB_USERNAME=RDSのユーザー名
DB_PASSWORD=RDSのパスワード
DB_HOSTNAME=RDSのエンドポイント
----------------------------
2. 「esc」を押して入力モードを終了する
3. 「:wq」を入力後、エンターを押して編集を完了する
#設定ファイルを反映させる
$ source .env
#設定した値が表示されることを確認する
$ echo $SECRET_KEY_BASE
$ echo $DB_NAME
$ echo $DB_USERNAME
$ echo $DB_PASSWORD
$ echo $DB_HOSTNAME
  • database.ymlの編集
EC2(クローンしたアプリのディレクトリ内で実施)
#.database.ymlファイルの編集
$ vi config/database.yml

1. 「i」を入力し、入力モードに切り替え、以下の編集をする
-----------------------------
production:
  <<: *default
  database: <%= ENV['DB_NAME'] %>
  username: <%= ENV['DB_USERNAME'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  host: <%= ENV['DB_HOSTNAME'] %>
----------------------------
2. 「esc」を押して入力モードを終了する
3. 「:wq」を入力後、エンターを押して編集を完了する
#MySQLを起動する
$ sudo systemctl start mysqld
#マイグレーションを実行する
$ bundle exec rake db:migrate RAILS_ENV=production

ここまでで「db設定」は完了です。

アプリ起動

以上で、各種設定が完了しましたので、最後にアプリを起動していきます。

  • 各種起動
EC2
#アプリのプリコンパイルをする
$ bundle exec rake assets:precompile RAILS_ENV=production
#プリコンパイルが正常に終了せず、「yarn」のエラーが発生した場合は以下を実施後にリトライする
$ npm install -g yarn
$ yarn upgrade
#Nginxを再起動する
$ sudo systemctl restart nginx
#Unicornを起動する
$ bundle exec unicorn_rails -c /var/www/rails/アプリ名/config/unicorn.conf.rb -D -E production
#Unicornの起動を確認する。以下コマンド実行後、プロセスが3行程度表示されること
$ ps -ef | grep unicorn | grep -v grep
  • 稼働確認

ブラウザより独自ドメインにてアクセスをし、無事に画面が表示されることを確認する
スクリーンショット 2021-06-12 11.44.36.png

まとめ

以上で、RailsのアプリをAWS EC2上にデプロイすることができました。アプリのデプロイにはAWS CodeDeployやECSなど、他のサービスも使用できるため、今後はそちらについても学習してみたいと思います。

参考

この記事は以下の情報を参考にして執筆しました。

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
What you can do with signing up
4
Help us understand the problem. What are the problem?