💪

【Rails7】DockerでRuby on Railsアプリを構築してHerokuにデプロイするまで

2022/01/06に公開
2

こんにちは!@hisaya_sugitaです!
今回は、DockerでRuby on Railsアプリを構築してHerokuにデプロイするまでの手順を解説を交えながら(備忘録も兼ねて)記事に残したいと思います。

環境

今回使用する環境は下記の通りです。

  • Docker
  • Ruby: 3.0.2
  • Rails 7.0.1
  • Node.js: 15.x

必要なファイルの用意

1. Railsアプリの作成

まずはRailsアプリを作るために必要なファイルを作成します。
この部分は本題と逸れるのでサクッと説明します。

$ mkdir my-app
$ cd my-app
$ bundle init
Writing new Gemfile to /path/to/my-app/Gemfile

Gemfileができるので、Railsをインストールするように編集します。

Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

gem "rails", "~> 7.0.0"

次にbundle installを実行してGemfile.lockを生成します。

$ bundle install --path vendor/bundle

rails newをしてRailsアプリの雛形を作ります。
※ databaseにpostgresqlを指定していますが、MySQLを使用する場合はmysqlを指定してください。

$ echo y | bundle exec rails new . -d postgresql --skip-bundle --skip-turbolinks --skip-system-test

このままだとHerokuにデプロイした際にBlocked hostエラーが発生するので、config/environments/development.rbに下記を追記します。

config/environments/development.rb
Rails.application.configure do
  ...
  config.hosts.clear
end

2. Dockerfile

Dockerfile
FROM ruby:3.0.2

RUN set -x \
  && curl -sL https://deb.nodesource.com/setup_15.x | bash - \
  && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
  && 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 --no-install-recommends \
    build-essential \
    libpq-dev libxslt-dev libxml2-dev \
    nodejs yarn \
    curl vim sudo cron \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/* \
  && rm -rf /var/cache/yum/*

# set environment variables
ENV LANG C.UTF-8
ENV APP_ROOT /app
ENV BUNDLE_JOBS 4
ENV BUNDLER_VERSION 2.2.25

# working on app root
RUN mkdir /app
WORKDIR $APP_ROOT
COPY Gemfile $APP_ROOT/Gemfile
COPY Gemfile.lock $APP_ROOT/Gemfile.lock
RUN gem install bundler -v $BUNDLER_VERSION
RUN bundle -v
RUN bundle install
COPY . $APP_ROOT

# execute script after build container
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

補足

たくさんインストールしてますが、この辺はお好みで。

RUN set -x \
  && curl -sL https://deb.nodesource.com/setup_15.x | bash - \
  && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
  && 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 --no-install-recommends \
    build-essential \
    libpq-dev libxslt-dev libxml2-dev \
    nodejs yarn \
    curl vim sudo cron \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/* \
  && rm -rf /var/cache/yum/*

今回はentrypoint.shでゴニョゴニョやりたいので、ENTRYPOINTを設定しています。

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

3. entrypoint.sh

entrypoint.sh
#!/bin/bash

set -ex
rm -f /app/tmp/pids/server.pid

if [ $RAILS_ENV = 'production' ]; then
  bundle exec rails assets:clobber
  bundle exec rails assets:precompile
fi

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

Heroku公式にも書いてありますが、HerokuにDockerイメージをデプロイする場合は環境変数(PORT)からポート番号を取得する必要があります。

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

4. 確認

ここまでで作成したファイルを確認します。

$ tree -L 1 -a
.
├── .bundle
├── .git
├── .gitattributes
├── .gitignore
├── .ruby-version
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── README.md
├── Rakefile
├── app
├── bin
├── config
├── config.ru
├── db
├── entrypoint.sh
├── lib
├── log
├── public
├── storage
├── test
├── tmp
└── vendor

Herokuへのデプロイの準備

次にHerokuへのデプロイの準備をしていきます。

1. herokuコマンドのインストール

herokuコマンドがインストールされていない場合は、インストールします。

$ brew tap heroku/brew && brew install heroku

詳細は公式サイトを参照してください。

2. heroku-cliにログイン

$ heroku login

3. Herokuでアプリを新規作成

$ heroku create my-app

4. DB用のアドオンを追加

PostgreSQLの場合

無料のHobby Devを利用します。

$ heroku addons:create heroku-postgresql:hobby-dev

Herokuアプリ内に環境変数DATABASE_URLが自動で設定されます。

MySQLの場合

無料のigniteを利用。

$ heroku addons:create cleardb:ignite
$ heroku config
CLEARDB_DATABASE_URL: mysql://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true

$ heroku configを確認するとCLEARDB_DATABASE_URLという環境変数が追加されるので、その値を環境変数DATABASE_URLとして設定します。

※ Herokuでは(Rails 4.1 以上の場合)config/database.ymlの内容は全て無視され、DATABASE_URLからDBの接続情報が読み込まれます。参考1参考2)。

$ heroku config:add DATABASE_URL='mysql://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true'

mysql2を使っている場合は下のように設定しないとエラーになります。

$ heroku config:add DATABASE_URL='mysql2://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true'

5. 作成したファイルをコミット

$ bundle lock --add-platform x86_64-linux # MacOSを使用している場合
$ git add .
$ git commit -m "create rails app"

Herokuへのデプロイと動作確認

1. アプリをHerokuにデプロイ

$ git push heroku main

2. 動作確認

$ heroku open

画像のように表示されればOKです🎉
ここまでやりきれてすごい!!!お疲れ様でした!

参考資料

https://devcenter.heroku.com/ja/categories/deploying-with-docker
https://qiita.com/kodai_0122/items/67c6d390f18698950440

Discussion

LeoLeo

2回目以降のデプロイに関して質問

お陰様で手順通りデプロイすることができました。ありがとうございます。
ただ、2回目以降のデプロイでソースコードが反映されません。

ソースを反映させた場合のデプロイ手順を教えていただきたいです。

以下試したこと

vendor/bundle/ruby/3.0.0/gems/railties-7.0.1/lib/rails/templates/rails/welcome/index.html.erb

  <ul>
    <li><strong>Rails version:</strong> <%= Rails.version %></li>
    <li><strong>Ruby version:</strong> <%= RUBY_DESCRIPTION %></li>
    ####### 以下一行を追加 
    <li><strong>hoge</strong></li>
  </ul>
</body>
git add .
git commit -m 'test edit'
git push heroku main

この状態で、デプロイ自体は完了(成功)しているように見えるのですが、

https://{app_name}.herokuapp.com/

にアクセスしてもhogeの文字が表示されておりませんでした。(リロードもしました。)
他に必要な手順がありましたらご教授いただきたいです。

Hisaya SugitaHisaya Sugita

コメントありがとうございます。
お返事が遅くなってしまい、申し訳ありません🙇‍♂️

もしまだ上記の問題で悩んでいるようでしたら、下記のコマンドを実行してから再度デプロイしてみてください。

$ heroku stack:set heroku-20