NAKKA-Kの技術ブログ

技術に関する知見や考え方などを投稿します。

Elastic BeanstalkのMultiContainer環境にRails+Nuxtをデプロイする

Elastic BeanstalkでMultiContainer環境を構築し、RailsとNuxt.jsをデプロイします。

今回の環境

  • ElasticBeanstalk(Multi-container Docker)
  • Rails 5.2 (ruby:2.6)
  • Nuxt.js 2.11 (node:12-alpine)
  • PostgreSQL (RDS)

目次

初期設定

AWSのアカウント登録

アカウント登録については以下の記事を参考にしてください。

www.wakuwakubank.com

https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/iam-servicerole.html

ElasticBeanstalkの環境を作成する

AWSマネジメントコンソールからElasticBeanstalkを検索し開く。

最初に新しいアプリケーションを作成する必要があります。 「アプリケーション名」はそれぞれのElasticBeanstalk環境をグルーピングするためのグループです。 特にこだわりがないならアプリケーション名だけ適当に入力して「作成」します。 f:id:NAKKA-K:20200131140720p:plain

次に右上のアクションから「環境の作成」をクリックする。 f:id:NAKKA-K:20200131130611p:plain

ウェブサーバー環境を選択したまま「選択」をクリック。 f:id:NAKKA-K:20200131130632p:plain

アプリケーションの情報を決めて設定していきます。 プラットフォームをMulti-container Dockerに設定します。 f:id:NAKKA-K:20200131135548p:plain f:id:NAKKA-K:20200131141826p:plain

DBやインスタンスなど、追加の設定をしたい場合「より多くのオプションの設定」をクリックします。 この中で重要な点をいくつか紹介します。

  • ソフトウェアでは環境変数を設定できます。
  • 容量ではEC2のインスタンスタイプを変更できます。
  • データベースではその名の通りどのDBを使用するか設定できます。
  • 設定のプリセットをカスタムにするとロードバランサーを設定できます。HTTPSの設定やポートの設定もこちらです。(環境作成時に設定しないとその後、EBから設定できないので気をつけましょう) f:id:NAKKA-K:20200131143144p:plain f:id:NAKKA-K:20200131143155p:plain

環境変数系の用意

ソフトウェアをクリックして環境変数を設定しましょう。 デプロイ環境では以下の環境変数を個別に指定する必要があります。

  • NODE_ENV = production
  • RAILS_ENV = production
  • RAILS_MASTER_KEY = (これはbackend/config/master.keyの値)

f:id:NAKKA-K:20200203102252p:plain

データベースを設定する

今回のプロジェクトではデータベースをPostgreSQLに設定します。 データーベースの項目をクリックして、データベースの変更とユーザー名・パスワードの設定をしましょう。

f:id:NAKKA-K:20200203102620p:plain

ロードバランサー の設定

まずApplication Load Balancerに必要なポートを列挙します。 それぞれにHTTP、HTTPSのどちらにするのか設定し、HTTPSにする場合はACM(AWS Certificate Manager)で発行した証明書を設定する必要があります。(既存の証明書をインポートすることもできます)

以下の写真では全てHTTPになっていますが、私の環境の場合80番以外HTTPSに設定します。

f:id:NAKKA-K:20200207143033p:plain

f:id:NAKKA-K:20200207143753p:plain

環境を作成する

設定が終わったら「環境の作成」ボタンをクリックして確定しましょう。

すると環境の作成を始め、初期設定のままならサンプルアプリケーションがデプロイされることになります。 環境の作成には5分~10分くらいかかるので気長に待ちましょう。

アプリケーションを確認する

構築が完了するとアプリケーションを管理する画面に遷移します。 画面上部にあるURLを開くとサンプルアプリケーションに接続できます。

f:id:NAKKA-K:20200203124842p:plain

このような画面が見えるかと思います。

f:id:NAKKA-K:20200203124908p:plain

本番アプリケーションをデプロイする

ここからはサンプルアプリケーションではなく実際のアプリケーションをデプロイしていきます。 私がデプロイ時に困ったことや気をつけた方がいいなと思った細かい事象はこの章の最後に一覧化しておきますので参考にしてください。

