herokuを使ったRailsアプリのデプロイについての記事です!scaffoldで作ったアプリをデプロイするだけだとだいぶ楽ですが、通常のちゃんとしたアプリの機能を備えたものをデプロイするのは中々作業が多いです。ただ、この記事の通りやれば、デプロイできるので、安心してください!
自分の環境とアプリの前提
バージョン
Rails 5.2.3
Ruby 2.6.3
前提
- 画像の投稿あり
- セッション管理はredis
- mailerを使用
Railsアプリをデプロイするための基本的な流れ
やることを整理すると以下の作業があります。
- herokuへの登録
- herokuの機能を自分のPCに紐付け(herokucliをダウンロード)
- config/routes.rbの設定
- Gemfileの設定
- config/datebase.ymlの設定
- config/environments/production.rbの設定
- redisの設定(使っている人だけ)
- S3の設定
- yarn、node関係
- rubybuild
- credentials.yml.encを使うときはherokuにmasterキーを登録
- mailer使う場合はmailerの設定
めっちゃありますね。AWSでのデプロイよりは簡単なんですが、それでもこれだけあります!私のやったことをまとめて書いていきます!
herokuへの登録
まずは、herokuに登録します。
会員登録が完了したら、今度はherokuの機能を自分のPCに紐付けましょう。cliをダウンロードします。
私はmacですので、ターミナルでherokuのページでの指示通り以下のコマンドでインストールしました。homebrewを使ってインストールします。
$ brew tap heroku/brew && brew install heroku
Railsアプリとherokuの紐づけ
まずは、自分のPCからherokuにログインします。ネットに繋げていないといけないので、ご注意を!
PCからherokuにログイン
$heroku login
そうすると、herokuに登録したemailとpasswordの入力を求められるので、指示された通りに打ち込んでください。
heroku上にアプリのフォルダを作成
以下のコマンドで、作成
$ heroku create 好きなアプリ名
doneとなっていれば完了!
Name is already taken...」となっていたら、名前がすでに使われているので、違う名前にしましょう!
config/routes.rb
configフォルダの中のroutes.rbについて、トップページのルーティングをきちんと作ります。
大事なのはトップページを何かしらに設定していていないとページがありませんというエラーがで続けます。
Gemfileの設定
次に、Gemfileを変更していきます。
私の場合はミドルウェアにmysqlを使っているので、こんな感じに書き直しました。
色々省略
gem 'mysql2', '>= 0.4.4', '< 0.6.0', group: [:development, :test]
group :production do
gem 'pg'
end
意味は、「mysqlはdevelopment環境とtest環境でしか適用しない」です。
これからデプロイする予定であるherokuではPostgreSQL(略してpg)というデータベースが最初からインストールされているので、その環境に合うようにこのような変更をしています。
さて、Gemfileを変更したので忘れずにbundle installをしておきましょう。ただし、以下のようにオプションを指定します。
$bundle install --without production
このオプションをつけることによって、group :produciton do~end内以外のgemをインストールすることができます。
ちなみに、このオプションは一度打ち込めば、アプリ内部の/bundle/configというところに書き込まれるため、それ以降は--without producitonを打たなくても本番環境以外のgemをインストールしてくれるようになります。その他のbundle install時のオプションは全てここに書き込まれます。
#このようになっていたらOKです
BUNDLE_WITHOUT: "production"
config/datebase.ymlの設定
さきほどGemfileを変更したことによりこのアプリは本番環境でPostgreSQLを使います、という宣言(と機能をインストールするための準備)は完了したのですが、実際にデータベースと接続する記述はまだ完了していません。その接続の設定をする箇所がconfigフォルダの中にあるdatabase.ymlというファイルで、これを変更する必要があります。
ファイル内の下の方にあるproduction環境についての設定を、以下のように記述します。インデントに注意です!ずれてるとダメです!
production:
<<: *default
adapter: postgresql
encoding: unicode
pool: 5
config/environments/production.rbの設定
Railsは本番環境でのプリコンパイルがデフォルトでオフになっています。
画像を表示するために以下の記述をfalseからtrueに変更して対応することも可能ですが、毎回読み込む度にコンパイルして配信するファイルを作るためパフォーマンスが悪くなります。
この記述により、assets以下のフォルダから動的にコンパイルしながらページを読み込むことになります。
#デフォルトでfalseとなっている以下の箇所をtrueに変更
config.assets.compile = true
設定としてはこちらのやり方が推奨です。
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
環境変数'RAILS_SERVE_STATIC_FILES'をtrueで設定してpublic配下のコンパイルしたファイルを静的に配信するようにします。
ここから先が結構厄介でした。。。。
S3の設定(Ruby + Heroku + carrierwave )
herokuデプロイで、投稿した画像データを表示するには、AWSのS3を設定し、そこに画像を保存する必要があります。
ここでの流れは、
①AWSのアカウントを作成する
②AWS Identity and Access Management (IAM)でユーザーとグループ(AmazonS3FullAccess)作成(アクセスキーとシークレットアクセスキーは後から使うのでcsvはダウンロードしておくと良い)
③作成したユーザーでログインし、サービス「S3」にてバケットを作成する
こちらの記事を参考にしました。
https://qiita.com/params_bird/items/dc2a3868f4a2caf0504c
設定コードの修正
fogをインストール、本番環境での保存先設定
fogをインストールします。Gemfileに含めたらbundle installします。
gem 'fog'
開発環境ではローカルファイルに画像保存で問題ありませんが、本番環境ではクラウドストレージサービス(fog)に保存するように設定します。
Carrierwaveをインストールした際に生成したuploaderファイルに以下を追加します。
if Rails.env.development?
storage :file
elsif Rails.env.test?
storage :file
else
storage :fog
end
carrierwaveの設定
私はcredentials.ymlに実際のキーなどを記載して、それを呼び出す方法をとりました!呼び出す際の設定ファイルの書き方は以下です!
if Rails.env.production?
CarrierWave.configure do |config|
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: Rails.application.credentials.aws[:access_key_id],
aws_secret_access_key: Rails.application.credentials.aws[:secret_access_key],
region: Rails.application.credentials.aws[:region]
}
config.fog_directory = Rails.application.credentials.aws[:fog_directory]
config.cache_storage = :fog
end
end
credentials.ymlは暗号化されて表示されるので、ファイルを直に弄って記載できないので、以下のコマンドでvimを起動して記載します!
$ EDITOR="vi" rails credentials:edit
そうすると、こんな感じでvimが起動され、中身が編集できるようになります。
aws:
access_key_id: DRFJUJGFHJ...........(ここは実際のキーが入ります)
secret_access_key: CEDGRGFHJ...........(ここは実際のキーが入ります)
region: ap-northeast-1(東京リージョンなら)
fog_directory: バケット名が入ります
インデントに注意して、このような形で定義すると、Rails.application.credentials.aws[:access_key_id]
などいった形で呼び出すことができます。
これだけだと、実はまだダメです!
credential.ymlは、master.key
が無いと開くことができないようになっており(秘密鍵と言います)、これをheroku上に登録してあげなければなりません。
以下のコマンドを打てば、登録できます!
$ heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
yarn,rubybuild
ここの設定をしていないと、デプロイコマンドを叩いた時に、「rails assets:precompile」
の部分でエラーが出ます。yarnを使えるようにしておきます。
$ heroku buildpacks:add --index 1 heroku/nodejs
$ heroku buildpacks:add --index 2 heroku/ruby
このコマンドを打っておきましょう!
redisの設定
Heroku CLI で アドオン を追加
heroku CLI で heroku-redis アドオンを追加する。herokuサイト上からもGUIで追加は可能
ダッシュボード上の「Configure Add-ons」からも可能!
コマンドの場合は、
$ heroku addons:create heroku-redis:hobby-dev
ここで、herokuのサイト上でクレジットカードを登録しておかないと、追加できないことがあるので、その時はクレジットカードを登録しておいてください。(無料のサービスしか使っていなければ課金されることはありません)
heroku CLI で 環境変数 REDIS_URL (Redis のエンドポイント)が追加されてることを確認する
$ heroku config
=== shakestagram Config Vars
...
REDIS_URL: redis://xxxxx@xxxxx:xxxxx
...
config/environments/production.rbの設定
# この一行追加
config.session_store :redis_store, servers: ENV['REDIS_URL'], expire_after: 1.day
production環境でのActionMailerの設定
HerokuのアドオンSendGridを追加します!
$ heroku addons:create sendgrid:starter
ENV['SENDGRID_USERNAME'とENV['SENDGRID_PASSWORD']の環境変数が上のコマンド一つでセットされます。
config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = { host: 'アプリのURL' }
config.action_mailer.perform_deliveries = true
config.action_mailer.smtp_settings = {
user_name: ENV['SENDGRID_USERNAME'],
password: ENV['SENDGRID_PASSWORD'],
domain: 'herokuapp.com',
address: 'smtp.sendgrid.net',
port: 587,
authentication: :plain,
enable_starttls_auto: true
}
私は、メールの永続化にsidekiqというツールを使っているので、その設定ファイルに環境変数のURLをコピペして記載します。コピペするのは、環境変数 REDIS_URL (Redis のエンドポイント)です!
。本番環境と開発環境で分岐。
$ heroku config
=== shakestagram Config Vars
...
REDIS_URL: redis://xxxxx@xxxxx:xxxxx
...
if Rails.env.development?
Sidekiq.configure_server do |config|
config.redis = {
url: 'redis://localhost:6379'
}
end
Sidekiq.configure_client do |config|
config.redis = {
url: 'redis://localhost:6379'
}
end
else
Sidekiq.configure_server do |config|
config.redis = {
url: 'redis://xxxxx@xxxxx:xxxxx'
}
end
Sidekiq.configure_client do |config|
config.redis = {
url: 'redis://xxxxx@xxxxx:xxxxx'
}
end
end
やっとherokuにデプロイ
変更したファイルを全て、git add、git commitしたあと、
$git push heroku master
これだけでデプロイできます。
本番環境でrails db:migrate
$ heroku run rails db:migrate
このようにheroku runをつけるとheroku上でrailsコマンドを打つことができます。
heroku run rails db:migrateが通らない場合
私の場合は、以下のコマンドを打ったあと、migrateすると通りました!
$ heroku addons:create heroku-postgresql