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
(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
という名に
- 今回は
$ heroku create アプリ名
(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に記載されている)とバージョンを揃えた方が良いが、今回はバージョン違いで困ることがないのでそのまま実行
- MySQLの場合、アドオンはいくつか存在するが、
$ heroku addons:create cleardb:ignite -a アプリ名
-
-a
はアプリの略
(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のデータベースの接続先情報は環境変数にして渡してあげる
- 環境変数にすることで、ソースコードにデータベースの接続先情報を載せなくて済む&接続先を環境毎にも切り替えられる
production:
<<: *default
database: app_production
username: app
password: <%= ENV['APP_DATABASE_PASSWORD'] %>
production:
<<: *default
database: <%= ENV['APP_DATABASE'] %>
username: <%= ENV['APP_DATABASE_USERNAME'] %>
password: <%= ENV['APP_DATABASE_PASSWORD'] %>
host: <%= ENV['APP_DATABASE_HOST'] %>
データベースの接続先情報の確認
$ heroku config -a アプリ名
(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 アプリ名
(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の設定を記述
# 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に記載
#!/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
で、ローカルと本番だとここの挙動が違い、本番ではこのコマンドを実行しなければならない
- そのための仕組みが
- ※ rails特有の事情・・・cssやjsのファイルをひとまとめにしてからhtmlで一発で読み込めるようにしている
-
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秒だとバインドできずにエラーとなることがよくある
- その時にデフォルトで60秒で設定されている
https://tools.heroku.support/limits/boot_timeout
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
ルーティングを設定
Rails.application.routes.draw do
root 'homes#top'
end
コントローラにアクションを定義
class HomesController < ApplicationController
def top
end
end
Viewファイル作成
- 綺麗なトップページにしたいので今回はVanta.jsを使用 ※任意
<!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>
<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>
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