LoginSignup
0
0

More than 1 year has passed since last update.

【デプロイ】Dockerで開発環境構築したRailsアプリをHerokuで本番公開する(M1Mac)

Last updated at Posted at 2022-09-23

1. 事前準備

前提:DockerでRailsの環境構築を行っておく(目安:15分)


Gitの初期設定を行う
※下記コマンドすべて実行

$ cd Documents/rails_docker
$ git config --global user.name "GitHubに登録したユーザネーム"
$ git config --global user.email "GitHubに登録したメールアドレス"
$ git config --global merge.ff false
$ git config --global pull.rebase merges
  • git config --global merge.ff false・・・mergeの際にファストフォワードが起こらないようにする設定
  • git config --global pull.rebase merges・・・pullの時に常にrebaseする設定

設定の確認

$ git config --list

2. Herokuにログイン

Heroku新規登録 ※既に登録済みの場合はSkip

  • クレカ登録
    • アイコンクリック→Account Settings→Billing
    • https://dashboard.heroku.com/account/billing
      • 無料枠の範囲内で行っていくが、MySQLをアドオンで追加する時にクレカを登録しておかないと追加できないため登録しておく

Heroku CLIをインストール ※インストール済みの場合はSkip

  • Herokuをコマンドで操作できるようにするツール

HerokuCLIインストール時にエラーが発生した場合はこちらも参考に


Herokuにログイン

  • rails_docker(任意で作成したアプリケーション名の)ディレクトリで行う
$ cd ~/Documents/rails_docker/
$ heroku login
  • 上記コマンドが実行されたらEnterキーを一度押す
    • ブラウザに遷移するのでログインボタンを押下
      スクリーンショット 2022-09-23 13.00.19.png
terminal
(base) sample@SampleMBP rails_docker % heroku login
›   Warning: Our terms of service have changed: https://dashboard.heroku.com/terms-of-service
heroku: Press any key to open up the browser to login or q to exit:
Opening browser to https://cli-auth.heroku.com/auth/cli/browser/e99d7720-5888-4587-85a2-bb1c591b335e?requestor=SFMyNTY.g2gDbQAAAAs2MC43OC43LjE3M24GAKC0MQmDAWIAAVGA.rmy7BA2sWUS2qp2udTXooa-GOABuSW_ZdvzkwGJs3IM
Logging in... done
Logged in as 自分のメールアドレスが表示される

Herokuコンテナレジストリにログイン

  • レジストリ・・・Dockerのイメージ置き場
    • ここにログインすることで、コンテナレジストリにイメージをUP出来るようになる
$ heroku container:login

Login Succeededと出ていればOK

3. Herokuアプリを作成

  • 世界中の他のアプリ名と重複できないため、アプリ名は任意で命名する
    • 今回はrails-docker-gucciという名に:sunglasses:
$ heroku create アプリ名
terminal
(base) sample@SampleMBP rails_docker % heroku create rails-docker-gucci
Creating ⬢ rails-docker-gucci... done
https://rails-docker-gucci.herokuapp.com/ | https://git.heroku.com/rails-docker-gucci.git

4. DBの追加 ・ 設定

追加

  • Herokuではデータベースをアドオンという形で作成する
    • MySQLの場合、アドオンはいくつか存在するが、cleardb:igniteというプランだけ無料
    • 無料なのはMySQLバージョン5系
      • 本来はローカルのSQL(Dockerfileに記載されている)とバージョンを揃えた方が良いが、今回はバージョン違いで困ることがないのでそのまま実行
$ heroku addons:create cleardb:ignite -a アプリ名
  • -aはアプリの略
terminal
(base) sample@SampleMBP rails_docker % heroku addons:create cleardb:ignite -a rails-docker-gucci
Creating cleardb:ignite on ⬢ rails-docker-gucci... free
Created cleardb-asymmetrical-43068 as CLEARDB_DATABASE_URL
Use heroku addons:docs cleardb to view documentation

設定

  • railsの接続先を変えておく
    • productionのデータベースの接続先情報は環境変数にして渡してあげる
    • 環境変数にすることで、ソースコードにデータベースの接続先情報を載せなくて済む&接続先を環境毎にも切り替えられる
修正前database.yml
production:
  <<: *default
  database: app_production
  username: app
  password: <%= ENV['APP_DATABASE_PASSWORD'] %>
修正後database.yml
production:
  <<: *default
  database: <%= ENV['APP_DATABASE'] %>
  username: <%= ENV['APP_DATABASE_USERNAME'] %>
  password: <%= ENV['APP_DATABASE_PASSWORD'] %>
  host: <%= ENV['APP_DATABASE_HOST'] %>

データベースの接続先情報の確認

