Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
135
Help us understand the problem. What is going on with this article?
@take18k_tech

サルでもできる!? Rails6 のアプリをAWS EC2にデプロイするまでの全手順【前半】(VPC, RDS, EC2, Capistrano)

【ご案内(2021/5/17)】 Puma のバージョン 5 (Systemd での起動)に対応しました!

この記事では,画像投稿機能の付いた Rails 6 のアプリを AWS EC2 にデプロイするまでの全過程を解説します。

Railsアプリのデプロイに関する記事はたくさん見かけますが,初学者にとっては

「具体的に何をすればよいかが分からない:sweat:

記事がほとんどで,ましてや「独自ドメインの設定方法」や「投稿画像を独自ドメインでCloudFrontから配信する方法」まで網羅的に解説を行っている記事は見当たらない状態です。

そこで,「Rails初学者が初めてAWSにデプロイする際に本当に参考となる記事」を目指して書かせていただきました。

Heroku にデプロイしたことはあるけれど,AWS にデプロイしたことがない」という方を対象としますので,AWS の操作は,直感的に操作できる AWS マネジメントコンソール で行います。

AWS CLITerraform などのツールは使用しませんので,あらかじめご了承下さい。

タイトル
【前半】 <-- こちら
1章 はじめに
2章 VPC
3章 RDS
4章 EC2
5章 サーバー構築
6章 デプロイ(Capistrano)
【後半】
7章 独自ドメイン
8章 HTTPS化(ACM, ALB)
9章 デプロイ関連事項
10章 S3
11章 CloudFront
12章 削除方法

1. はじめに

1.1 注意事項

この記事における注意事項を列記します。

料金

AWS は有料のサービスで,いわゆる従量課金制です(サービスの使用量に応じて料金が決まります)。

この記事の構成で AWS を利用した場合,ポートフォリオのようにあまりアクセスが来ないアプリであっても,(無料利用枠を使用する前提で)月におよそ3000円前後かかります。

RDS, ALB などを使用せず, EC2 にデータベースシステムをインストールする構成にすればもっと安く済ませることができますが,ポートフォリオのアピール材料としては弱くなるでしょう。

なお,エラーが発生した際に原因を特定しやすくするため,AWS へのデプロイはアプリの 完成後ではなく開発初期の段階 から行うことをお勧めします。

ただ,料金の問題がありますので,アプリの開発初期は Heroku にデプロイし,仕上げの段階で AWS にデプロイするという手法もありでしょう。

Railsアプリの条件

AWSにデプロイ予定のアプリが,以下の条件を満たすことを前提とします。

  • アプリの Rails のバージョンが 6 であること

  • データベースは MySQL 5.7 もしくは PostgreSQL を使用

  • 画像投稿機能がある場合は CarrierWave を使用

6.1 に画像投稿機能の付いたサンプルアプリを作成する方法を紹介しておりますので,必要がございましたらご利用下さい。

動作確認時の環境

  • Ruby 2.7.3
  • Rails 6.1.3.2
  • Puma 5.3.1

構成図

以下のような一般的な構成を目指します。(料金の都合上,冗長化は行いません)

1_1.png

サーバー環境

  • 【Web サーバー】 Nginx
  • 【アプリケーションサーバー】 Puma

使用する AWS のサービス

  • VPC(Amazon Virtual Private Cloud)
  • RDS(Amazon Relational Database Service)
  • EC2(Amazon Elastic Compute Cloud)
  • Route 53
  • ACM(Certificate Manager)
  • ALB(Application Load Balancer)
  • S3(Amazon Simple Storage Service)
  • IAM(AWS Identity and Access Management)
  • CloudFront

基礎知識の解説

この記事は,「画像投稿機能の付いた Rails アプリを AWS EC2 にデプロイし,独自ドメインでアクセスできるようにする」ことを主目的としております。

最低限度知っておくべき内容は触れますが,インフラの基礎知識は解説しません。

AWS に必要な基礎知識を学べる本はたくさんありますし,Udemyにも丁寧な解説動画が存在します。デプロイの完了後でもよいですので,是非学習されることをお勧めします。

注意点

理解が不十分な状態で進められる場合は, 絶対にミスをしない ように気を付けて下さい。1つのミスで最初からやり直すことになり,数時間の作業が無駄になる可能性があります。

コメントについて

記事内の改善点・間違いなどございましたら,遠慮なくご指摘下さい。可能な限りで記事にも反映させていただきます。

Qiita上の質問には原則お答えする時間が取れませんので,あらかじめ了解いただいた上でご質問下さい。

メモ

作業中にパスワードなど各自設定が異なる部分が複数存在します。メモ帳に以下を貼り付け,決まり次第埋めていくようにされるとよいでしょう。

メモ
【アプリ名】



【RDS】

●マスターユーザー名



●マスターパスワード


●エンドポイント


【EC2】

●Elastic IP


●sshでサインインするときのコマンド

ssh アプリ名

●ユーザー名



●パスワード

【ドメイン】

●ドメイン名


●ネームサーバー情報

【S3】

●バケット名


●リージョン


【IAM】

●ユーザー名


●アクセスキーID


●シークレットアクセスキー


【CloudFront】

static.ドメイン名

まずは,AWSで使用する アプリ名 を決め,上記にメモして下さい。ただし,「aws_sample_app」のように スネークケース 表記であることを前提とします。(アルファベット大文字は使わないで下さい)

「(AWSで使用する)アプリ名」は,「Railsのアプリ名」「GitHubのリポジトリ名」と合わせる方が混乱しづらいと思いますが,同じでなくても問題ありません。

以下, アプリ名 と記載している箇所は,全てこのメモ通りにして下さい。

1.2 AWSアカウントの作成・初期設定

要点のみ記載します。

  • AWSアカウントの作成

    • https://portal.aws.amazon.com/billing/signup
    • メールアドレス・パスワードは超重要です。絶対に忘れないようにし,また他人に知られないように注意しましょう。不正利用されると高額の料金を請求される可能性があります。
    • パスワードは,大文字・小文字・数字・記号を含む16文字以上の強固なものを設定しましょう。
    • サポートプランは特に用事がなければ「ベーシックプラン」でOK
  • 「セキュリティステータス」に全てチェックが入るように設定を進めましょう。

【お勧め参考記事】 https://qiita.com/tmknom/items/303db2d1d928db720888

  • ルートアカウントの MFA を有効化
    • セキュリティ向上のため2段階認証を導入
  • 個々の IAM ユーザーの作成
    • 最初に発行される「ルートアカウント」は,セキュリティの都合上,今後サインインに使用しないようにします
    • 普段のサインインに使用する IAM ユーザーを作成
    • 「パスワードのリセットが必要」は不要なのでチェックを外しましょう
    • 今後のサインインに必要となる「アカウントID」「ユーザー名」「パスワード」を忘れないようにしましょう
  • グループを使用してアクセス許可を割り当て
    • ほぼ全ての権限を持つ「AdministratorAccess」のポリシーを持つグループを作成し,作成した IAM ユーザーを追加
  • IAMパスワードポリシーの適用

