概要
rails5.1.1をvueとreact readyのアプリをインストールし、ローカルとAWS Elasticbeanstalkで表示するまでの手順を示す。
ただしElastic Beanstalkは、nginxの調査が足りないため暫定的な方法を記した。 webpackerの設定をすることで出来るようになりました。
環境
ローカル
- rbenv 2.3.1
- macOS Sierra
- yarnインストール済
- npmインストール済
- gitインストール済(SourceTreeでも可)
本番(AWS Elastic Beanstalk)
- AWSアカウント持ってる
- ebとawsのCLIがローカルにインストールされている。
ローカル環境で動かすまで
yarnを最新バージョンにする
brew upgrade yarn
railsインストール
- bundle初期化
rbenvでlocalのバージョンを2.3.1にセット(バージョンはなんでもいいです。)
rbenv local 2.3.1
rbenv exec bundle init
- rails インストール準備
gem 'rails'
- rails インストール
bundleのインストール先として、 vendor/bundler を指定しました。
rbenv exec bundle install --path vendor/bundler
rbenv exec bundle exec rails new . --webpack
(途中Gemfileの上書きして良いか聞かれるのでYを選択。)
rbenv exec bundle exec rails webpacker:install:vue
rbenv exec bundle exec rails webpacker:install:react
vueとreact動作確認用の設定
class StaticPagesController < ApplicationController
def home
end
end
Rails.application.routes.draw do
root to: 'static_pages#home'
end
<%= javascript_pack_tag 'hello_vue' %>
<%= javascript_pack_tag 'hello_react' %>
サーバー起動
rails server と webpack-dev-server を両方起動する
rbenv exec bundle exec rails s
bin/webpack-dev-server
アクセスしてみる
本番環境(AWS ElasticBeanstalk)で動かすための追加設定
このまま、デプロイしても失敗する。
失敗する原因は以下の3つ。
- webpackerが使うyarnがEBSにインストールされていない
- yarnをインストールする前に、rake assets:precompile が行われてしまう
- publick/pack配下のwebpack が変換したjavascriptをnginxがアセットとして認識してくれない
1と2は解決法を、3については暫定的な対応策を示す。
その前にEBSにデプロイするための一般的な設定
こちらのRuby on Railsの環境構築をElastic Beanstalkで行うの通りすすめればOK。(かなり丁寧に説明されています。)
上記と重複しますが、もし、上記でうまく行かなかったら参考になるかもしれませんので、自分の作業手順を記します。
postgresql用のgemインストール
- elastic beanstalkでpostgresqlを使うようにrailsを修正
###省略###
# postgreSQL
gem 'pg'
rbenv exec bundle install
データベースの設定をEBSの環境変数から読み込むように修正
###省略###
production:
<<: *default
adapter: postgresql
database: <%= ENV["RDS_DB_NAME"] %>
username: <%= ENV["RDS_USERNAME"] %>
password: <%= ENV["RDS_PASSWORD"] %>
host: <%= ENV["RDS_HOSTNAME"] %>
port: <%= ENV["RDS_PORT"] %>
IAM ユーザ作成
- awsでIAM でelastic beacnstalkに接続できる権限を有するユーザを作成し、 アクセスキーID と シークレットアクセスキー を取得
awsの接続設定
- awsコマンドラインツールとebコマンドラインを事前にインストールしておいて、以下を実行
> aws configure
AWS Access Key ID [****************LSGQ]: アクセスキーID
AWS Secret Access Key [****************FmS9]: シークレットアクセスキー
Default region name [ap-northeast-1]:
Default output format [json]:
elastic beanstalkの設定フォルダ( .elasticbeanstalk )をコマンドラインで作成
- 事前準備:AWSのキー(今回はaws-eb2をつくっておきました)
- アプリ直下のフォルダで操作ターミナル操作してください。
> eb init
Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-south-1 : Asia Pacific (Mumbai)
7) ap-southeast-1 : Asia Pacific (Singapore)
8) ap-southeast-2 : Asia Pacific (Sydney)
9) ap-northeast-1 : Asia Pacific (Tokyo)
10) ap-northeast-2 : Asia Pacific (Seoul)
11) sa-east-1 : South America (Sao Paulo)
12) cn-north-1 : China (Beijing)
13) us-east-2 : US East (Ohio)
14) ca-central-1 : Canada (Central)
15) eu-west-2 : EU (London)
(default is 3): 9
Select an application to use
1) rails-base
2) [ Create new Application ]
(default is 1):
It appears you are using Ruby. Is this correct?
(Y/n):
Select a platform version.
1) Ruby 2.3 (Puma)
2) Ruby 2.2 (Puma)
3) Ruby 2.1 (Puma)
4) Ruby 2.0 (Puma)
5) Ruby 2.3 (Passenger Standalone)
6) Ruby 2.2 (Passenger Standalone)
7) Ruby 2.1 (Passenger Standalone)
8) Ruby 2.0 (Passenger Standalone)
9) Ruby 1.9.3
(default is 1):
Do you want to set up SSH for your instances?
(Y/n):
Select a keypair.
1) aws-eb
2) aws-eb2
3) [ Create new KeyPair ]
(default is 2):
上記を実行すると以下のファイルが作成されます。
(rails-baseというのは、アプリ名です。それぞれのアプリで異なります。)
branch-defaults:
elasticbeanstalk:
environment: null
global:
application_name: rails-base
branch: null
default_ec2_keyname: aws-eb2
default_platform: Ruby 2.3 (Puma)
default_region: ap-northeast-1
instance_profile: null
platform_name: null
platform_version: null
profile: eb-cli
repository: null
sc: git
workspace_type: Application
変更した内容をgitにコミットする
elasticbeanstalkにアップロードするファイルはgitでcommitされたファイル。
よってこれまでの変更をcommitする。
リポジトリを作成
git init
これまでの変更をgitのステージにあげる
git add .
gitにコミットする
git commit -m 'first commit desu'
elastic beastalkの新しいアプリケーションを作成
以下を実行する。
ただし、データベースの設定をしていないので失敗します。でも気にしない。
eb create
Enter Environment Name
(default is rails-base-dev):
Enter DNS CNAME prefix
(default is rails-base-dev):
Select a load balancer type
1) classic
2) application
(default is 1):
以下のようなエラーメッセージで終了するはず。
INFO: Command execution completed on all instances. Summary: [Successful: 0, Failed: 1].
WARN: Environment health has transitioned from Pending to Degraded. Command failed on all instances. Initialization completed 24 seconds ago and took 4 minutes.
ERROR: Create environment operation is complete, but with errors. For more information, see troubleshooting documentation.
データベースの追加
RDSの作成を参照してデータベースを追加する。
railsサーバー用のシークレットキーの生成
下記でシークレットキーを作成する。
rbenv exec bundle exec rake secret
elasticbeanstalkの環境変数の設定
下記のコマンドを実行して、環境変数を設定します。
わかりやすさを重視して、環境変数を1個ずつ設定するようにしました。
しかし、設定毎に、デプロイが行われ(かつ失敗する!)のでうざいかも。
eb setenv RDS_DB_NAME=ebdb
eb setenv RDS_USERNAME=データベースのユーザ名
eb setenv RDS_HOSTNAME=データベースの接続アドレス
eb setenv RDS_PASSWORD=データベースの接続パスワード
eb setenv RDS_PORT=5432
eb setenv SECRET_KEY_BASE=railsサーバー用のシークレットキー
その場合は、上記のリンク先を参照して、下記の様に1行にして実行してください。うざい回数が減ります。
eb setenv RDS_DB_NAME=ebdb RDS_USERNAME=データベースのユーザ名 RDS_HOSTNAME=データベースの接続アドレス RDS_PASSWORD=データベースの接続パスワード RDS_PORT=5432 SECRET_KEY_BASE=railsサーバー用のシークレットキー
一般的なEBSの設定はここまで。
でも前述の通り、これだけではデプロイに失敗するので、追加の設定をします。
追加の設定
webpackerが使うyarnがEBSにインストールされていないへの対処
yarnをインストールするための設定を .ebextensions に書き込みます。
コードは以下のリンク先のままです。内容は、yarn公式のインストールコマンドを並べただけです。
Customize AWS ElasticBeanstalk NodeJS Install (use yarn)
commands:
02_install_yarn:
command: "sudo wget https://dl.yarnpkg.com/rpm/yarn.repo -O /etc/yum.repos.d/yarn.repo && curl --silent --location https://rpm.nodesource.com/setup_6.x | sudo bash - && sudo yum install yarn -y"
yarnをインストールする前に、rake assets:precompile が行われてしまうへの対処
EBSの環境変数 RAILS_SKIP_ASSET_COMPILATION を true にすると rake assets:precompile を抑制できます。
下記のコマンドで環境変数を追加します。
eb setenv RAILS_SKIP_ASSET_COMPILATION=true
ただし、このままだとprecompileされません。前述のyarnのインストールの後に実行されるように .ebextensions に bundle exec rake assets:precompile を実行する命令を追加します。
commands:
02_install_yarn:
command: "sudo wget https://dl.yarnpkg.com/rpm/yarn.repo -O /etc/yum.repos.d/yarn.repo && curl --silent --location https://rpm.nodesource.com/setup_6.x | sudo bash - && sudo yum install yarn -y"
container_commands:
03_compile-assets:
command: bundle exec rake assets:precompile
publick/pack配下のwebpack が変換したjavascriptをnginxがアセットとして認識してくれないへの対処
(以前の文書(webpacker 1.2の場合)は文末に移動しました。)
webpackerが2.0であることを確認してください(Gemfile.lockを見るとよいです)。もし、webpackerが1.2以下ならば、wepacker git pageを参照して、アップデートしてください。ただし、下記の手順は新規インストールを前提にしています。また、 アップデートに伴う既存のwebpackerの設定ヘの影響は検証していません。
EBSのnginxがアセットとして認識するのはpublic直下とpublic/assets。
一方、webpackerがデフォルトでアセットを作成するのはpublic/packs。
この差異を解決するため、webpacker.ymlを編集します。
default: &default
source_path: app/javascript
source_entry_path: packs
public_output_path: assets # ここをpacksからassetsに変更した
省略
デプロイする
前述の結果をgitにコミットします。
下記のコマンドでデプロイする。
eb deploy
ルートパスにアクセスするとローカル環境と同じhello vue!やhello react!などの文字が表示されることを確認してください。
表示されていれば、本番環境へのデプロイが無事されています。
付録1:独自ドメイン取得と登録
過去記事 AWS Route 53でElastic Beanstalkのアプリをドメイン登録
付録2:HTTPS対応
- 下記でかなり丁寧に説明されています。
*
Elastic BeanstalkでAWS上にHTTPS対応のRailsアプリケーションを構築する
備考
nginxの箇所は理解できたら追記します。 とりあえず使えるようになったので別の機会に勉強します。 @kansiho さんコメントありがとうございます。
.ebextensions/
にhttps://gist.github.com/ankitsinghaniyaz/48b3276d344668dff82a2b1cc3a8d455 のファイルを追加すればよいと思います。
下記の箇所の記述により、assets
とpacks
どちらでアクセスしてもキチンとpublic
配下を検索してくれるみたいです。
省略
location ^~ /assets/ {
root /var/app/current/public;
}
# commented out for now in favor of rails serving the files
location ^~ /packs/ {
root /var/app/current/public;
}
省略
古い文書(webpacker 1.2以前の場合)
publick/pack配下のwebpack が変換したjavascriptをnginxがアセットとして認識してくれないへの対処
先に断っておくと、 nginxに public/pack配下をアセットとして認識させる方法 はわかりませんでした。
よって、今回は nginxのアセットを使わないとする ことで 暫定的にEBSで起動させる 方法をとりました。
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
# config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? #これをコメントアウト
config.public_file_server.enabled = true # これを追加