AWS EC2 に Amazon Linux 2023 で Rails を立ち上げる。

前回、Amazon Linux 2023 の Docker イメージで Rails を立ち上げられた。
今回は、改めて AWS EC2 上の Amazon Linux 2023 で Rails を立ち上げる。

参考

操作

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

  • VPC エンドポイント 用を作成
  • EC2 インスタンス 用を作成

どちらもインバウンドルール、アウトバンドルールともに空で入れておく。

EC2 インスタンスを作成

Amazon Linux 2023 でインスタンスを作成。
作ったEC2インスタンス用のセキュリティグループを割り当てる。

VPC エンドポイントを作成

  • 名前:任意
  • サービスカテゴリ: EC2 Instance Connect Endpoint
  • VPC: EC2 インスタンスに割り当てた VPC を設定
  • セキュリティグループ: 作った VPC エンドポイント用のセキュリティグループを割り当て
  • subnet: 任意

セキュリティグループを編集

  • VPC エンドポイント 用を作成

    • インバウンドルール:空
    • アウトバンドルール:
      • タイプ:SSH
      • プロトコル:TCP
      • ポート範囲:22
      • 送信先:カスタム
        • EC2 インスタンス用のセキュリティグループ
  • EC2 インスタンス 用を作成

    • インバウンドルール:
      • タイプ:SSH
      • プロトコル:TCP
      • ポート範囲:22
      • ソース:カスタム
        • VPC エンドポイント用のセキュリティグループ
    • アウトバンドルール:
      • タイプ:すべてのトラフィック
      • プロトコル:TCP
      • ポート範囲:22
      • 送信先:カスタム
        • 0.0.0.0/0

EC2 インスタンス内の設定

EC2 Instance Connect エンドポイントを使用したEC2 Instance Connect で、EC2 インスタンスへ接続できるようになっている。

ruby のセットアップ

asdf 経由での ruby 導入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ dnf update -y
$ dnf install -y nano git which tar gcc rust patch make bzip2 openssl-devel libyaml-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel

# asdf の設定
$ git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.12.0
$ echo '. "$HOME/.asdf/asdf.sh"' >> ~/.bashrc
$ echo '. "$HOME/.asdf/completions/asdf.bash"' >> ~/.bashrc
$ source ~/.bashrc
$ asdf plugin add ruby https://github.com/asdf-vm/asdf-ruby.git
$ TMPDIR="${PWD}/tmp" asdf install ruby 3.2.2
# まあまあ待つ(割り当てたスペック次第の可能性もある)
# --verbose を付けると、進行状況が見えるように書いてあるが、実際は表示されなかった。
# 併せて案内される tail -f ~~ に従って、別のコンソールを開き、見る方が状況が掴める。

$ asdf global ruby 3.2.2
$ rm -rf tmp/

nginx のセットアップ

1
$ dnf install -y nginx

Rails のセットアップ

1
2
3
4
5
6
7
8
$ bundle init
# # gem "rails"
# のコメントアウトを削除
$ bundle install
$ bundle exec rails new .
# => Y
$ bundle exec rails s
# => Rails 起動

別のコンソールで、curl localhost:3000 を実行すると応答する。
とりあえず、起動まで確認できる。

Rails と nginx を連携

config/puma.rb
1
2
3
4
5
#ポート設定をコメントアウトして
#port ENV.fetch("PORT") { 3000 }

#ソケットファイルの作成を指定する
bind "unix://#{Rails.root}/tmp/sockets/puma.sock"
/etc/nginx/conf.d/rails_apps_unix.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
upstream rails_app_unix {
server unix:///[rails アプリケーションのパス]/tmp/sockets/puma.sock;
}

server {
server_name localhost;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

root [rails アプリケーションのパス]/public;

location / {
try_files $uri @rails_app;
}

location @rails_app {
proxy_pass http://rails_app_unix;
}
}
1
2
3
4
$ bundle exec rails s

# 別のコンソールで
$ systemctl restart nginx

別のコンソールで、curl localhost を実行すると応答する。
nginx のログを見ると nginx を通過していることを確認できる。

インターネットからアクセスさせる

直接

EC2 インスタンスの、セキュリティグループを編集。

  • EC2 インスタンス 用を作成
    • インバウンドルール:
      • タイプ:HTTP
      • プロトコル:TCP
      • ポート範囲:22
      • ソース:Anywhere IPv4
      • 0.0.0.0/0

ブラウザで、EC2 インスタンスのパブリック IPv4 DNS にアクセスすると、Rails が応答する。
ただし、Blocked host: [パブリック IPv4 DNS に記載されたもの] となる。

以下のように編集。

config/environments/[環境].rb
1
2
3
Rails.application.configure do
config.hosts << "[パブリック IPv4 DNS に記載されたもの]"
env

再起動すると、インターネットからの通信にもRailsからエラー無く応答する。

ALB 経由

ターゲットグループを作成。

  • ターゲットタイプの選択:インスタンス
  • ターゲットグループ名:任意
  • プロトコル:HTTP
  • ポート:80
  • VPC: EC2 インスタンスが所属しているVPC
  • プロトコルバージョン: HTTP1