最後に「請求アラーム」を作成し,課金状況を確認できるようにしておくことをお勧めします。

【お勧め参考記事】 https://www.kakiyoro.com/archives/2198

2. VPC

Amazon VPC とは Amazon Virtual Private Cloud の略称で,ユーザー専用のプライベートなネットワーク空間を構築できるサービスです。

RailsアプリをAWSで動作させるために,Webサーバーを配置する EC2 とデータベースシステムを動かす RDS を使用しますが,これらを配置するには先に VPC を設定する必要があります。

Amazon VPC は追加料金なしで使用できます。(参考:https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/what-is-amazon-vpc.html

2.1 VPC の作成

2章では以下の部分を作成していきます。

2_0.png

【注意】 メニューバー右側の真ん中に「米国」などと表示されている場合は,「東京(アジアパシフィック(東京) ap-northeast-1)」に変更して下さい

2_1a.png

  • 画面左上の「サービス」を開き、検索欄に「VPC」と入力し、「VPC」を選択

2_1b.png

【注意】 以下,左上の「New VPC Experience」をONにしていることを前提とします。

  • 画面左のメニューバー(もしくは,ダッシュボード内の)の「VPC」をクリック

2_1c.png

  • 「VPCを作成」ボタンをクリック
キー
名前タグ アプリ名_vpc
IPv4 CIDR ブロック 10.0.0.0/16

【注意】1章で注意しましたとおり,「アプリ名」の箇所はあらかじめ メモ しておいた「アプリ名」を使用して下さい

  • 他はデフォルトのままで「VPCを作成」ボタンをクリック

2_1d.png

2.2 サブネット の作成

VPCの中に,「インターネットから直接通信できる EC2用 のサブネット」と「インターネットから直接通信できない RDS用 のサブネット」を2つずつ作成していきましょう。(許可する接続方法は後に設定します)

  • 画面左のメニューバーから「サブネット」を選択

EC2 用のサブネット

HTTPS化 する際に ALB を使用するため,異なる アベイラビリティーゾーン に属するサブネットを 2つ 用意する必要があります。

  • 「サブネットの作成」ボタンをクリック
キー
VPC アプリ名_vpc ※リストから選択

2_2a.png

キー
名前タグ アプリ名_public_1a_subnet
アベイラビリティーゾーン ap-northeast-1a ※リストから選択
IPv4 CIDR ブロック 10.0.0.0/24

2_2b.png

  • 「新しいサブネットを追加」ボタンをクリック
キー
名前タグ アプリ名_public_1c_subnet
アベイラビリティーゾーン ap-northeast-1c ※リストから選択
IPv4 CIDR ブロック 10.0.1.0/24

※ まだ作成しますので,「サブネットを作成」ボタンをクリックしないこと!

RDS 用のサブネット

RDS を利用するには異なる アベイラビリティーゾーン に属するサブネットを 2つ 用意する必要があります。

  • 「新しいサブネットを追加」ボタンをクリック
キー
名前タグ アプリ名_private_1a_subnet
アベイラビリティーゾーン ap-northeast-1a
IPv4 CIDR ブロック 10.0.10.0/24
  • 「新しいサブネットを追加」ボタンをクリック
キー
名前タグ アプリ名_private_1c_subnet
アベイラビリティーゾーン ap-northeast-1c
IPv4 CIDR ブロック 10.0.11.0/24
  • 「サブネットを作成」ボタンをクリック

  • 下図の状態になっていることを確認しておきましょう

2_2c.png

2.3 インターネットゲートウェイ の作成

VPC 内から インターネット に接続するための「出入口」に相当する インターネットゲートウェイ を作成しましょう。

  • 画面左のメニューバーから「インターネットゲートウェイ」を選択
  • 「インターネットゲートウェイの作成」ボタンをクリック
キー
名前タグ アプリ名_gateway

2_3a.png

  • 他はデフォルトのままで「インターネットゲートウェイの作成」ボタンをクリック
  • フラッシュで表示されている「VPCへアタッチ」をクリック
    • (「アクション」を選択し、「VPCにアタッチ」を選択してもOK)
キー
使用可能なVPC アプリ名_vpc
  • 「インターネットゲートウェイのアタッチ」ボタンをクリック

2_3b.png

2.4 ルートテーブル の作成

インターネットゲートウェイ をアタッチしただけでは,サブネットからインターネットにアクセスすることはできません。
インターネットゲートウェイ へ転送する経路である ルートテーブル を設定する必要があります。

  • 画面左のメニューバーから「ルートテーブル」を選択
  • 「ルートテーブルの作成」ボタンをクリック
キー
名前タグ アプリ名_table
VPC アプリ名_vpc

2_4a.png

  • 「作成」ボタンをクリック
  • 「閉じる」ボタンをクリック

  • 作成したルートテーブルを選択し,「アクション」ボタンをクリックし,「ルートの編集」を選択

2_4b.png

  • 「ルートの追加」ボタンをクリック
    • local を消さないこと!
キー
送信先 0.0.0.0/0
ターゲット 「Internet Gateway」を選択し,先ほど作成した「アプリ名_gateway」を選択

2_4c.png

2_4d.png

  • 「ルートの保存」をクリック
  • 「閉じる」ボタンをクリック

  • (作成したルートテーブルを選択したまま)「アクション」ボタンをクリックし,「サブネットの関連付けの編集」を選択

  • 「アプリ名_public_1a_subnet」「アプリ名_public_1c_subnet」のみを選択し,「保存」ボタンをクリック

2_4e.png

2.5 セキュリティグループ の作成

インスタンスごとに許可する通信を設定するため, セキュリティグループ を作成しておきましょう。

EC2RDS に適用する作業は,後で行います)

EC2 用のセキュリティグループ

【構成内容】 クライアント --(HTTP or SSH)--> EC2

  • 画面左のメニューバーの「セキュリティグループ」を選択

2_5a.png

  • 「セキュリティグループを作成」ボタンをクリック
キー
セキュリティグループ名 アプリ名_ec2_security_group
説明 アプリ名_ec2_security_group
VPC アプリ名_vpc

「インバウンドルール」の「ルールを追加」を2回クリック

キー
タイプ HTTP ※「HTTPS」ではありません!
プロトコル TCP ※自動選択
ポート範囲 80 ※自動選択
ソース 任意の場所 (0.0.0.0/0 と ::/0 が表示)
説明 ※空白でOK
キー
タイプ SSH
プロトコル TCP ※自動選択
ポート範囲 22 ※自動選択
ソース マイIP (自分のグローバルIPが表示)
説明 ※空白でOK

2_5b.png

【注意】ソースを マイIP とすることで,SSH接続できるIPアドレスを制限できます。ただし,自宅以外で EC2 にアクセスする可能性がある場合は,他のIPアドレスも登録が必要です。(意味が分からない場合は, SSH のソースも 任意の場所 に設定して下さい)

RDS 用のセキュリティグループ

【構成内容】 EC2 --(TCP)--> RDS

データベースは EC2 からのリクエストのみを受け付けるように設定しておきます。