まず今回ElasticBeanstalkの設定をするに当たって必要なファイルは以下の通りです。 順番に設定していきましょう。

  • Dockerrun.aws,json
  • .ebextentions/
    • elb-listener.config
    • elb-secure.config
  • .elasticbeanstalk/
    • config.yml

Dockerrun.aws.json

全体の説明は複数コンテナの Docker 設定を参照してください。

docker-compose.ymlとDockerrun.aws.jsonはある程度互換性があります。

docker-compose.yml Dockerrun.aws.json
services以下のサービス名 name
image image
hostname hostname
該当なし memory
ports portMappings
volumes volumes+mountPoints
depends_on links
environment environment
command command

まず3行目のvolumesでホスト側のどのソースをマウントしたいのか設定します。 nameは任意の識別子なので自分でわかるものを指定してください。 hostにはどのパスをマウントするのか設定します。

そしてここで設定したnamecontainerDefinitionsにあるmountPointsで使用します。sourceVolumeに対して先ほど設定した任意の識別子を記述し、containerPathにマウント先のコンテナ内のパスを設定します。

次にenvironmentについてです。 containerDefinitions配列内のオブジェクトがそれぞれ1つのコンテナになっています。あるコンテナに書いたenvironmentはそのコンテナ内でしか展開されないようになっていますので気をつけてください。 そしてこのDockerrun.aws.jsonは基本的にGit管理下に含めるため、重要なキーなどを絶対に含めないように気をつけてください。秘密にしなければいけない環境変数AWSコンソールから環境プロパティに設定しましょう。

最後にmemoryに関してです。 これに関しては具体的にどうと言えるわけではありませんが、t2.microのメモリ1GiBを超えないように気を付けることだけは徹底しましょう。 合計で1GiBよりも小さく設定している理由としては、限界まで設定すると逆にパフォーマンスが悪くなる可能性、そしてインスタンスsshをした時にコマンドを走らせる猶予を考慮してのことです。 感覚的な話ですがmemoryを256に設定した時はメモリが足りずに動かなくなってしまっていた状況が見られたので低すぎるのは厳禁です。

.ebextentions/elb-listener.configと.ebextentions/elb-secure.config

APIコンテナに接続するために8080番の設定を別途します。 他には基本HTTPS通信にする予定なので443ポートの設定も書いておきましょう。

SSLCertificateArnsACMで取得した証明書のIDに書き換えておきましょう。 重要な値なので.ebextentions/elb-secure.configは.gitignoreでGit管理下から外しておきましょう。

.elasticbeanstalk/config.yml

このファイルはコマンドを使用して生成します。 以下の記事を見ながらawsebcliをインストールしてください。

qiita.com

インストール後、デプロイしたいプロジェクトのルートディレクトリでeb initを実行して対話的に設定してください。 コマンドの実行が完了するとファイルが生成されていますので完了です。

デプロイする

Dockerrun.aws.jsonのあるプロジェクトルートからeb deployコマンドを実行しましょう。 git archiveコマンドが実行されZIP化されたソースコードがS3にアップロードされます。その後S3からECSを通してDockerコンテナの立ち上げなどが行われます。 Dockerコンテナの起動にはDockerrun.aws.jsonが参照されて、設定通りに起動されます。

このコマンドには1分程度かかり、その後反映まで少し時間がかかります。 デプロイが完了したら、AWSコンソールでヘルスチェックがグリーンになっていることも確認できます。

(補足)デプロイ時に気を付けること一覧

順不同なのでざっと見て必要なところだけ確認してください。

私も詰まった部分が多すぎて全てを詳細に書ききれません。 内容についてコメントで聞いていただければ、答えられる部分に関しては答えたいと思っています。

EC2やDocker

Nuxt

HTTPS

Rails

まとめ

今回のデプロイでは全ての工程が長く、かつその他の問題も複雑に絡んできたせいで多くの障害がありました。 その苦難を少しでも解決するためにこの記事を書きました。

このデプロイで得た教訓としては、結局地道に見当・検証することが重要でした。 そして実際の細かな動きをトレースして全体の構成を想像すれば大体解決しました。

既に記憶から薄れ始めている部分もあるので、聞かれないと思い出さない箇所もあって全てを詳細に書ききれていません。 そのため追加で詳しく聞きたい箇所などあればコメントください。 少しでも解決の一助になればと思います。

引用