ロードバランサー用セキュリティグループを作成。

  • EC2 インスタンス 用を作成
    • インバウンドルール:

      • タイプ:HTTP
      • プロトコル:TCP
      • ポート範囲:80
      • ソース:Anywhere IPv4
        • 0.0.0.0/0
    • インバウンドルール:

      • タイプ:HTTP
      • プロトコル:TCP
      • ポート範囲:80
      • ソース:Anywhere IPv6
        • ::/0
    • アウトバンドルール:

      • タイプ:HTTP
      • プロトコル:TCP
      • ポート範囲:80
      • 送信先:カスタム
        • EC2 インスタンス用のセキュリティグループ

ロードバランサーを作成。

  • Application Load Balancer を選択
  • 基本的な設定
    • ロードバランサー名:任意
    • スキーム:インターネット向け
    • IPアドレスタイプ:Dualstack
  • ネットワークマッピング
    • VPC 任意
    • マッピング:任意(今回はすべてチェックをいれた)
  • セキュリティグループ
    • ロードバランサー用セキュリティグループ を割り当て
  • リスナーとルーティング
    • プロトコル:HTTP
    • ポート:80
    • デフォルトアクション:作成したターゲットグループを割り当て

ブラウザで、ロードバランサの DNS 名 にアクセスすると、Rails が応答する。
また、ただし、Blocked host: [パブリック IPv4 DNS に記載されたもの] となる。

config/environments/[環境].rb をまた編集。
再起動すると、インターネットからの通信にもRailsからエラー無く応答する。

EC2 インスタンスのターゲットグループは、インターネットからのアクセスを受け付けているので、編集する。

  • EC2 インスタンス 用を編集
    • インバウンドルール:
      • タイプ:HTTP
      • プロトコル:TCP
      • ポート範囲:22
      • ソース:Anywhere IPv4
        • ロードバランサーのセキュリティグループ

ブラウザで、EC2 インスタンスのパブリック IPv4 DNS にアクセスして応答しないことを確認できる。

割り当てたドメインでHTTPS

Route53 でドメインを取って有り、パブリック証明書を取ってあるものとする。

ロードバランサーのセキュリティグループを編集。

  • EC2 インスタンス 用を作成
    • インバウンドルール:
      • タイプ:HTTPS
      • プロトコル:TCP
      • ポート範囲:443
      • ソース:Anywhere IPv4
        • 0.0.0.0/0
    • インバウンドルール:
      • タイプ:HTTPS
      • プロトコル:TCP
      • ポート範囲:443
      • ソース:Anywhere IPv6
        • ::/0

ロードバランサーにリスナーを追加。

  • リスナーの詳細
    • プロトコル:HTTPS
    • ポート:443
    • アクションの種類:ターゲットグループへ転送
        - ターゲットグループへ転送:作成済みのターゲットグループを割り当て
  • セキュアリスナーの設定
    • セキュリティポリシー: ELBSecurityPolicy-TLS13-1-2-2021-06 (推奨)
      • 推奨のモノを選んでおいた
    • デフォルトの SSL/TLS 証明書
      • ACMから
      • 作成済みの証明書を割り当て

ブラウザから、取得済みのドメインでアクセスをすると、nginx が 502 を返す。
また、ただし、Blocked host: [ドメイン] となる。

config/environments/[環境].rb をまた編集。
再起動すると、インターネットからの通信にもRailsからエラー無く応答する。

このタイミングで、ドメインからのアクセスしか受け付けないように他のhost名登録は消しておく。

また、ロードバランサーの HTTPのリスナーを一旦削除する。
再作成。

  • リスナーの詳細
    • プロトコル:HTTP
    • ポート:80
    • デフォルトアクション
      • アクションの種類
        • URLにリダイレクト
      • URL にリダイレクト
          - プロトコル:HTTPS
        • ポート:443
      • ステータスコード
        • 301 - 完全に移動されました

HTTPでアクセスするとHTTPSにリダイレクトがかかる。

Rails をサービス化する

Rails はコンソールから実行しているので、最後にサービス化して終わる。

/etc/systemd/system/puma.service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=RailsApp
After=nginx.service

[Service]
Type=simple
Environment="PATH=/root/.asdf/shims:/root/.asdf/bin:/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
MAIL=/var/spool/mail/root"
WorkingDirectory=[アプリケーションのパス]
ExecStart=/root/.asdf/shims/bundle exec /root/.asdf/shims/rails s
Restart=always

[Install]
WantedBy=default.target

起動します。

1
$ systemctl start puma

プロセスを手動で kill して再起動する事も確認できる。
自動起動も設定する。

1
2
3
$ systemctl enable nginx
$ systemctl enable puma
$ reboot

OSが再起動しても自動で再起動する事が確認できた。


AWS EC2 上の Amazon Linux 2023 で Rails を立ち上げた。
後半は、ALB 周りのセットアップの振り返りだったようにも思えるが、良かったことにする。
SELinux で困るかと思ったが、とりあえずここまでの設定で困る事はない。
どこか引っかかるポイントがありそうなので、別途確認をしておきたい。
最近 Docker でなるだけ全部もみたいな形だったが、たまには全部セットアップしてみるのもいいのやもしれない。

では。