画面左のメニューバーの「セキュリティグループ」を選択し,「セキュリティグループを作成」ボタンをクリック

キー
セキュリティグループ名 アプリ名_db_security_group
説明 アプリ名_db_security_group
VPC アプリ名_vpc

「インバウンドルール」の「ルールを追加」をクリック

【注意】アプリで使用するデータベースシステムを確認し,「いずれか一方」のルールを追加して下さい

  • MySQL の場合
キー
タイプ MySQL/Aurora
プロトコル TCP ※自動選択
ポート範囲 3306 ※自動選択
ソース カスタム : アプリ名_ec2_security_group
説明 ※空白でOK

2_5c.png

「セキュリティグループを作成」をクリック

  • PostgreSQL の場合
キー
タイプ PostgreSQL
プロトコル TCP ※自動選択
ポート範囲 5432 ※自動選択
ソース カスタム : アプリ名_ec2_security_group
説明 ※空白でOK

2_5d.png

「セキュリティグループを作成」をクリック

3. RDS

Amazon RDS とは Amazon Relational Database Service の略称で,MySQLPostgreSQL のようなデータベース管理システム(DBMS)を最適な動作条件で利用できるサービスです。

RDS は運用負荷が低く非常に便利なのですが,コストが高い ため注意が必要です。

AWSアカウント作成後,1年間は一定の条件で無料となりますが,不要になった時点で削除することをお勧めします。

3.1. サブネットグループの作成

2.2 で作成した RDS 用のサブネット2つをグループ化しましょう。

  • 画面左上の「サービス」を開き、検索欄に「RDS」と入力し、「RDS」を選択

  • 画面左のメニューバーの「サブネットグループ」を選択し,右上の「DB サブネットグループを作成」ボタンをクリック

  • サブネットグループの詳細

キー
名前 アプリ名_subnet_group_db
説明 アプリ名_subnet_group_db
VPC アプリ名_vpc
  • サブネットの追加
    • 異なる アベイラビリティーゾーン に属するサブネットを2つ以上選択する必要があります
    • マルチ AZ 構成時に必要となるため,今回のように マルチ AZ を使用しない場合にも必須となります
キー
アベイラビリティーゾーン ap-northeast-1a, ap-northeast-1c
サブネット 10.0.10.0/24, 10.0.11.0/24 の2つを選択

3_1.png

「作成」ボタンをチェック

3.2 パラメータグループの作成(MySQL限定)

【注意】PostgreSQL の場合はスキップして下さい

RDSMySQL のデフォルト文字コードは latin1 であり,日本語に対応していません。

文字コードを変更するためのパラメータグループを先に作成しておきましょう。

(1度作成すれば使い回しが可能です)

  • 画面左のメニューバーの「パラメータグループ」を選択

「パラメータグループの作成」ボタンをクリック

  • パラメータグループの詳細
キー
パラメータグループファミリー mysql5.7
グループ名 mysql57-supported-in-ja
説明 parameter group for mysql5.7 supported in ja
  • 作成した「mysql57-supported-in-ja」をクリック

  • 「パラメータの編集」ボタンをクリック

  • 検索窓にキーをコピペして値を変更

キー
character_set_client utf8
character_set_connection utf8
character_set_database utf8mb4
character_set_results utf8
character_set_server utf8mb4
skip-character-set-client-handshake 1
  • 「変更の保存」ボタンをクリック

3.3 DBインスタンスの作成

画面左のメニューバーの「データベース」を選択

「データベースを作成」ボタンをクリック

「MySQL」の場合と「PostgreSQL」の場合で設定が異なりますので,いずれか片方を実行して下さい。

3.3.1 MySQLの場合

  • データベース作成方法を選択

「標準作成」を選択

  • エンジンのオプション
キー
エンジンのタイプ MySQL
バージョン MySQL 5.7.* (*の箇所は最新のものを推奨)
  • テンプレート

「無料利用枠」を選択

3_3ma.png

  • 設定

【注意】ここの「アプリ名」の _ は ハイフン - とすること
【注意】マスターユーザー名・パスワードをメモしておくこと

キー
DB インスタンス識別子 アプリ名-db
マスターユーザー名 root
マスターパスワード 任意
  • DB インスタンスサイズ

db.t2.micro(デフォルト)

3_3mb.png

  • ストレージ

※デフォルト設定で

  • 可用性と耐久性

※デフォルト設定で

3_3mc.png

  • 接続

「アプリ名_vpc」を選択

  • 「追加の接続設定」のドロップダウンをクリック
キー
サブネットグループ アプリ名_subnet_group_db ※2.1で作成
セキュリティグループ アプリ名_db_security_group ※1.5で作成, default は外す
アベイラビリティーゾーン ap-northeast-1a

3_3md.png

  • データベース認証

※デフォルト設定で

  • 「追加設定」をクリック

  • データベースの選択肢

キー
最初のデータベース名 アプリ名_production
DB パラメータグループ mysql57-supported-in-ja
オプショングループ ※デフォルト設定
  • バッグアップ以降

※デフォルト設定で

3_3me.png

3_3f.png

  • 「データベースの作成」ボタンをクリック

3.3.2 PostgreSQLの場合

まず,ターミナルでローカルで使用している PostgreSQL のバージョンを確認しておきましょう。

psql -V
  • データベース作成方法を選択

「標準作成」を選択

  • エンジンのオプション

PostgreSQL のバージョンは,上記で確認したローカルのバージョンに合わせた方が無難です。

メジャーバージョンを合わせれば十分なので,例えばローカルが 12.3 ならば,12.* (*の箇所は最新のもの) をお勧めします。

(2021年5月時点ではバージョン 13 は無料利用枠の対象外となっております。ローカルのバージョンが 13 の場合でも,無料利用枠のために 12 を選択されてもよいでしょう)

キー
エンジンのタイプ PostgreSQL
バージョン ※上記を参考に設定
  • テンプレート

「無料利用枠」を選択

3_3pa.png

  • 設定

【注意】ここの「アプリ名」の _ は ハイフン - とすること
【注意】マスターユーザー名・パスワードをメモしておくこと

キー
DB インスタンス識別子 アプリ名-db
マスターユーザー名 postgres
マスターパスワード 任意
  • DB インスタンスサイズ

db.t2.micro(デフォルト)

3_3pb.png

  • ストレージ

※デフォルト設定で

  • 可用性と耐久性

※デフォルト設定で

3_3pc.png

  • 接続

「アプリ名_vpc」を選択

  • 「追加の接続設定」のドロップダウンをクリック
キー
サブネットグループ アプリ名_subnet_group_db ※2.1で作成
セキュリティグループ アプリ名_db_security_group ※1.5で作成, default は外す
アベイラビリティーゾーン ap-northeast-1a

3_3pd.png

  • データベース認証

※デフォルト設定で

  • 「追加設定」をクリック

  • データベースの選択肢

キー
最初のデータベース名 アプリ名_production
DB パラメータグループ ※デフォルト設定
オプショングループ ※デフォルト設定
  • バッグアップ以降