$ heroku config -a アプリ名
terminal
(base) sample@SampleMBP rails_docker % heroku config -a rails-docker-gucci
=== rails-docker-gucci Config Vars
CLEARDB_DATABASE_URL: mysql://b659fc19e4d6cb:3adea8dc@us-cdbr-east-06.cleardb.net/heroku_6a7fdff24c98449?reconnect=true
  • 仕組み
    • mysql://ユーザ名:パスワード@ホスト名/データベース名?reconnect=true

確認した接続先情報を環境変数に設定していく

heroku config:addと打つことで、環境変数を登録できる

$ heroku config:add APP_DATABASE='heroku_6a7fdff24c98449' -a rails-docker-gucci
$ heroku config:add APP_DATABASE_USERNAME='b659fc19e4d6cb' -a rails-docker-gucci
$ heroku config:add APP_DATABASE_PASSWORD='3adea8dc' -a rails-docker-gucci
$ heroku config:add APP_DATABASE_HOST='us-cdbr-east-06.cleardb.net' -a rails-docker-gucci

環境変数が設定できているか確認

$ heroku config -a アプリ名
terminal
(base) sample@SampleMBP rails_docker % heroku config -a rails-docker-gucci
=== rails-docker-gucci Config Vars
APP_DATABASE:          heroku_6a7fdff24c98449
APP_DATABASE_HOST:     us-cdbr-east-06.cleardb.net
APP_DATABASE_PASSWORD: 3adea8dc
APP_DATABASE_USERNAME: b659fc19e4d6cb
CLEARDB_DATABASE_URL:  mysql://b659fc19e4d6cb:3adea8dc@us-cdbr-east-06.cleardb.net/heroku_6a7fdff24c98449?reconnect=true

5. Dockerfileを本番環境用に修正

アプリケーションディレクトリ直下にstart.shというファイルを作成

$ cd ~/Documents/rails_docker/
$ touch start.sh

Dockerfileを修正

  • 環境変数設定
  • start.shの設定を記述
Dockerfile
# Rubyの2.7.5を使用
FROM ruby:2.7.5

# 環境変数設定
ENV RAILS_ENV=production

# 必要なライブラリをインストール
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
  # nodejsとyarnをインストールするために必要なライブラリのアップデート関連
  && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
  && apt-get update -qq \
  && apt-get install -y nodejs yarn # nodejsとyarnをインストールしている

# 今回は作業ディレクトリを/appとする
WORKDIR /app

# ローカルの./src(railsのソースコードを入れる場所)以下のソースコードを/app配下にコピー
COPY ./src /app

# RubyのGemfileを一括インストール
RUN bundle config --local set path 'vendor/bundle' \
  && bundle install

# ローカルのstart.shをDocker側にコピー
COPY start.sh /start.sh
# 実行権限を付与
RUN chmod 744 /start.sh
# start.shを実行
CMD ["sh", "/start.sh"]

start.shに記載

start.sh
#!/bin/sh

if [ "${RAILS_ENV}" = "production" ]
then
  bundle exec rails assets:precompile
fi

bundle exec rails s -p ${PORT:-3000} -b 0.0.0.0

解説

  • #!/bin/sh・・・start.shはシェルスクリプトなので1行目に記載する
  • if [ "${RAILS_ENV}" = "production" ]・・・${RAILS_ENV}がproductionの時(本番環境の時だけ実行したい)
  • bundle exec rails assets:precompileを実行(ローカルでは必要ないが、本番ではこのコマンドを実行する必要がある)
    • ※ rails特有の事情・・・cssやjsのファイルをひとまとめにしてからhtmlで一発で読み込めるようにしている
      • そのための仕組みがassets:precompileで、ローカルと本番だとここの挙動が違い、本番ではこのコマンドを実行しなければならない
  • bundle exec rails s・・・Railsサーバを起動
  • ${PORT:-3000}・・・環境変数でPORTの値が入っていたらそれを使い、何も設定がなかった時は3000番ポートを使用
  • -b 0.0.0.0・・・バインドでIPアドレスを設定。0.0.0.0はどこからのIPアドレスでもOK

このように、環境特有の処理を入れる時はDockerfileに設定を書き、シェルスクリプトを作成し条件分岐させる


環境変数を追加

  • assets:precompileが本番で起動するようになる
$ heroku config:add RAILS_SERVE_STATIC_FILES='true' -a アプリ名

Boot Timeoutの秒数を増やす

  • Herokuをデプロイした時にポート番号をサーバがバインドする
    • その時にデフォルトで60秒で設定されている
      • 無料枠だとマシンパワーが弱く、60秒だとバインドできずにエラーとなることがよくある

https://tools.heroku.support/limits/boot_timeout
スクリーンショット 2022-09-23 15.50.10.png
Change Boot Timeoutボタン押下