※デフォルト設定で

3_3pe.png

3_3pf.png

  • 「データベースの作成」ボタンをクリック

3.4 エンドポイントの確認

  • アプリ名を選択

  • 「接続とセキュリティ」の「エンドポイント」をメモ

    • データベースが作成されるまで待つ必要がありますので,別タブで次の EC2 の設定に進めるとよいでしょう

3_4.png

4. EC2

Amazon EC2 とは Amazon Elastic Compute Cloud の略称で,コンピューティング性能をクラウド内で提供するサービスです。サーバーに必要なものをクラウド内で借りることができます。

Railsのアプリをこの EC2 にデプロイし,ブラウザからアクセスできるように準備を行います。

EC2 も運用に料金がかかりますので,不要になったインスタンスなどは削除するようにしましょう。

4.1 インスタンスの作成

  • 画面左上の「サービス」を開き、検索欄に「EC2」と入力し、「EC2」を選択

  • 画面左のメニューバーの「インスタンス」を選択し,「インスタンスを起動」ボタンをクリック

ステップ 1: Amazon マシンイメージ (AMI)

「無料利用枠の対象」タグの付いた「Amazon Linux 2 AMI (HVM), SSD Volume Type」「64ビット (x86)」の「選択」ボタンをクリック

4_1a.png

ステップ 2: インスタンスタイプの選択

  • 「無料利用枠の対象」タグの付いた「t2.micro」が選択されていることを確認した上で,「次のステップ」ボタンをクリック
    • 「確認と作成」ボタンをクリックしないこと。クリックした場合は,「戻る」ボタンをクリックしてステップ3まで移動しましょう

4_1b.png

ステップ 3: インスタンスの詳細の設定

キー
ネットワーク アプリ名_vpc
サブネット アプリ名_public_1a_subnet

他はデフォルト設定のまま「次のステップ」ボタンをクリック

4_1c.png

ステップ 4: ストレージの追加

「次のステップ」ボタンをクリック

ステップ 5: タグの追加

「タグの追加」ボタンをクリック

キー
Name 「アプリ名_instance」を選択

4_1d.png

「次のステップ」ボタンをクリック

ステップ 6: セキュリティグループの設定

「既存のセキュリティグループを選択する」にチェック

「アプリ名_ec2_security_group」にチェック

4_1e.png

「確認と作成」ボタンをクリック

ステップ 7: インスタンス作成の確認

  • セキュリティグループの「名前」が「アプリ名_ec2_security_group」になっていることを確認した上で,「起動」ボタンをクリック

既存のキーペアを選択するか、新しいキーペアを作成します。

  • 「新しいキーペアの作成」を選択

  • 「キーペア名」は「アプリ名」を入力

    • メモ しているアプリ名と全く同じにして下さい(ハイフン - を使用せず,アンダースコア _ を使用)
  • 「キーペアのダウンロード」を選択

    • アプリ名.pem をダウンロードできます。後に EC2 のログインで利用します

4_1f.png

「インスタンスの作成」ボタンをクリック

作成ステータス

「インスタンスの表示」ボタンをクリック

4.2 Elastic IPの作成、紐付け

インターネットに接続するには グローバルIPアドレス が必須です。

現状ではこの グローバルIPアドレス は固定化されておらず EC2インスタンス を再起動した際に変更されてしまいます。(URLが変化してしまう!)

Elastic IP 設定することで,グローバルIPアドレス を固定化することができます。

Elastic IP はこれから行う EC2インスタンス との関連付けを行っている状態では無料ですが,関連付けた EC2インスタンス を削除したり停止させると料金が発生するようになります。

EC2インスタンス を削除する際は Elastic IP の開放を忘れないように注意しましょう。

Elastic IPの作成

  • 画面左のメニューバーの「Elastic IP」を選択

  • 「Elastic IP アドレスの割り当て」ボタンをクリック

  • 「割り当て」ボタンをクリック

Elastic IPの紐付け

  • 先ほど割り当てた Elastic IP を選択した状態で、「アクション」ドロップダウンを選択し、「Elastic IP アドレスの関連付け」をクリック

4_2a.png

ここで,表示されている Elastic IP は必ずメモしておいて下さい。

キー
インスタンス アプリ名_instance
プライベート IP アドレス ※クリックして表示されるIPを選択
再関連付け チェックを入れる

4_2b.png

  • 「関連付ける」ボタンをクリック

4.3 EC2へのログイン

アプリ名を定義(ローカル環境)

作業ミスを減らすため,ターミナルで頻出する アプリ名 を一時的にグローバル変数として定義しておきましょう。

アプリ名 の箇所は,各自がメモしているものに置き換えて実行して下さい。

ターミナル
APP_NAME=アプリ名
echo $APP_NAME
(例)
APP_NAME=aws_sample_app
echo $APP_NAME

最後のコマンドで,「アプリ名」が正しく表示されていることを確認した上で,以下を実行して下さい。

【補足】間違った場合は再度上記を実行し直してから進めて下さい。また,コマンドは原則コピペして下さい。1文字間違っただけで大きく時間をロスする可能性があります。

ターミナル
# zsh の場合
echo "export APP_NAME=$APP_NAME" >> ~/.zshrc
source ~/.zshrc

# bash の場合
echo "export APP_NAME=$APP_NAME" >> ~/.bash_profile
source ~/.bash_profile

【備考】 使用しているシェルスクリプトが zshbash か分からない場合は echo $SHELL を実行して確認して下さい

4_3a.png

キーペアの移動・アクセス権の付与

【参考】 https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-key-pairs.html

4.1 でダウンロードしたキーペア アプリ名.pem.ssh ディレクトリに移動し,利用できる状態にしておきましょう。

ターミナル
cd
mkdir .ssh
mv Downloads/$APP_NAME.pem .ssh
chmod 400 .ssh/$APP_NAME.pem
ls -l .ssh/$APP_NAME.pem

最後のコマンドで -r-------- (略) .ssh/アプリ名.pem が表示されていればOKです。

【補足】mv コマンド実行時に No such file or directory が表示された場合は,Google Chrome の下に現れている アプリ名.pem のドロップダウンメニューから,キーペアの場所を確認して,直接,ホームディレクトリの .ssh ディレクトリに移動させて下さい。キーペアのファイル名が アプリ名.pem になっているかどうかも確認しましょう。

EC2 インスタンスの状態を確認

  • EC2 の画面左のメニューバーの「インスタンス」をクリックし,作成した EC2インスタンスの「インスタンスの状態」が 実行中 となっているか確認して下さい
    • 実行中 になっていない場合はしばらく待ってからブラウザをリロードして下さい

【補足】4.2で Elastic IP をメモし忘れた人は,作成した EC2インスタンス を選択し, Elastic IP をメモして下さい

4_3b.png

ssh接続の設定ファイルを作成

EC2インタスタンス にログインするには,「ホスト名」「ユーザー名」「AWSからダウンロードしたキーペア(秘密鍵)」が必要になります。

これらをログインの度に毎回記述するのは面倒なので,設定ファイルに記載し,使える状態にしましょう。

ローカル環境のターミナル
vi ~/.ssh/config

Vim エディタでファイルが開かれますので,以下を記述して下さい。(デフォルトで ec2-user という名前のユーザーが用意されています)

ローカル環境のターミナル(~/.ssh/config)
Host アプリ名
  Hostname ElasticIPを記入
  User ec2-user
  IdentityFile ~/.ssh/アプリ名.pem

【参考】 「アプリ名」が aws_sample_app, 「Elastic IP」が 172.217.161.46 の場合は,次の形式となります。

(例)
Host aws_sample_app
  Hostname 172.217.161.46
  User ec2-user
  IdentityFile ~/.ssh/aws_sample_app.pem

【補足】 Vimの基本

一般のテキストエディタは,ファイルを開いてすぐに文字が入力できます。 Vimインサートモード に変更しなければキー入力ができません。

ここは初学者が非常に混乱しやすいところですので,くれぐれもご注意下さい。

以下は最低限覚えておきましょう。

  • Vim の起動時は「ノーマルモード」
  • 文字をキー入力したいときは i を入力し,「インサートモード」に変更する必要がある
    • 「かな」入力モードでは i を入力しても効果が出ないので,「英数」入力モードに切り替えてから行うこと
  • 「ノーマルモード」への移行は,esc
  • 保存終了は「ノーマルモード」にしてから :wq
  • (保存せずに)強制終了は「ノーマルモード」にしてから :q!

EC2にログイン

それでは, EC2インタスタンス にログインしてみましょう。

ターミナル
ssh アプリ名

Are you sure you want to continue connecting (yes/no/[fingerprint]) と表示されたら,yes と入力してEnterキーを押しましょう。

これで, EC2インタスタンス にログインできます。


【備考】ここでSSH接続できない場合は,以下の可能性があります。

  • 先ほど作成した ~/.ssh/config にミスがある

  • 4.3で,キーペアが指定箇所に移動できていない or パーミッションを適切に変更できていない(ls -l ~/.ssh/$APP_NAME.pem で確認)

  • Elastic IP をメモし間違えている

  • 2.5で作成した「EC2 用のセキュリティグループ(アプリ名_ec2_security_group)」の設定を間違えている

    • SSHのソースが マイIP の場合は,IPアドレスが変わっていないかも確認しましょう(不明な場合は 任意の場所 に変更)
  • 4.1で設定したEC2 用のセキュリティグループが「アプリ名_ec2_security_group」になっていない

  • 2.4で作成したルートテーブルの「サブネットの関連付け」を間違えている


4.4 EC2の初期設定

(参考)Amazon Linux インスタンスでユーザーアカウントを管理する


要注意

今後,EC2にログインした状態の サーバー環境のターミナル と,通常の ローカル環境のターミナル のどちらで操作するかを「必ず」確認して下さい。1度でも間違えると,エラー解決に大きく時間を取られる可能性があります。

なお,一定時間が経過しますと,EC2からログアウトしますので,その点にも注意しましょう。


新規ユーザーアカウントの作成

今後 EC2 での作業や Capistrano で利用するユーザーを作成しましょう。作業を楽にするため,しばらくパスワード無しで sudo コマンドを使える状態にしておきます。

EC2にログインした状態の サーバー環境のターミナル で以下を実行しましょう。

「ユーザー名」の箇所は自由に決め, メモ しておいて下さい。

サーバー環境のターミナル
APP_USER=ユーザー名
echo $APP_USER

最後のコマンドで,「ユーザー名」が正しく表示されていることを確認した上で,以下を実行して下さい。

サーバー環境のターミナル
sudo adduser $APP_USER
echo "$APP_USER ALL=(ALL) NOPASSWD: ALL" | sudo EDITOR='tee -a' visudo > /dev/null
sudo su - $APP_USER
sudo ls

最初の表示が ec2-user から「自分の決めたユーザー名」に変更され,最後のコマンドでパスワードを求められなければOKです。

【補足】2番目の操作は sudo visudo 実行後,一番最後の行に ユーザー名 ALL=(ALL) NOPASSWD: ALL を追加する操作です

アプリ名を定義(サーバー環境)

作業ミスを減らすため,サーバー環境でも「アプリ名」をグローバル変数として定義しておきましょう。

サーバー環境のターミナル
APP_NAME=アプリ名
echo $APP_NAME

最後のコマンドで,「アプリ名」が正しく表示されていることを確認した上で,以下を実行して下さい。

(間違っている場合は再度上記を実行し直してから進めて下さい)

サーバー環境のターミナル
echo "export APP_NAME=$APP_NAME" >> ~/.bash_profile
source ~/.bash_profile

新規ユーザーでssh接続するための設定

新規ユーザーでssh接続できるようにするには,アプリ名.pem (秘密鍵)に対応する 公開鍵EC2~/.ssh/authorized_keys に配置し,適切な権限を与えておく必要があります。

サーバー環境のターミナル
mkdir .ssh -m 700
vi .ssh/authorized_keys

サーバー側でVimエディタが開かれます。