ローカルのwebサーバを削除しておく

ローカルでwebサーバが起動しているとHerokuでwebサーバが起動しないことがあるため

$ docker-compose down
$ rm src/tmp/pids/server.pid

docker-compose downを行えばsrc/tmp/pids/server.pidも削除されるはずだが、これが残っているとHerokuでエラーとなってしまうため念のため実行する

6. Dockerイメージをビルド ・ リリース

Dockerイメージをビルドし、コンテナレジストリに上げたイメージからHeroku上にDockerコンテナをリリース

$ docker buildx build . --platform linux/amd64 -t 任意のタグ名/アプリ名
$ docker tag タグ名/アプリ名:latest registry.heroku.com/アプリ名/web
$ docker push registry.heroku.com/アプリ名/web
$ heroku container:release web -a アプリ名
$ docker buildx build . --platform linux/amd64 -t gucci/rails-docker-gucci:latest
$ docker tag gucci/rails-docker-gucci:latest registry.heroku.com/rails-docker-gucci/web
$ docker push registry.heroku.com/rails-docker-gucci/web
$ heroku container:release web -a rails-docker-gucci

マイグレーション

$ heroku run bundle exec rake db:migrate RAILS_ENV=production -a アプリ名
(base) sample@SampleMBP rails_docker % heroku run bundle exec rake db:migrate RAILS_ENV=production -a rails-docker-gucci
Running bundle exec rake db:migrate RAILS_ENV=production on ⬢ rails-docker-gucci... up, run.5914 (Free)

リリースしたHerokuのアプリを開く

$ heroku open -a アプリ名

🎉🎉🎉エラーが出ていなければデプロイ成功!!🎉🎉🎉


herokuでエラーになった時の対策

  • 環境変数を設定
$ heroku config:add RAILS_LOG_TO_STDOUT='true' -a アプリ名
  • herokuのログを出力
    • FATALなどの情報を見てググり、エラーを解決していく
$ heroku logs -t -a アプリ名

7. おまけ(機能追加する際の手順)

開発用サーバを立ち上げる

$ docker-compose up -d

Controller作成

$ docker-compose exec web bundle exec rails g controller homes

ルーティングを設定

config/routes.rb
Rails.application.routes.draw do
  root 'homes#top'
end

コントローラにアクションを定義

app/controller/homes_controller.rb
class HomesController < ApplicationController
  def top
  end
end

Viewファイル作成

  • 綺麗なトップページにしたいので今回はVanta.jsを使用 ※任意

app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>App</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>
app/views/homes/top.html.erb
<div id="bird">
  <div class="main-visual">
    <h1>Congratulations on your deployment!!</h1>
    <h2>created user : Ryo.S</h2>
  </div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r121/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.birds.min.js"></script>
<script>
  VANTA.BIRDS({
    el: "#bird",
    mouseControls: true,
    touchControls: true,
    gyroControls: false,
    minHeight: 970.00,
    minWidth: 200.00,
    scale: 1.00,
    scaleMobile: 1.00,
    backgroundColor: 0x22652,
    color1: 0x91243d,
    color2: 0x1bc1fa,
    birdSize: 1.20,
    wingSpan: 33.00,
    speedLimit: 7.00,
    separation: 31.00,
    alignment: 26.00,
    cohesion: 17.00
  })
</script>
assets/stylesheets/homes.scss
body {
  margin: 0;
}
.main-visual {
  text-align: center;
  color: transparent;
	background: linear-gradient(45deg, #B67B03 0%, #DAAF08 45%, #FEE9A0 70%, #DAAF08 85%, #B67B03 90% 100%);
	-webkit-background-clip: text;
  width: auto;
  padding-top: 100px;
  padding-right: 30px;
  padding-left: 30px;
  font-size: 35px;
  font-style: italic;
  font-family: Times New Roman, "MS Pゴシック";
}

ブラウザで動作確認(ローカル)


Herokuに反映させる

$ docker-compose down
$ rm src/tmp/pids/server.pid
$ docker buildx build . --platform linux/amd64 -t gucci/rails-docker-gucci:latest
$ docker tag gucci/rails-docker-gucci:latest registry.heroku.com/rails-docker-gucci/web
$ docker push registry.heroku.com/rails-docker-gucci/web
$ heroku container:release web -a rails-docker-gucci
$ heroku open -a rails-docker-gucci

その他よく使うコマンド

  • アプリケーション起動コマンド
$ heroku ps:scale web=1 -a アプリ名

  • アプリケーション停止コマンド
$ heroku ps:scale web=0 -a アプリ名

  • 起動停止確認コマンド
    • upなら起動中
    • No dynos onが表示されていたら停止中
$ heroku ps -a アプリ名

  • お掃除コマンド
$ docker system prune

NextStep

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0