ここで,新しく ローカル 環境のターミナルを用意して下さい。( command + n もしくは command + t

そして, ローカル 環境のターミナルで 秘密鍵(アプリ名.pem) から 公開鍵 をコピーして下さい。

ローカル環境のターミナル
ssh-keygen -y -f ~/.ssh/$APP_NAME.pem | pbcopy

(コマンドを実行するだけでコピーされますので,command + c は不要です。もし pbcopy: command not found が表示される場合は | pbcopy を削って実行し,直接コピーして下さい)

その後,サーバー環境のターミナルに戻って以下の操作を行ってください。

サーバー環境のターミナル
# 公開鍵(ssh-rsa *****)を貼り付け,保存終了
chmod 600 .ssh/authorized_keys
exit
exit

これで,新しく作成したユーザーでもログインができるようになりました。

ログイン時のユーザー名を変更しましょう。

ローカル環境のターミナル
vi ~/.ssh/config
  • 「ユーザー名」を ec2-user から メモしたユーザー名 に変更しましょう。
ローカル環境のターミナル(~/.ssh/config)
Host アプリ名
  Hostname ElasticIP
  User ユーザー名 ★ここを変更★
  IdentityFile ~/.ssh/アプリ名.pem

yml:(ユーザー名が take の場合)
Host aws_sample_app
Hostname 172.217.161.46
User take
IdentityFile ~/.ssh/aws_sample_app.pem

4.5 今後のEC2のログイン方法

再度,以下のコマンドで EC2インスタンス にログインしてみましょう。

ローカル環境のターミナル
ssh アプリ名

ec2-user ではなく各自が決めたユーザー名でログインできるはずです。

デフォルトユーザーは必要なくなりましたので,削除しておきましょう。

サーバー環境のターミナル
sudo userdel -r ec2-user

5. サーバー構築

Railsアプリを実行できるようにするための環境構築を行っていきます。

EC2インスタンス にログインしていない場合は,次でログインして下さい。

ローカル環境のターミナル
ssh アプリ名

5.1 Nginx の設定

以下の順序で実行していきます。

  • サーバーをアップデート
  • Nginx のインストール
  • Nginx の起動とインスタンス起動時自動起動の設定
サーバー環境のターミナル
sudo yum -y update
sudo amazon-linux-extras install -y nginx1
sudo systemctl start nginx
sudo systemctl enable nginx

ブラウザに Elastic IP を入力してアクセスしましょう。

Welcome to nginx on Amazon Linux! が表示されればOKです。

【補足】ここでアクセスできない場合は,以下の可能性があります

  • 2.5で作成した「EC2 用のセキュリティグループ(アプリ名_ec2_security_group)」の設定を間違えている
    • 「タイプが HTTP, ソースが 0.0.0.0/0::/0」のものが含まれているかを確認。「HTTP」を「HTTPS」にしているミスを見かけます
  • 4.1で設定したEC2 用のセキュリティグループが「アプリ名_ec2_security_group」になっていない

5.2 必要なプラグインのインストール

  • 各種プラグインのインストール
    • 1行のコマンドです
サーバー環境のターミナル
sudo yum -y install git make gcc-c++ patch openssl-devel libyaml-devel libffi-devel libicu-devel libxml2 libxslt libxml2-devel libxslt-devel zlib-devel readline-devel ImageMagick ImageMagick-devel

【注意】上記はあくまで「画像投稿可能なアプリ」のデプロイを想定したものです。アプリに導入されている gem や ライブラリ次第では,依存関係にある他のプラグインもインストールしておく必要があります。

5.3 データベースにログイン

まず,EC2 にプリインストールされている MariaDB を削除しておきましょう。

サーバー環境のターミナル
sudo yum -y remove mariadb-libs

MySQLの場合

以下の順序で実行していきます。

  • MySQL のリポジトリを追加
  • MySQL の5.7がインストールされるように変更
  • MySQL をインストール
サーバー環境のターミナル
sudo yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
sudo yum-config-manager --disable mysql80-community
sudo yum-config-manager --enable mysql57-community
sudo yum -y install mysql-community-client mysql-server mysql-devel

次のコマンドでRDSの MySQL にログインできます。

サーバー環境のターミナル
mysql -h エンドポイント -u root -p
# RDS の パスワード を入力

mysql> という表示が出た後に次を実行して下さい。

サーバー環境のターミナル(mysql)
show databases;
# 表示されたデータベース一覧に,「アプリ名_production」が存在していればOK
exit

【参考】「エンドポイント」は 2.4 で確認したものです。確認できていない場合は RDS の「データベース」をクリックし,アプリを選択して出てくる「エンドポイント」を確認しましょう。


【補足】もし,データベース一覧に,「アプリ名_production」が存在しない場合は,exit; で終了する前に以下を実行してデータベースを作成して下さい。

サーバー環境のターミナル(mysql)
# 「アプリ名_production」が存在しない場合のみ,次を実行して下さい
CREATE DATABASE アプリ名_production;

【参考】 Sequel Aceで MySQL に接続する方法

Sequel Ace をインストールしていない場合は,App Store からインストールしましょう。

  • SSHのタブを選択
キー
MySQL Host RDSのエンドポイントを記載
Username root
Password RDSのパスワードを記載
Database アプリ名_production
Port 3306
SSH Host Elastic IPを記載
SSH User EC2のユーザー名を記載
SSH Password 右側の鍵マークボタンをクリックし「~/.ssh/アプリ名.pem」を選択

【参考】 .ssh は隠しファイルです。隠しファイルを表示するショートカットキーは command + shift + . です。

5_3.png

PostgreSQLの場合

単純にインストールするとバージョンが低すぎるので,amazon-linux-extras リポジトリから PostgreSQL のバージョン11を入れることにしましょう。

サーバー環境のターミナル
sudo amazon-linux-extras install -y postgresql11
yum list | grep postgresql
sudo yum -y install postgresql-devel

【補足】PostgreSQLのバージョン12以上を強引に入れることも可能ですが,postgresql-devel のインストールが難しいのでお勧めしません。なお,インストール可能な最新バージョンは, amazon-linux-extras | grep postgresql で確認できます。


次のコマンドでRDSの PostgreSQL にログインできます。

サーバー環境のターミナル
psql -h エンドポイント -U postgres
# RDS の パスワード を入力

postgres=> という表示が出た後に次を実行して下さい。

サーバー環境のターミナル(PostgreSQL)
\l
# 表示されたデータベース一覧に,「アプリ名_production」が存在していればOK
exit;

【補足】もし,データベース一覧に,「アプリ名_production」が存在しない場合は,exit; で終了する前に以下を実行してデータベースを作成して下さい。

サーバー環境のターミナル(PostgreSQL)
# 「アプリ名_production」が存在しない場合のみ,次を実行
CREATE DATABASE アプリ名_production;

【参考】 Postico で PostgreSQL に接続する方法

https://eggerapps.at/postico

インストールしていない場合は,上記サイトの Download ボタンをクリックし,zipファイルを解凍して出てくる Postico をアプリケーションに移動した上で,実行して下さい。

  • Postico を起動し,左下の「New Favorite」をクリック

  • Options のドロップダウンを開き, Connect via SSH をクリック

キー
Nickname ※任意 (アプリ名_production など)
Host RDS のエンドポイントを記載
Port ※不要
User postgres
Password RDSのパスワードを記載
Database アプリ名_production
SSH Host Elastic IPを記載
User EC2のユーザー名を記載
Password ※不要
Private Key 「Choose」をクリックし,「~/.ssh/アプリ名.pem」を選択

「Connect」を選択し,再度「Connect」を選択

5_3b.png

5.4 Node, Yarn のインストール

サーバー環境のターミナル
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
. ~/.nvm/nvm.sh

# インストール可能なバージョンを確認
nvm ls-remote | grep v14

# バージョン14のいずれかをインストール
# (例) nvm install v14.16.1

node -e "console.log('Running Node.js ' + process.version)"

最後のコマンドで Running Node.js バージョン が表示されればOKです。

  • Yarn のインストール
サーバー環境のターミナル
curl -o- -L https://yarnpkg.com/install.sh | bash

5.5 Rubyのインストール

  • rbenv のインストール
サーバー環境のターミナル
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
  • ruby-build のインストール
サーバー環境のターミナル
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
  • Ruby のインストール

まず,デプロイするアプリの Ruby のバージョンを確認して下さい。

ローカル環境のターミナル でアプリのディレクトリまで移動し ruby -v で確認できます)

以下は,バージョンが 2.7.3 の場合の例です。バージョンはアプリに「必ず」合わせて下さい。

サーバー環境のターミナル
rbenv install 2.7.3
rbenv global 2.7.3
rbenv rehash

Ruby のインストールには時間がかかります。

  • Bundler のインストール
サーバー環境のターミナル
gem install bundler

完了後に以下を実行し,全てバージョンが表示されればOKです。

サーバー環境のターミナル
rbenv -v
ruby -v
yarn -v
bundler -v

5.6 デプロイ先ディレクトリの設定

(デフォルト設定の場合) Capistrano によるアプリのデプロイ先は /var/www/アプリ名 ディレクトリになります。

そこで,このディレクトリをあらかじめ作成しておき,必要な権限を与えておきましょう。

サーバー環境のターミナル
sudo mkdir -p /var/www/$APP_NAME
sudo chown `whoami`:`whoami` /var/www/$APP_NAME
ls -l /var/www

最後のコマンドで drwxr-xr-x 2 ユーザー名 ユーザー名 日付 アプリ名 が表示されればOKです。

5.7 Git の初期設定

次に,サーバー環境で GitHub の操作ができるようにしていきましょう。

まずは,サーバー環境の Git の初期設定を行いましょう。ここでは,ローカル環境と同じ「ユーザー名」「メールアドレス」を登録することとしておきます。

まず, Git に登録した名前とメールアドレスを確認しましょう。

ローカル環境のターミナル
cat ~/.gitconfig

次の箇所をコピーして下さい。

出力内容の一部
[user]
    name = ~~~~~
  email = ~~~~~@~~~.~~~
  • .gitconfig ファイルの生成
サーバー環境のターミナル
cd
vi .gitconfig
  • Vimが開いたら先ほどコピーしたものをペーストしましょう。

5.8 GitHub連携

サーバー環境に GitHub へのアクセス権限を持たせるため,必要な公開鍵・秘密鍵を生成しましょう。

サーバー環境のターミナル
cd .ssh
ssh-keygen -t rsa -f "${APP_NAME}_git_rsa" -N ""
  • これで,以下のファイルが作成されます

    • 公開鍵(GitHubに配置する鍵) アプリ名_git_rsa.pub
    • 秘密鍵(EC2に残しておく鍵) アプリ名_git_rsa
  • config ファイルの生成

サーバー環境のターミナル
vi config
  • Vimでファイルが開かれたら次を追加
    • 「アプリ名」の箇所は各自の設定に合わせること
~/.ssh/config
Host github github.com
  Hostname github.com
  User git
  IdentityFile ~/.ssh/アプリ名_git_rsa
  • GitHubに公開鍵を登録

以下を実行し,値をコピーしておきましょう。

サーバー環境のターミナル(~/.ssh)
cat "${APP_NAME}_git_rsa.pub"

5_8a.png

  1. ブラウザでGitHubにアクセス
  2. 右上のサムネイル画像をクリック
  3. 「Settings」をクリック
  4. 左メニューバーから「SSH and GPG keys」をクリック
  5. 「SSH Keys」の「New SSH key」をクリック

5_8b.png
5_8c.png

キー
Title アプリ名_git_rsa.pub
Key サーバー環境のターミナルからコピーした値をペースト

5_8d.png

「Add SSH key」ボタンをクリック

  • サーバーから GitHub に接続できるか確認
サーバー環境のターミナル(~/.ssh)
chmod 600 config
ssh github

yes を入力し,次の赤枠の内容が出力されればOKです。

5_8e.png

6. デプロイ(Capistrano)

Capistrano を使い,1コマンドで Rails アプリを AWS EC2 にデプロイできる状態にしていきましょう。

サンプルのアプリをデプロイされたい場合は 6.1 から進めて下さい。オリジナルのアプリをデプロイされる場合は 6.2 から進めて下さい。

なお,オリジナルアプリのデプロイについては,以下の条件を改めて確認しておいて下さい。

  • Rails 6 であること
  • アプリで使用するデータベースシステムの指定が RDS と一致していること
    • 他のデータベースを指定している場合は config/database.yml を修正して下さい。
    • rails db:system:change --to=mysql もしくは rails db:system:change --to=postgresql コマンドが便利です
  • アプリで使用する gem やライブラリ次第では EC2 に他にもあらかじめインストールしておく必要がある可能性があります

6.1 Railsのサンプルアプリを作成

【注】 「サンプルのアプリ」で AWS のデプロイに挑戦されたい方以外はスキップして下さい。

CarrierWave を用いた画像投稿機能を持つアプリを簡単に実装しましょう。

アプリの作成(MySQLの場合)

ターミナル
rails new aws_sample_app -d mysql -C -M -T --skip-active-storage

アプリの作成(PostgreSQLの場合)

ターミナル
rails new aws_sample_app -d postgresql -C -M -T --skip-active-storage

※ 以下は MySQL, PostgreSQL 共通です

ターミナル
cd aws_sample_app
git add .
git commit -m "init"
bundle remove jbuilder
bundle add carrierwave
rails g scaffold Post title:string image:string --skip-assets --skip-helper
rails db:migrate:reset
rails g uploader Image
echo "/public/uploads/" >> .gitignore
  • トップページを設定
config/routes.rb
Rails.application.routes.draw do
  # ********** 以下を追加 **********
  root to: 'posts#index'
  # ********** 以上を追加 **********
  resources :posts
end
  • 画像投稿機能を付けるための準備
app/models/post.rb
class Post < ApplicationRecord
  # ********** 以下を追加 **********
  mount_uploader :image, ImageUploader
  # ********** 以上を追加 **********
end
  • 投稿する画像の選択ボタンを作成
app/views/posts/_form.html.erb
<!-- 略 -->
  <div class="field">
    <%= form.label :image %>
  <!-- ********** 「<%= form.text_field :image %>」を変更 ********** -->
    <%= form.file_field :image, accept: "image/png,image/jpeg,image/gif" %>
  <!-- ********** 以上を変更 ********** -->
  </div>
<!-- 略 -->
  • 投稿詳細ページで,投稿した画像が表示されるように設定
app/views/posts/show.html.erb
<p id="notice"><%= notice %></p>

<p>
  <strong>Title:</strong>
  <%= @post.title %>
</p>

<!-- ********** 以下を編集 ********** -->
<% if @post.image? %>
  <p>
    <%= image_tag @post.image.url %>
  </p>
<% end %>
<!-- ********** 以上を編集 ********** -->

<%= link_to 'Edit', edit_post_path(@post) %> |
<%= link_to 'Back', posts_path %>

動作確認を行った上で,GitHubにリポジトリを作成し,add, commit を行い, GitHub に push しましょう。

さらに,画像を AWS S3 に保存できるようにすべきですが,ひとまず画像投稿は可能ですのでデプロイ完了後の10章・11章で設定を行うこととしましょう。

6.2. データベースの設定

※以下は自作アプリの場合の場合も実行して下さい。必要があれば作業前にブランチを切るようにしましょう。

ファイル名 ファイルのイメージ
config/master.key
config/credentials.yml.enc 錠付きファイル

まず,本番環境用の config/database.yml を修正しておきましょう。

RDS のパスワードとエンドポイントは GitHub から見られないようにするため, credentials.yml.enc に記載し,これを読み込むように設定することとします。

dotenv-rails を導入し .env にパスワードなどを記載する方法もあります)

MySQLの場合

config/database.yml
production:
  <<: *default
  # ***** 以下を修正 *****
  database: アプリ名_production
  username: root
  password: <%= Rails.application.credentials.db[:password] %>
  host: <%= Rails.application.credentials.db[:hostname] %>

PostgreSQLの場合

config/database.yml
production:
  <<: *default
  # ***** 以下を修正 *****
  database: アプリ名_production
  username: postgres
  password: <%= Rails.application.credentials.db[:password] %>
  host: <%= Rails.application.credentials.db[:hostname] %>

※ 以下は MySQL, PostgreSQL 共通です

  • database.yml で読み込むパスワードとエンドポイントを credentials.yml.enc に記載しましょう
    • yaml 形式ですので,インデント幅にはくれぐれも注意して下さい
    • 例えば,password:の後に「半角スペース1個」がないだけでエラーになります
ローカル環境のターミナル
EDITOR=vi rails credentials:edit
config/credentials.yml.enc
db:
  password: RDSのパスワード
  hostname: RDSのエンドポイント

さらに,本番環境で master.key が存在しない場合はエラーが出るように設定しておきます。

config/environments/production.rb
# 次のコメントアウトを解除
config.require_master_key = true

念のため以下を実行し,パスワードとエンドポイントが取得できることを確認しておいた方がよいでしょう。

ローカル環境のターミナル
rails c
# コンソール起動後
Rails.application.credentials.db[:password]
Rails.application.credentials.db[:hostname]
# RDSのパスワード, エンドポイントが表示されることを確認後
exit

確認ができれば,add, commit を行い, GitHub に push しましょう。

master(main) ブランチ以外で作業をされている場合は,プルリクを出し,GitHubの master(main) ブランチにマージするところまでは行ってください。

6.3. Capistrano

1コマンドで Rails アプリをデプロイできるよう Capistrano を導入しましょう。

Gemfile
group :development do
  # 略
  # ***** 以下を追加 *****
  gem "capistrano", "~> 3.10", require: false
  gem "capistrano-rails", "~> 1.6", require: false
  gem 'capistrano-rbenv', '~> 2.2'
  gem 'capistrano-rbenv-vars', '~> 0.1'
  gem 'capistrano3-puma'
  # ***** 以上を追加 *****
end
ローカル環境のターミナル
bundle install
bundle exec cap install STAGES=production

Capfile# require "capistrano/passenger" の下に以下を追加

Capfile
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/puma'
install_plugin Capistrano::Puma
install_plugin Capistrano::Puma::Systemd
install_plugin Capistrano::Puma::Nginx
  • デプロイの設定ファイルを修正・追記しましょう
    • 「アプリ名」「GitHubリポジトリURL」は各自のものに置き換えて下さい
    • 「GitHubリポジトリURL」は HTTPS でなく SSH のURLをコピペして下さい
config/deploy.rb
# config valid for current version and patch releases of Capistrano
lock "~> 3.14.1"

# ***** 以下を修正 *****
set :application, "アプリ名"
set :repo_url, "GitHubのリポジトリURL"
set :rbenv_ruby, File.read('.ruby-version').strip
set :branch, ENV['BRANCH'] || "master"

# Nginxの設定ファイル名と置き場所を修正
set :nginx_config_name, "#{fetch(:application)}.conf"
set :nginx_sites_enabled_path, "/etc/nginx/conf.d"

append :linked_files, "config/master.key"
append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "node_modules"
# ***** 以上を追加 *****
  • production.rb の一番上に,EC2サーバーにログインするユーザー名、サーバーのロールを記述
    • 「ElatsticIP」「アプリ名」「ユーザー名」は各自のものに置き換えること
config/deploy/production.rb
server "ElatsticIP", user: "ユーザー名", roles: %w{app db web}

set :ssh_options, {
  keys: %w(~/.ssh/アプリ名.pem),
  forward_agent: true,
  auth_methods: %w(publickey),
}

master.key の配置と Rails アプリのデプロイ

準備が整いましたので,Railsアプリのデプロイを行いましょう。

初回の実行では master.key がないためデプロイに失敗しますが, master.key を配置するために必要なディレクトリが生成されます。

デプロイ失敗後に scp コマンドで master.key をサーバー側に追加し,再度実行すればデプロイに成功するでしょう。

ローカル環境のターミナル
# Railsアプリのルートディレクトリに移動してから
bundle exec cap production deploy

# 「ERROR linked file /var/www/アプリ名/shared/config/master.key does not exist on ElasticIP」が出ればOK

scp config/master.key $APP_NAME:/var/www/$APP_NAME/shared/config
bundle exec cap production puma:config
bundle exec cap production puma:systemd:config puma:systemd:enable

【注意】 ブランチが master でない場合は, BRANCH=HEAD を付けた bundle exec cap production deploy BRANCH=HEAD を実行して下さい

最後のコマンドで, /etc/systemd/system/puma_アプリ名_production.service が作成されます。このファイルの $HOME を実際のパスに変更しないとエラーが出るため,修正して下さい。

サーバー環境のターミナル
echo $HOME

# ここで表示されるパス「/home/ユーザー名」をコピー

cd /etc/systemd/system/
vi puma_${APP_NAME}_production.service

# 開かれたファイルの ExecStart=$HOME の $HOME を先ほどコピーしたものに置き換えて保存終了

sudo systemctl daemon-reload
sudo systemctl enable puma_${APP_NAME}_production.service

これで準備が完了です。再度デプロイしてみましょう!

ローカル環境のターミナル
bundle exec cap production deploy

【備考】ここでデプロイに失敗した場合は,まずエラー文を確認しましょう。いろいろなケースがありますが,アプリで使用されている gem 次第では,先に依存関係にあるプラグインを EC2 にインストールしておく必要があります。

Nginx の設定

Nginx 用の設定ファイルを追加するため,先に必要なディレクトリをサーバー側で作成しておきましょう。

サーバー環境のターミナル
cd /etc/nginx
sudo mkdir sites-available

ローカル環境 のターミナルで,Railsアプリのルートディレクトリまで移動した後,以下を実行しましょう。
これで Nginx 用の設定が生成されます。

ローカル環境のターミナル
# Railsアプリのルートディレクトリに移動してから
bundle exec cap production puma:nginx_config

これで,サーバー側の /etc/nginx/conf.d に設定ファイル アプリ名.conf が入ります。

Nginx を再起動しましょう。

サーバー環境のターミナル(/etc/nginx)
sudo service nginx restart

ブラウザのアドレスバーに Elastic IP を入力してアクセスし, スーパーリロード して下さい。(ショートカットキーは command + shift + r

アプリが表示されればOKです!

【補足】アプリが表示されない場合は,以下を試して下さい

  • ローカル環境のターミナルから curl -I ElasticIP を実行したとき,最初に HTTP/1.1 301 Moved Permanently が出力される場合
    • config/environments/production.rbconfig.force_ssl = true をコメントアウトして下さい
  • 9.4 にログの確認方法を記載していますので,確かめてみましょう!!

これでひとまずデプロイは完了です!……が,他にもすべきことがあります。

「無事デプロイに成功した!!」という方は是非 LGTM もお願いいたします!

135
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
135
Help us understand the problem. What is going on with this article?