Railsチュートリアルをカスタマイズしてポートフォリオを作成する方法【Docker・Rails7・CircleCI対応】


 

こんにちは。Tomoyuki(@tomoyuki65)です。

別の記事にてRailsチュートリアルを完了したことはお伝えしましたが、次のステップとしてはRubyやRails、そしてGemのバージョンを上げたりしつつ、最新の技術も取り入れながら、Railsチュートリアルベースのアプリを作ってポートフォリオの一つとして使えたらと考えました。

そこでこの記事では、2022年7月時点で最新のRials7にアップグレードし、Railsチュートリアルベースのアプリをカスタムしていく方法をまとめておきます。

 

関連記事👇

35歳、Railsチュートリアルに挑む編【Web系エンジニア1年目】

2022年7月17日

 



目次

Railsチュートリアルをカスタマイズしてポートフォリオを作成する方法【Docker・Rails7・CircleCI対応】

Rails7からはアセット周りの仕様が色々変わっているため、まずは①Rails7のデフォルト設定でDockerによる開発環境を構築する方法と、②Rails7とBootstrapでDockerによる開発環境を構築する方法をまとめます。

※ある程度Dockerを使ったことがある人向けの内容なので、Dockerのことがよくわからない方はまずそちらを調べてみて下さい。

 

①Rails7のデフォルト設定でDockerによる開発環境を構築する方法

まず、以下のコマンドを実行し、必要なファイルを作成します。

$ mkdir ディレクトリ名
$ cd ディレクトリ名
$ touch Dockerfile
$ touch entrypoint.sh
$ touch Gemfile
$ touch Gemfile.lock
$ touch db.env
$ touch docker-compose.yml

※ディレクトリ名は任意の名前を付けて下さい(例:sample_appなど)

 

次に各ファイルの中身を記載します。

# 2022年7月時点の最新安定版のRuby
FROM ruby:3.1.2

# railsコンソール中で日本語入力するための設定
ENV LANG=C.UTF-8

# 本番環境用のRAILS_ENV設定
ENV RAILS_ENV=production
# bundlerのバージョンを固定するための設定
ENV BUNDLER_VERSION=2.3.10

# インストール可能なパッケージ一覧の更新
RUN apt-get update -qq \
    # パッケージのインストール(-yは全部yesにするオプション)
    # コンパイラに必要なパッケージ、PostgreSQLのクライアント
    # PostgreSQLの接続に必要なパッケージをインストール
    # chromium-driverはRSpecのシステムスペック用に必要
    # credentials.yml.encの編集用にvimが必要
    && apt-get install build-essential \
                       postgresql-client \
                       libpq-dev \
                       chromium-driver \
                    -y vim-gtk \
    # キャッシュを削除して容量を小さくする
    && rm -rf /var/lib/apt/lists/*

# 作業ディレクトリの指定
RUN mkdir /ディレクトリ名
WORKDIR /ディレクトリ名

# ローカルにあるGemfileとGemfile.lockを
# コンテナ内のディレクトリにコピー
COPY Gemfile /ディレクトリ名/Gemfile
COPY Gemfile.lock /ディレクトリ名/Gemfile.lock

# bundlerのバージョンを固定する
RUN gem install bundler -v $BUNDLER_VERSION
RUN bundle -v

# bunlde installを実行する
RUN bundle install --jobs=4
COPY . /ディレクトリ名

# コンテナ起動時に実行するスクリプト
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]

※ディレクトリ名は任意の名前に修正して下さい。そして、RSpec用にchromium-driverもインストールしておきます。また、Rails7のデフォルト設定ではnodejs、npm、yarnなどは使わない仕様(インストール不要)になってます。そのほか、本番環境用の環境変数にRAILS_ENVを設定していますが、docker-composeを起動した場合はdocker-composeで定義した環境変数のRAILS_ENVの値が優先されます。最後に、本番環境用にCMDはpumaコマンドにしています。(rails sでもpumaは起動するが、本番環境のHerokuでpumaを使いたい場合、明示的にpumaを起動することが推薦されているため。)

 

#!/bin/bash
set -e
 
# Rails特有の問題を解決するためのコマンド
rm -f /ディレクトリ名/tmp/pids/server.pid

# production環境の場合のみJSとCSSをビルド
if [ "$RAILS_ENV" = "production" ]; then
  bundle exec rails assets:clobber
  bundle exec rails assets:precompile
fi

# サーバー実行(DockerfileのCMDをセット)
exec "$@"

※ディレクトリ名は任意の名前に修正して下さい。

 

source 'https://rubygems.org'
# 2022年7月時点の最新版Rails
gem 'rails', '7.0.3'

 

POSTGRES_USER=任意のユーザー名
POSTGRES_PASSWORD=任意のパスワード

※これはDBのPostgreSQLの環境変数になりますが、任意のユーザー名とパスワードを設定して下さい。また、このファイルは公開しないので「.gitignore」にファイル名を追加して下さい。

 

version: "3"
services:
  # DBの設定
  db:
    # コンテナ名の指定
    container_name: ディレクトリ名_db
    # 2022年7月時点の最新版PostgreSQL
    image: postgres:14.4
    # 環境変数の設定(db.envから読み込む)
    env_file:
      - ./db.env
    # データの永続化(ローカルのtmp/dbディレクトリにマウント)
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  # アプリの設定
  web:
    # コンテナ名の指定
    container_name: ディレクトリ名_web
    # Dockerfileのあるディレクトリパスを指定
    build: .
    # 環境変数の設定(db.envから読み込む)
    env_file:
      - ./db.env
    # 開発環境のRAILS_ENVはdevelopmentを設定
    environment:
      - RAILS_ENV=development
    # コマンド実行(Rails特有の問題解決とRailsの立ち上げ)
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    # データの永続化(ローカルのカレントディレクトリにマウント)
    volumes:
      - .:/ディレクトリ名
    # ポートの指定(外部からアクセス時のポート:コンテナからアクセス時のポート)
    ports:
      - "3000:3000"
    # 標準入出力デバイスを設定(bin/devを使う場合は必須)
    tty: true
    stdin_open: true
    # 依存関係の指定(dbが起動した後に、webが起動する)
    depends_on:
      - db

※ディレクトリ名は任意の名前に修正して下さい。

 

次にRailsのアプリケーションの生成を行います。

$ docker-compose run web rails new . --force --database=postgresql

※DBはPostgreSQLを使うオプションを付けてます。

 

次にconfig/database.ymlのデフォルト設定に、PostgreSQLのユーザー名とパスワードを環境変数(db.envで設定した値)から読み取るように修正します。

  ・
  ・
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # https://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  # 以下の3行を追加
  username: <%= ENV["POSTGRES_USER"] %>
  password: <%= ENV["POSTGRES_PASSWORD"] %>
  host: db
  ・
  ・

 

次にイメージのビルドとコンテナの起動を行います。

$ docker-compose build --no-cache
$ docker-compose up -d
$ docker-compose ps

 

起動したコンテナのSTATUSが「running」になってればOKです。

 

次にDBの作成とRailsアプリケーションの表示確認を行います。

$ docker-compose exec web rails db:create

 

以下のようなRailsのトップ画面が表示されればOKです。

 

②Rails7とBootstrapでDockerによる開発環境を構築する方法

次はRails7とBootstrap(バージョンは5になると思います)でDockerによる開発環境を構築する方法になりますが、Railsチュートリアルベースのアプリを作るならこちらの方法が合っているのかなと思います。

まず、以下のコマンドを実行し、必要なファイルを作成します。

$ mkdir ディレクトリ名
$ cd ディレクトリ名
$ touch Dockerfile
$ touch entrypoint.sh
$ touch Gemfile
$ touch Gemfile.lock
$ touch db.env
$ touch docker-compose.yml

※ディレクトリ名は任意の名前を付けて下さい(例:sample_appなど)

 

次に各ファイルの中身を記載します。

# 2022年7月時点の最新安定版のRuby
FROM ruby:3.1.2

# railsコンソール中で日本語入力するための設定
ENV LANG C.UTF-8

# 本番環境用のRAILS_ENV設定
ENV RAILS_ENV=production
# bundlerのバージョンを固定するための設定
ENV BUNDLER_VERSION 2.3.10

# インストール可能なパッケージ一覧の更新
RUN apt-get update -qq \
    # パッケージのインストール(-yは全部yesにするオプション)
    # コンパイラに必要なパッケージ、PostgreSQLのクライアント
    # PostgreSQLの接続に必要なパッケージをインストール
    # chromium-driverはRSpecのシステムスペック用に必要
    # credentials.yml.encの編集用にvimが必要
    # Bootstrapを利用する場合はnodejsとnpmとyarnが必要
    && apt-get install build-essential \
                       postgresql-client \
                       libpq-dev \
                       chromium-driver \
                    -y vim-gtk \
                    -y nodejs \
                       npm \
    # キャッシュを削除して容量を小さくする
    && rm -rf /var/lib/apt/lists/* \
    # yarnをインストール
    && npm install --global yarn

# 作業ディレクトリの指定
RUN mkdir /ディレクトリ名
WORKDIR /ディレクトリ名

# ローカルにあるGemfileとGemfile.lockを
# コンテナ内のディレクトリにコピー
COPY Gemfile /ディレクトリ名/Gemfile
COPY Gemfile.lock /ディレクトリ名/Gemfile.lock

# bundlerのバージョンを固定する
RUN gem install bundler -v $BUNDLER_VERSION
RUN bundle -v

# bunlde installを実行する
RUN bundle install --jobs=4
COPY . /ディレクトリ名

# コンテナ起動時に実行するスクリプト
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]

※ディレクトリ名は任意の名前に修正して下さい。そして、Bootstrapを使う場合はnodejs、npm、yarnのインストールも必要です。加えて、RSpec用にchromium-driverもインストールしておきます。そのほか、本番環境用の環境変数にRAILS_ENVを設定していますが、docker-composeを起動した場合はdocker-composeで定義した環境変数のRAILS_ENVの値が優先されます。最後に、本番環境用にCMDはpumaコマンドにしています。(rails sでもpumaは起動するが、本番環境のHerokuでpumaを使いたい場合、明示的にpumaを起動することが推薦されているため。)

 

#!/bin/bash
set -e
 
# Rails特有の問題を解決するためのコマンド
rm -f /ディレクトリ名/tmp/pids/server.pid

# production環境の場合のみJSとCSSをビルド
if [ $RAILS_ENV = "production" ]; then
  bundle exec rails assets:clobber
  bundle exec rails assets:precompile
fi

# サーバー実行(DockerfileのCMDをセット)
exec "$@"

※ディレクトリ名は任意の名前に修正して下さい。

 

source 'https://rubygems.org'
# 2022年7月時点の最新版Rails
gem 'rails', '7.0.3'

 

POSTGRES_USER=任意のユーザー名
POSTGRES_PASSWORD=任意のパスワード

※これはDBのPostgreSQLの環境変数になりますが、任意のユーザー名とパスワードを設定して下さい。また、このファイルは公開しないので「.gitignore」にファイル名を追加して下さい。

 

version: "3"
services:
  # DBの設定
  db:
    # コンテナ名の指定
    container_name: ディレクトリ名_db
    # 2022年7月時点の最新版PostgreSQL
    image: postgres:14.4
    # 環境変数の設定(db.envから読み込む)
    env_file:
      - ./db.env
    # データの永続化(ローカルのtmp/dbディレクトリにマウント)
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  # アプリの設定
  web:
    # コンテナ名の指定
    container_name: ディレクトリ名_web
    # Dockerfileのあるディレクトリパスを指定
    build: .
    # 環境変数の設定(db.envから読み込む)
    env_file:
      - ./db.env
    # 開発環境のRAILS_ENVはdevelopmentを設定
    environment:
      - RAILS_ENV=development
    # コマンド実行(Rails特有の問題解決とRailsの立ち上げ。Bootstrapを使う場合はbin/devで起動)
    command: bash -c "rm -f tmp/pids/server.pid && bin/dev"
    # データの永続化(ローカルのカレントディレクトリにマウント)
    volumes:
      - .:/ディレクトリ名
    # ポートの指定(外部からアクセス時のポート:コンテナからアクセス時のポート)
    ports:
      - "3000:3000"
    # 標準入出力デバイスを設定(bin/devを使う場合は必須)
    tty: true
    stdin_open: true
    # 依存関係の指定(dbが起動した後に、webが起動する)
    depends_on:
      - db

※ディレクトリ名は任意の名前に修正して下さい。

 

次にRailsのアプリケーションの生成を行います。

$ docker-compose run web rails new . --force --database=postgresql --css=bootstrap

※DBはPostgreSQL、CSSはBootstrapを使うオプションを付けてます。

 

次にconfig/database.ymlのデフォルト設定に、PostgreSQLのユーザー名とパスワードを環境変数(db.envで設定した値)から読み取るように修正します。

  ・
  ・
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # https://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  # 以下の3行を追加
  username: <%= ENV["POSTGRES_USER"] %>
  password: <%= ENV["POSTGRES_PASSWORD"] %>
  host: db
  ・
  ・

 

次にRails7にBootstrapなどを導入した場合、開発環境では通常の「rails s」ではなく「bin/dev」でサーバーを起動する必要があるため、Procfile.devの「web: bin/rails server -p 3000」に「-b 0.0.0.0」を追加します。

web: bin/rails server -p 3000 -b 0.0.0.0
js: yarn build --watch
css: yarn build:css --watch

 

次にイメージのビルドとコンテナの起動を行います。

$ docker-compose build --no-cache
$ docker-compose up -d
$ docker-compose ps

 

起動したコンテナのSTATUSが「running」になってればOKです。

 

次にDBの作成とRailsアプリケーションの表示確認を行います。

$ docker-compose exec web rails db:create

 

以下のようなRailsのトップ画面が表示されればOKです。

 

Dockerでの環境構築が上手くいかない場合に使うコマンドまとめ

docker-composeのログを確認

$ docker-compose logs

 

docker-composeで起動中のコンテナ一覧の表示

$ docker-compose ps

 

docker-composeで起動中のコンテナの停止と削除

$ docker-compose down

 

dockerに保存されたイメージの一覧を表示

$ docker images

 

対象のイメージを削除

$ docker rmi イメージID

 

使用していないイメージを全て削除(コマンド実行後、yを入力して削除)

$ docker image prune

 

dockerに保存されたボリュームの一覧を表示

$ docker volume ls

 

ボリュームの削除

$ docker volume rm ボリューム名

 

使用していないボリュームの削除(コマンド実行後、yを入力して削除)

$ docker volume prune

 

dockerの容量の利用状況の一覧を表示

$ docker system df

 

dockerのビルドキャッシュを削除(コマンド実行後、yを入力して削除)

$ docker builder prune

 

gitで追跡中かつまだaddしていないファイルの変更を戻す

$ git checkout .

 

gitでまだ追跡していないディレクトリとファイルを削除

$ git clean -df

 

Railsチュートリアルを進めてみる

ここまででDockerによるRails7環境を構築する手順を2つご紹介しましたが、これでRailsチュートリアルの内容を進めていける最低限の準備は整ったかなと思います。

ただし、Railsチュートリアルの内容を進める際は、必要に応じてGemの種類やバージョンを変えたり、別の実装方法を検討する必要があると思うので、そこはちょっと難易度が高い部分かなと思います。

ただ自分で調べてRailsチュートリアルベースのアプリを作成できれば、また一歩大きな成長につながると思いますし、カスタマイズ次第でポートフォリオに使えると思うので、興味がある方はぜひチャレンジしてみて下さい。

 



DockerのRails環境をHerokuにデプロイする方法

ここでは本番環境のHerokuにDockerのRailsアプリをデプロイする方法をまとめます。

※以下ではHerokuにログインしてコマンドが使える状態を前提にしています。

 

Herokuは2022年11月28日より無料プランが廃止になります!

Herokuは2022年11月28日より無料プランが廃止されるため、学習用途で使おうとしている方は注意が必要です。有料プランで使う場合は問題ありませんが、本番環境を無料で使って学習を進めたい方は別のサービスなどに移行が必要です。

今までのHerokuの様に全て無料でいい感じに使えるわけではありませんが、近いサービスとして「Render.com」があるため、下記「DockerのRailsアプリをRender.comにデプロイする方法まとめ」に簡単な使い方をまとめておきます。興味がある方は参考にしてみて下さい。

 

まず、本番環境のHerokuではWebサーバーとしてpumaを使用するため、config/puma.rbの設定で、「workers ENV.fetch(“WEB_CONCURRENCY”) { 2 }」と「preload_app!」のコメントを外して有効化します。

※HerokuでWebサーバーにpumaを使いたい場合、通常ならProcfileを作成してこのファイルにpumaコマンドを記述しますが、DockerのRails環境をHerokuにデプロイする場合はProcfileは読み込まれない(Docker環境では作成不要です)ため、Dockerfileの中でpumaコマンドを実行する必要があります。

 

次にHerokuにアプリを作成します。

$ heroku create アプリ名

 

次に作成したアプリに環境変数として「RAILS_ENV」、「RAILS_MASTER_KEY」、「RAILS_SERVE_STATIC_FILES」の値を設定します。

$ heroku config:set RAILS_ENV=production
$ heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
$ heroku config:set RAILS_SERVE_STATIC_FILES=true

※RAILS_SERVE_STATIC_FILESはアセットコンパイルしたファイルを読み込むのに必要です。

 

次にHerokuのContainerにログインし、DB(PostgreSQLのアドオン)を追加後、アプリのコンテナのプッシュとリリース、そしてマイグレーションを実行します。

$ heroku container:login
$ heroku addons:create heroku-postgresql:hobby-dev
$ heroku container:push web
$ heroku container:release web
$ heroku run rails db:migrate

 

これでHeroku上で公開されているため、以下のコマンドを実行すればブラウザが開いて確認できます。

$ heroku open

 

尚、HerokuではRailsの初期画面は表示できないため、デプロイ前にroot_pathで「hello, world!」などを表示できるように修正しておいて下さい。

 

本番環境でSSLを使う場合

本番環境でSSLを使う場合は、config/environments/production.rbの「config.force_ssl=true」のコメントを外して有効化して下さい。

 

RailsとHerokuのタイムゾーンを日本にする方法

RailsのデフォルトのタイムゾーンはUTCになっており、そのままだとDBの更新日時にはUTCの時間が設定されます。

Railsのタイムゾーンを日本にするには、config/application.rbに以下の設定を追加します。

module アプリ名
  classApplication < Rails::Application
    〜 省略 〜

    # タイムゾーン設定を日本にする
    config.time_zone = "Asia/Tokyo"
    config.active_record.default_timezone = :local
  end
end

 

そして、本番環境であるHerokuのタイムゾーンを変更するには、以下のコマンドを実行して環境変数を設定します。

$ heroku config:add TZ=Asia/Tokyo

 

DockerのRails環境にRSpecを導入する方法

ここではDockerのRails環境にRSpecを導入する方法についてまとめます。

まずは、GemfileにRSpec用のGemを追加します。

# 以下のGemを「group :development, :test」内に追加
gem "rspec-rails"
gem "factory_bot_rails"

# 以下のGemを「group :test」内に追加
gem 'launchy'
gem 'shoulda-matchers'

※factoru_bot_rails(テストデータ作成用)、launchy(save_and_openメソッドで保存されるHTMLを自動で開く用)、shoulda-matchers(簡潔なテストコードを書く用)

 

次にコンテナの再ビルドを行い、コンテナを起動します。

$ docker-compose build --no-cache
$ docker-compose up -d

 

次にRSpecをインストールします。

$ docker-compose exec web rails g rspec:install

 

次にMinitest用の「/test」を削除します。

$ rm -rf test

 

次にRSpecの初期設定として、「.rspec」に「–color」と「–format documentation」を追加します。

--require spec_helper
--color
--format documentation

 

次にbinstubの設定(短いコマンドで実行できるようにする)を行います。

$ docker-compose exec web bundle binstubs rspec-core

 

次に不要なスペックがたくさん作られないようにするため、config/application.rbにジェネレータの設定を追加します。

module RtC2207
  class Application < Rails::Application
  ・
  ・
    # ジェネレータの設定を追加
    config.generators do |g|
      g.test_framework :rspec,
        fixtures: false,
        view_specs: false,
        routing_specs: false
      end
    end
  ・
  ・
  end
end

 

次にRSpec関連の設定ファイルを追加するため、まずはspec/rails_helper.rbの「Dir[Rails.root.join(‘spec’, ‘support’, ‘**’, ‘*.rb’)].sort.each { |f| require f }」のコメントを外して有効化します。

※そのほか、docker-compose.ymlの環境変数(environment)に「RAILS_ENV=development」を設定した場合は、RSpec実行時の環境変数も「development」を読み込んでしまうため、その場合はspec/rails_helper.rbの「ENV[‘RAILS_ENV’] ||= ‘test’」を「ENV[‘RAILS_ENV’] = ‘test’」に修正して下さい。

 

次にUIテスト用の設定を追加するため、以下のコマンドを実行してspec/support直下に「capybara.rb」を作成します。

$ mkdir spec/support
$ touch spec/support/capybara.rb

 

そして、Docker環境でシステムスペックを実行できるようにするため、capybara.rbに以下の設定を追加します。

# RSpecのドライバ設定
RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :rack_test
  end

  config.before(:each, type: :system, js: true) do
    driven_by :headless_chrome
  end
end

# Docker環境用のドライバ設定を追加
Capybara.register_driver :headless_chrome do |app|
  browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts|
    opts.args << "--headless"
    opts.args << "--disable-gpu"
    opts.args << "--no-sandbox"
  end
  Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
end

 

最後に以下のコマンドを実行し、RSpecを実行して確認します。

$ docker-compose exec web bin/rspec

※binstubを設定していない場合は、コマンド「bundle exec rspec」を使います。

 

以下のように実行できればOKです。

 

テスト時に使用するコマンドまとめ

全てのRspecを実行

$ docker compose exec web bin/rspec

 

modelsのRSpecのみ実行

$ docker compose exec web bin/rspec spec/models

 

対象ファイルのRSpecのみ実行

$ docker compose exec web bin/rspec spec/models/user_spec.rb

 

対象ファイルの1行目のみRSpecを実行

$ docker compose exec web bin/rspec spec/models/user_spec.rb:1

 

対象ファイルの3〜10行目のみRSpecを実行

$ docker compose exec web bin/rspec spec/models/user_spec.rb:3:10

 

システムスペックの作成

$ docker compose exec web rails g rspec:system ファイル名

 



GitHubとCircleCIでCI/CDパイプラインを構築する方法(テストの自動化とHerokuに自動でデプロイ)

ここからはGitHubとCircleCIを連携し、CI/CDパイプラインを構築する方法をまとめます。

※以降の内容については、GitHubへのログインを済まし、かつCircleCIと連携予定のmainリポジトリの最新化(ローカルでブランチを切ってない状態も含む)をしている状態を前提としています。

 

GitHubとCircleCIを連携する方法

まずGitHubとCircleCIを連携しますが、GitHubにログイン中の状態CircleCIの公式サイトにアクセスし、「無料でビルドを開始する」をクリックします。

 

次にユーザー登録画面が表示されるので、画面右の「GitHub で登録」をクリックします。

 

次に承認画面が表示されるので、「Authorize circleci」をクリックします。

 

次にGitHubのパスワード入力画面が表示されるので、パスワードを入力後、「Confirm password」をクリックします。

 

これでGitHubとCircleCIの連携は完了です。

そのまますぐにセットアップを行う場合は上側の「Set up your code」を進め、後からセットアップをする場合は画面下の「Skip setup」をクリックして下さい。

 

CircleCIのチュートリアルを進める

次はそのままセットアップを行いますが、今回はCircleCIのチュートリアルを例に進めます。

まずSelect Organizationで対象のGitHubアカウントを選択、次にSelect Repositoryで対象のリポジトリを選択、次にSelect your config.yml fileで「Fast」をチェックし、最後に「Set Up Project」をクリックします。

尚、既に「.circleci/config.yml」を作成済みで対象のリポジトリに存在する場合は、Select your config.yml fileで「Fastest」をチェックして進めて下さい。

 

次にconfig.ymlのテンプレート選択画面が表示されるので、「Hello World」を選択します。

 

次に設定ファイルのエディター画面が表示されますが、チュートリアルとしては特に変更する必要がないため、そのまま「Commit and Run」をクリックします。

※ここでファイル内容を修正することも可能です。

 

その後、config.ymlに記載されている内容が実行され、その結果が画面に表示されます。(問題がなければStatusが「Success」になります。)

そして、連携しているGitHubのリポジトリに作成されたファイル「.circleci/config.yml」のブランチがプッシュされるので、次はGitHubを確認します。

 

GitHubを確認するとブランチがプッシュされているため、「Compare & pull request」をクリックして、マージ処理を進めます。

 

次はプルリクエスト作成のため、「Create pull request」をクリックします。

 

プルリクエスト作成後、CircleCIのチェック結果が表示されるので、問題がなければ「Merge pull request」をクリックしてマージ処理を進めます。

 

次に「Confirm merge」をクリックしてマージします。

 

マージ処理をすると、ステータスが「Merged」に変わります。

そして、マージ元のブランチは不要なので、「Delete branch」をクリックして削除します。

これでマージ処理が完了したので、マージ先のリポジトリを確認します。

 

マージ後、「.circleci/config.yml」が追加されていればOKです。

 

もう一度CircleCIの画面を確認すると、GitHubのアクションからCircleCIが実行された処理が追加されて表示されます。これでCircleCIのチュートリアルが完了です。

 

この後は以下のコマンドを実行し、ローカルのmainリポジトリを最新化して下さい。

$ git pull

 

後は「.circleci/config.yml」を上手く修正すれば、目的に応じたCI/CDパイプラインが構築できます。

 

CircleCIで「.circleci/config.yml」を修正する方法

「.circleci/config.yml」はローカルで編集することも可能ですが、最初はCircleCIから編集した方がわかりやすいと思います。

CircleCIから編集するには、対象のプロジェクトのブランチを選択(最初はmainブランチになると思います)し、画面上の「Edit Config」をクリックします。

 

次にconfig.ymlの編集画面が開き、右側にはOrbs(ジョブ、コマンド、Executorなどの共通可能な設定要素をパッケージ化したもの)などを追加するためのメニュー画面表示されます。(メニュー画面が画面右側の部分をクリックすれば閉じれます。)

 

画面右のメニューを閉じれば、そのままファイルを修正可能です。画面下の緑色の部分はLINTERの判定結果で、構文チェックなどを行なってくれます。(緑ならOK)

ファイルを修正後、保存と実行をする場合は画面右上の「Save and Run」をクリックします。

 

保存した際にまだブランチが作成されていなければ、ブランチ選択画面が表示されるので、下の「Create a new branch for this commit」にチェックが付いている状態で画面右下の「Commit Changes」をクリックすると、新しいブランチが作成され、修正したファイル「.circleci/config.yml」が連携しているGitHubのリポジトリにプッシュされます。

 

CircleCIの画面では実行したワークフローの一覧が表示されるので、Statusが「Success」になるようなコードが書ければOKです。

また、実行結果が失敗した場合はStatusが「Failed」になりますが、ステータス部分をクリックすると実行したジョブ名が表示され、それをクリックすると実行結果を確認できます。(確認→修正→保存&実行→実行結果確認→・・・のようにして修正して下さい。)

尚、実行結果が失敗した場合でも、連携しているGitHubのリポジトリにはファイル「.circleci/config.yml」がプッシュされるので、実行結果が成功するまではmainリポジトリにマージしないように注意して下さい。

※尚、今回は紹介しませんが、CircleCI CLIをインストールすればコマンドラインからファイルの修正(構文チェックやジョブの実行など)が行えると思います。ただし、CLIではワークフローの機能は使えないようなので、ジョブ名を指定して検証するようです。

 

CircleCIで環境変数を設定する方法

本格的に「.circleci/config.yml」ファイルを編集する前に、必要になりそうな環境変数はCircleCIに登録します。

環境変数を登録するには、CircleCIの画面右上の「Project Setting」をクリックします。

 

次にProject Setting画面が表示されるので、画面左のメニュー「Environment Variables」をクリック後、「Add Environment Variable」をクリックします。

 

次に環境変数登録画面が表示されるので、環境変数の名前と値を設定し、画面右下の「Add Environment Variable」をクリックします。

 

これでCircleCIに環境変数を登録できるので、必要になりそうな環境変数は事前に登録しておきましょう。

※ただし、後述にも記載していますが、「.circleci/config.yml」で仮想マシン(machine)を利用した場合は、CircleCIに登録した環境変数は直接読み込めない(そのまま代入もできない)ので注意が必要です。

 

仮想マシン(machine)とdocker-composeを利用したテストの自動化方法

今回はテストを自動化する例として、CircleCIの仮想マシン(machine)とdocker-composeを利用したテストの自動化方法についてまとめます。

CircleCIの仮想マシン(machine)にはあらかじめいくつかのソフトウェアがインストールされており、例えばdocker-composeやHerokuのコマンドがすぐに利用可能です。

この方法ならCircleCI上でdocker-composeを使ってテストを実行するため、普段ローカルでdocker-composeからテストを実行する時と同様な感じでテストを実行できるのがメリットです。

ただし、デメリットとしてはおそらく実行時間がちょっと遅くなるので、その点はご注意下さい。(個人で使う分には十分問題ないと思います。)

では、完成したテスト用の「.circleci/config.yml」のコードは次のようになります。

# Use the latest 2.1 version of CircleCI pipeline process engine.
# See: https://circleci.com/docs/2.0/configuration-reference
version: 2.1

# Define a job to be invoked later in a workflow.
# See: https://circleci.com/docs/2.0/configuration-reference/#jobs
jobs:
  # テスト用のジョブ
  test:
    # docker compose を利用するため、仮想マシンを利用する。(最新版のimageは下記URLを参照)
    # See: https://circleci.com/docs/ja/configuration-reference#available-linux-machine-images
    machine:
      image: ubuntu-2204:current
    # 仮想マシンを利用する場合、CircleCIの環境変数はDockerのコンテナ内へは直接読み込めない。
    # そのまま代入もできないため、一度parametersを設定する。
    parameters:
      postgres_user:
        type: string
        default: $POSTGRES_USER
      postgres_password:
        type: string
        default: $POSTGRES_PASSWORD
      rails_master_key:
        type: string
        default: $RAILS_MASTER_KEY
      tz:
        type: string
        default: $TZ
    # 作業用のディレクトリを設定
    working_directory: ~/test_rspec
    # タスクを定義
    steps:
      # リポジトリを作業用のディレクトリにpull
      - checkout
      # 処理を実行
      # db.envは公開していないため、まずは空ファイルを作成する。
      - run:
          name: db.envの空ファイルを作成
          command: touch db.env
      # parametersに設定したCircleCIの環境変数をdb.envに書き込んでDockerコンテナ内で読み込む
      - run:
         name: db.envに環境変数POSTGRES_USERを設定
         command: echo POSTGRES_USER=<< parameters.postgres_user >> >> db.env
      - run:
         name: db.envに環境変数POSTGRES_PASSWORDを設定
         command: echo POSTGRES_PASSWORD=<< parameters.postgres_password >> >> db.env
      - run:
         name: db.envに環境変数RAILS_MASTER_KEYを設定
         command: echo RAILS_MASTER_KEY=<< parameters.rails_master_key >> >> db.env
      - run:
         name: db.envに環境変数TZを設定
         command: echo TZ=<< parameters.tz >> >> db.env
      # docker composeで各種コマンドを順次実行する。
      - run:
         name: Dockerコンテナのビルドを実行
         command: docker compose build --no-cache
      - run:
         name: yarn.lockからyarnを再インストール
         command: docker compose run --rm web yarn install --frozen-lockfile
      - run:
         name: Dockerコンテナの起動
         command: docker compose up -d
      # Dockerコンテナ起動後、すぐにDBを作成しようとするとエラーが発生する可能性があるため、少し待機する。
      - run:
          name: DB接続前の待機時間 10s
          command: sleep 10
      - run:
          name: DBを作成
          command: docker compose exec web rails db:create
      - run:
          name: マイグレーションを実行
          command: docker compose exec web rails db:migrate
      - run:
          name: RSpecの実行
          command: docker compose exec web bin/rspec
      - run:
          name: 起動中のDockerコンテナを停止して削除
          command: docker compose down

# Invoke jobs via workflows
# See: https://circleci.com/docs/2.0/configuration-reference/#workflows
workflows:
  test-workflow:
    jobs:
      - test

 

簡単に解説すると、仮想マシンを利用するには「machine:」で、「image:」を定義します。imageは最新のものを指定するのが好ましいため、CircleCI更新のドキュメントをチェックして最新のものを選ぶ必要があります。(この記事を書いた時点では「ubuntu-2204:current」が最新でした。)

次に環境変数については、仮想マシン(machine)を利用すると直接読み込んでDockerコンテナ内で使うことができないため、何らかの方法でDockerコンテナ内へ渡す必要があります。

まずはCircleCIの環境変数をパラメーターとして指定できるようにするため、「parameters:」で必要な環境変数をパラメーターに設定しています。

そして、私の場合はDocker内で環境変数を読み込む方法として、GitHubには公開していない「db.env」を利用していたため、「db.env」に「parameters:」で設定した環境変数を書き込み、Dockerコンテナ内で読み込めるようにしました。

そのほか、yarnで作成される関連ファイルもGitHubには公開していないため、Dockerコンテナを起動する前にyarnのインストールが必要(yarn.lockから復元する)になりました。

※ただし、yarnを再インストールする場合は、通常のインストール(例えばyarn install)だと関連ファイルが更新されて差異が出てしまうようなので、yarnのバージョンがv1系なら「yarn install –frozen-lockfile」、v2系なら「yarn install –immutable –immutable-cache –check-cache」を使ってインストールするといいようです。

 

ファイル修正後、「Save and Run」を実行すると上図のようにStatusが「Success」になり、これでテストの自動化ができるようになります。

 

Herokuに自動でデプロイする方法

次はHerokuに自動でデプロイする方法についてまとめます。

まずは以下のコマンドを実行してHerokuのAPI-KEYを取得し、取得したAPI-KEYとHerokuのアプリ名をCircleCIの環境変数「HEROKU_API_KEY」、「HEROKU_APP_NAME」にそれぞれ設定しておきます。

※CircleCIで環境変数「HEROKU_API_KEY」を設定すると、Herokuへのログインは自動で行われるようです。また、下記コマンドで得られるトークンについては、有効期限(最初にHerokuにログインしてから約1年?)があるのでご注意下さい。有効期限が切れた場合は、再度Herokuにログイン後、下記コマンドでトークンの値を再取得し、CircleCIの環境変数に再設定して下さい。

$ heroku auth:token

 

次に完成したデプロイ用の「.circleci/config.yml」のコードは次のようになります。

# Use the latest 2.1 version of CircleCI pipeline process engine.
# See: https://circleci.com/docs/2.0/configuration-reference
version: 2.1

# Define a job to be invoked later in a workflow.
# See: https://circleci.com/docs/2.0/configuration-reference/#jobs
jobs:
  # デプロイ用のジョブ
  deploy:
    # docker compose を利用するため、仮想マシンを利用する。(最新版のimageは下記URLを参照)
    # See: https://circleci.com/docs/ja/configuration-reference#available-linux-machine-images
    machine:
      image: ubuntu-2204:current
    # 仮想マシンを利用する場合、CircleCIの環境変数はDockerのコンテナ内へは直接読み込めない。
    # そのまま代入もできないため、一度parametersを設定する。
    parameters:
      postgres_user:
        type: string
        default: $POSTGRES_USER
      postgres_password:
        type: string
        default: $POSTGRES_PASSWORD
      rails_master_key:
        type: string
        default: $RAILS_MASTER_KEY
      tz:
        type: string
        default: $TZ
      heroku_app_name:
        type: string
        default: $HEROKU_APP_NAME
    # 作業用のディレクトリを設定
    working_directory: ~/deploy_heroku
    steps:
      # リポジトリを作業用のディレクトリにpull
      - checkout
      # 処理を実行
      # db.envは公開していないため、まずは空ファイルを作成する。
      - run:
          name: db.envの空ファイルを作成
          command: touch db.env
      # parametersに設定したCircleCIの環境変数をdb.envに書き込んでDockerコンテナ内で読み込む
      - run:
          name: db.envに環境変数POSTGRES_USERを設定
          command: echo POSTGRES_USER=<< parameters.postgres_user >> >> db.env
      - run:
          name: db.envに環境変数POSTGRES_PASSWORDを設定
          command: echo POSTGRES_PASSWORD=<< parameters.postgres_password >> >> db.env
      - run:
          name: db.envに環境変数RAILS_MASTER_KEYを設定
          command: echo RAILS_MASTER_KEY=<< parameters.rails_master_key >> >> db.env
      - run:
          name: db.envに環境変数TZを設定
          command: echo TZ=<< parameters.tz >> >> db.env
      - run:
         name: Dockerコンテナのビルドを実行
         command: docker compose build --no-cache
      - run:
         name: yarn.lockからyarnを再インストール
         command: docker compose run --rm web yarn install --frozen-lockfile
      # 下記はエラーが出たので権限付与するコマンド
      - run:
         name: sudo chown -R $USER /home/circleci/deploy_heroku/tmp/db
         command: sudo chown -R $USER /home/circleci/deploy_heroku/tmp/db
      # Herokuコマンドを順次実行し、デプロイを行う。
      - run:
          name: heroku container:login
          command: heroku container:login
      - run:
          name: heroku container:push web
          command: heroku container:push web -a << parameters.heroku_app_name >>
      - run:
          name: heroku container:release web
          command: heroku container:release web -a << parameters.heroku_app_name >>
      - run:
          name: heroku run rails db:migrate
          command: heroku run rails db:migrate -a << parameters.heroku_app_name >>

# Invoke jobs via workflows
# See: https://circleci.com/docs/2.0/configuration-reference/#workflows
workflows:
  deploy-workflow:
    jobs:
      - deploy

 

こちらも簡単に解説しますが、基本的にはテスト用と同じ感じの構成です。

そして上記でも書きましたが、CircleCIで環境変数「HEROKU_API_KEY」を設定すると、Herokuへのログインは自動で行われるよう?なので、上記のコードのようにログインコマンドは不要で各種コマンドを実行できます。

また、「heroku container:push web」実行時に、「/home/circleci/deploy_heroku/tmp/db」の所有者権限が足りない系のエラーが出たので、権限付与のコマンドを追加しています。

後は、テストとデプロイで同じような処理を行なっているため、何らかのキャッシュ処理を上手く追加できれば、処理時間を短くできるかもしれません。

では、下記に最終的に完成したCI/CDパイプライン構築用のコードを載せておきます。

 

最終的に完成したCI/CDパイプライン構築用のコード

# Use the latest 2.1 version of CircleCI pipeline process engine.
# See: https://circleci.com/docs/2.0/configuration-reference
version: 2.1

# Define a job to be invoked later in a workflow.
# See: https://circleci.com/docs/2.0/configuration-reference/#jobs
jobs:
  # テスト用のジョブ
  test:
    # docker compose を利用するため、仮想マシンを利用する。(最新版のimageは下記URLを参照)
    # See: https://circleci.com/docs/ja/configuration-reference#available-linux-machine-images
    machine:
      image: ubuntu-2204:current
    # 仮想マシンを利用する場合、CircleCIの環境変数はDockerのコンテナ内へは直接読み込めない。
    # そのまま代入もできないため、一度parametersを設定する。
    parameters:
      postgres_user:
        type: string
        default: $POSTGRES_USER
      postgres_password:
        type: string
        default: $POSTGRES_PASSWORD
      rails_master_key:
        type: string
        default: $RAILS_MASTER_KEY
      tz:
        type: string
        default: $TZ
    # 作業用のディレクトリを設定
    working_directory: ~/test_rspec
    # タスクを定義
    steps:
      # リポジトリを作業用のディレクトリにpull
      - checkout
      # 処理を実行
      # db.envは公開していないため、まずは空ファイルを作成する。
      - run:
          name: db.envの空ファイルを作成
          command: touch db.env
      # parametersに設定したCircleCIの環境変数をdb.envに書き込んでDockerコンテナ内で読み込む
      - run:
          name: db.envに環境変数POSTGRES_USERを設定
          command: echo POSTGRES_USER=<< parameters.postgres_user >> >> db.env
      - run:
          name: db.envに環境変数POSTGRES_PASSWORDを設定
          command: echo POSTGRES_PASSWORD=<< parameters.postgres_password >> >> db.env
      - run:
          name: db.envに環境変数にRAILS_MASTER_KEYを設定
          command: echo RAILS_MASTER_KEY=<< parameters.rails_master_key >> >> db.env
      - run:
          name: db.envに環境変数にTZを設定
          command: echo TZ=<< parameters.tz >> >> db.env
      # docker composeで各種コマンドを順次実行する。
      - run:
          name: Dockerコンテナのビルドを実行
          command: docker compose build --no-cache
      - run:
          name: yarn.lockからyarnを再インストール
          command: docker compose run --rm web yarn install --frozen-lockfile
      - run:
          name: Dockerコンテナの起動
          command: docker compose up -d
      # Dockerコンテナ起動後、すぐにDBを作成しようとするとエラーが発生する可能性があるため、少し待機する。
      - run:
          name: DB接続前の待機時間 10s
          command: sleep 10
      - run:
          name: DBを作成
          command: docker compose exec web rails db:create
      - run:
          name: マイグレーションを実行
          command: docker compose exec web rails db:migrate
      - run:
          name: RSpecの実行
          command: docker compose exec web bin/rspec
      - run:
          name: 起動中のDockerコンテナを停止して削除
          command: docker compose down

  # デプロイ用のジョブ
  deploy:
    # docker compose を利用するため、仮想マシンを利用する。(最新版のimageは下記URLを参照)
    # See: https://circleci.com/docs/ja/configuration-reference#available-linux-machine-images
    machine:
      image: ubuntu-2204:current
    # 仮想マシンを利用する場合、CircleCIの環境変数はDockerのコンテナ内へは直接読み込めない。
    # そのまま代入もできないため、一度parametersを設定する。
    parameters:
      postgres_user:
        type: string
        default: $POSTGRES_USER
      postgres_password:
        type: string
        default: $POSTGRES_PASSWORD
      rails_master_key:
        type: string
        default: $RAILS_MASTER_KEY
      tz:
        type: string
        default: $TZ
      heroku_app_name:
        type: string
        default: $HEROKU_APP_NAME
    # 作業用のディレクトリを設定
    working_directory: ~/deploy_heroku
    steps:
      # リポジトリを作業用のディレクトリにpull
      - checkout
      # 処理を実行
      # db.envは公開していないため、まずは空ファイルを作成する。
      - run:
          name: db.envの空ファイルを作成
          command: touch db.env
      # parametersに設定したCircleCIの環境変数をdb.envに書き込んでDockerコンテナ内で読み込む
      - run:
          name: db.envに環境変数POSTGRES_USERを設定
          command: echo POSTGRES_USER=<< parameters.postgres_user >> >> db.env
      - run:
          name: db.envに環境変数POSTGRES_PASSWORDを設定
          command: echo POSTGRES_PASSWORD=<< parameters.postgres_password >> >> db.env
      - run:
          name: db.envに環境変数RAILS_MASTER_KEYを設定
          command: echo RAILS_MASTER_KEY=<< parameters.rails_master_key >> >> db.env
      - run:
          name: db.envに環境変数TZを設定
          command: echo TZ=<< parameters.tz >> >> db.env
      - run:
          name: Dockerコンテナのビルドを実行
          command: docker compose build --no-cache
      - run:
          name: yarn.lockからyarnを再インストール
          command: docker compose run --rm web yarn install --frozen-lockfile
      # 下記はエラーが出たので権限付与するコマンド
      - run:
         name: sudo chown -R $USER /home/circleci/deploy_heroku/tmp/db
         command: sudo chown -R $USER /home/circleci/deploy_heroku/tmp/db
      # Herokuコマンドを順次実行
      - run:
          name: heroku container:login
          command: heroku container:login
      # HerokunのメンテナンスモードON
      - run:
          name: heroku maintenance:on
          command: heroku maintenance:on -a << parameters.heroku_app_name >>
      # Herokuへのデプロイ処理
      - run:
          name: heroku container:push web
          command: heroku container:push web -a << parameters.heroku_app_name >>
      - run:
          name: heroku container:release web
          command: heroku container:release web -a << parameters.heroku_app_name >>
      - run:
          name: heroku run rails db:migrate
          command: heroku run rails db:migrate -a << parameters.heroku_app_name >>
      # HerokuのメンテナンスモードOFF
      - run:
          name: heroku maintenance:off
          command: heroku maintenance:off -a << parameters.heroku_app_name >>

# Invoke jobs via workflows
# See: https://circleci.com/docs/2.0/configuration-reference/#workflows
workflows:
  test-and-deploy-wf:
    jobs:
      - test
      - deploy:
          requires:
            - test
          filters:
            branches:
              only: main

※HerokuのメンテナンスモードのON/OFFと、ワークフローを修正(mainブランチにマージした時だけデプロイする)しました。尚、仮想マシンのバージョンは最新のものを使わないとエラーが出る場合があるのでご注意下さい。

 

上手く行った場合は、上図のような感じになります。

 

GitHubにプッシュした際にCircleCIを実行させたくない場合について

CI/CDパイプラインを構築すると、ブランチをGitHubにプッシュした際に設定したジョブが自動で実行されてしまいますが、プッシュ前の最後のコミットメッセージに「[skip ci]」を含めると、ジョブの実行をスキップすることが可能です。

 



Rails7でBootstrapを導入した際にCSSを修正する方法について

Railsチュートリアル(第6版)では、CSSを修正する際にcustom.scssを作りますが、Rails7でBootstrapを導入した場合(rails newのオプションで「–css=bootstrap」を付けた場合)は、app/assets/stylesheets配下にファイルapplication.bootstrap.scssがあるので、これを修正すればCSSを反映させられます。

※例えばもしcustom.scssのようなファイルを作ってCSSを反映させたい場合は、他の関連ファイルも修正して対応する必要があったりするっぽいので、application.bootstrap.scssを修正した方が早いです。そのほか上記でも書きましたが、本番環境がHerokuの場合は、環境変数に「RAILS_SERVE_STATIC_FILES=true」の設定(アセットコンパイルしたファイルを読み込む用)も必要です。

 

GitHubでタスク管理(issueの使い方)を行う方法まとめ

実際の業務では何らかのタスク管理ツールを使い、そこにMilestone(目標)やissue(課題)といったタスクを立てて開発を進めていくことになると思います。

GitHubでもタスク管理をするための機能として「issues」があり、使い方をある程度覚えておくと今後に役立つため、使い方について簡単にまとめておきます。

 

issue(課題)の作り方

GitHubの「issues」を使うには、対象のリポジトリ画面の上にあるメニューから、「issues」をクリックします。この画面でissueの管理が可能です。

 

issueを作成するには、画面右上の「New issue」をクリックします。

 

次にissueの入力画面が表示されるので、タイトルと内容を記載し、必要に応じて画面右側の担当者、ラベル、プロジェクト、マイルストーンなどを設定後、「Submit new issue」をクリックします。

 

これでissueの作成が完了です。

 

Milestone(目標)の作り方

次にMilestone(目標)を作るには、画面右上の「Milestones」をクリックします。

 

次にMilestoneを作成するには、画面中央の「Create a Milestone(まだ未作成の場合)」、または画面右上の「New milestone」をクリックします。

 

次にMilestoneの入力画面が表示されるので、タイトル、完了予定日、詳細を記載し、画面右下の「Create milestone」をクリックします。

 

これでMilestoneの作成が完了です。Milestoneのタイトルをクリックすると詳細を確認できます。

 

Milestoneの詳細画面では、紐付けたissueの管理が可能です。

 

Label(名札)について

GitHubのissuesにはLabel(名札)機能もあり、対象のissueに付けて内容の種類を分かりやすくすることが可能です。

 

デフォルトでも9種類のラベルが使用できるようになっていますが、新規作成や編集、そして削除なども可能なので、プロジェクトに応じて自由に設定できます。

 

例えばissueにラベルを付けると上図のようになります。

 

Rails7のデバッグ(debug)について

Railsチュートリアル(第6版)では、デバッグ方法としてapplication.html.erbに「<%= debug(params) if Rails.env.development? %>」を追加し、開発環境の画面でデバッグ情報を表示しています。

Rails7でも同様のコードでデバッグ情報の表示はできますが、出力形式が変わっているようなので、YAML形式で表示したい場合は「to_yaml」メソッドを使う必要があります。

<%= debug(params.to_yaml) if Rails.env.development? %>

 

そして、CSS部分に関しても表示のされ方が変わっているようなので、見やすくしたい場合は以下のようなコードを使います。

/* mixins, variables, etc. */
@mixin box_sizing {
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

/* miscellaneous */
.debug_dump {
  clear: both;
  float: left;
  width: 100%;
  margin-top: 45px;
  @include box_sizing;
  background-color: #f5f5f5;
  border: solid 2px #d3d3d3;
  border-radius: 10px;
}

※backgraund-color(背景色)、border(囲い線)、border-radius(ボーダーの角の丸み)を設定する

 

これで下図のように表示できます。

 

そのほか、Rails7からはデバッグ用のGemとして「byebug」ではなく「debug」が使われているので、その点もご注意下さい。

 

DockerのRails環境でデバッグ(debug)をする方法

通常の環境であればターミナルを新しいウインドウで開き、「rails s」を実行してサーバーを立てるため、Railsのログをリアルタイムで見ながらデバッグなども行えますが、DockerのRails環境の場合はコンテナ内でサーバーを立てるため、そのままではリアルタイムでログを見たりすることはできません。

そのため、DockerのRails環境でデバッグを行いたい場合は、docker-composeの設定追加と、起動しているWebサーバーへの接続が必要になります。

まず、docker-composeの設定追加については、Webサーバーの設定に以下を追加します。

web:
    ・
    ・
    ・
  # tty(標準入出力デバイスを設定)、stdin_open(標準入出力デバイスとコンテナを接続)を追加
  tty: true
  stdin_open: true

 

次に「docker compose up -d」でコンテナを起動後、ターミナルを新しいウインドウで立ち上げて対象のディレクトリに移動し、次のコマンドを実行してWebサーバーのコンテナ名を確認します。

$ docker ps

 

次にWebサーバーのコンテナに接続するため、以下のコマンドを実行します。

$ docker attach Webサーバーのコンテナ名

 

これでRailsのログをリアルタイムで確認できるようになったので、ブラウザでリクエストを送ると次のように表示されます。

 

また、Gem「debug」のメソッド「binding.break(エイリアスとして、binding.bやdebuggerも使える)」でデバッグをした場合は次のようになります。

※コントローラーのメソッドに「debugger」を追加し、デバッグをしてみた例

 

尚、Gem「debug」の詳細や使えるコマンドなどについては、GitHubのリポジトリにあるREADME.meをご確認下さい。

Gem「debug」のメソッド「binding.break」を終了するコマンドについては、「q」を入力するか、「command-D(WindowsはCtrl-D)」を使うようです。

 

最後に、Webサーバーのコンテナへの接続を解除するにはコマンド「control + p → control + q」を使います。

その後、ブラウザの表示などが上手く行かない場合は、以下のコマンドを実行してサーバーを再起動して下さい。

$ docker compose stop
$ docker compose start

 



Rails7の注意点

Rails7からデフォルトでTurbo(Hotwireと呼ばれるJavaScriptを極力書かずにモダンなアプリケーションを作成するためのフレームワークの中心要素のことで、TypeScriptで書かれたサーバー側言語に依存しないフレームワーク)が有効になっており、Rails6以前とは処理の書き方を変えないと上手く動作しない部分があるので、その点は注意が必要です。

 

例えば、Railsチュートリアル(第6版)ではフォームのボタンを押した際に、バリデーションチェックでエラーならエラーメッセージを画面に表示させますが、同じような処理の書き方だとエラーメッセージは表示されません。

Rails7でエラーメッセージを表示させたい場合は、コントローラーにあるrenderにオプション「status: :unprocessable_entity」を設定する必要があるので、以下のように書く必要があります。

class UsersController < ApplicationController
  ・
  ・
  def create
    @user = User.new(user_params)
    if @user.save
      # 保存の成功処理
    else
      render "new", status: :unprocessable_entity
    end
  end
  ・
  ・
end

 

このように、Rails6以前とは書き方が異なる部分がいくつかあるので注意が必要です。他には伊藤淳一(@jnchito)さんが書かれた記事が参考になるので、詳しくは以下の記事を参考にしてみて下さい。

・Rails 7.0 + Ruby 3.1でゼロからアプリを作ってみたときにハマったところあれこれ

 

destroyアクション(削除処理)ではボタン(button_to)を使う

Railsチュートリアル(第6版)でログアウト処理などのdestroyアクション(削除処理)を実行する場合、HTMLでリンク(link_to)を使って行っていますが、Rails7では上手く処理されなくなっているため、ボタン(button_to)を使う必要があります。

※そもそもdeleteでlogout_pathが実行されなかったのと、上記の伊藤淳一さんの記事にも書いている通り、destroyアクションでlink_toを使うのは注意が必要になるので気をつけて下さい。

 

Rails7のBootstrap5で書き方が違う部分まとめ

Rails7でBootstrapを導入した場合(rails newのオプションで「–css=bootstrap」を付けた場合)はBootstrap5が導入されることになりますが、Railsチュートリアル(第6版)のBootstrap3とは書き方が違う部分があるため、ここではその点についてまとめておきます。

 

「jumbotron」→「bg-light p-4 p-sm-5 my-4 rounded」

Bootstrap5では以前までにあった「jumbotron」が廃止されたため、同じようにしたい場合は「bg-light p-4 p-sm-5 my-4 rounded」を設定すると可能です。

 

・Bootstrap3の場合

<div class="center jumbotron>
</div>

 

・Bootstrap5の場合

<div class="center bg-light p-4 p-sm-5 my-4 rounded>
</div>

 

「col-md-offset-3」→「offset-md-3

Bootstrap3にある「col-md-offset-3」という書き方は、Bootstrap4以降では「offset-md-3」という書き方に変わっているので注意しましょう。

 

・Bootstrap3の場合

<div class="col-md-6 col-md-offset-3">
</div>

 

・Bootstrap4以降の場合

<div class="col-md-6 offset-md-3">
</div>

 

ナビゲーションバーで上部固定にした場合、bodyタグに「padding-top: 5rem;」を設定する

ナビゲーションバーで上部固定にした場合、最上部がナビゲーションバーと重なるため、CSSで「padding-top」を設定する必要がありますが、Bootstrap5の場合は値に「5rem」を設定します。

body {
  padding-top: 5rem;
}

 

「@extend .has-error;」→「@extend .is-invalid;」

Railsチュートリアル(第6版)では、フォーム送信でエラーの場合のエラーメッセージのCSS設定で「@extend .has-error;」を使っていますが、これはBootstrap4以降では廃止されたため、Bootstrap4以降では「@extend .is-invalid」を使います。

 

・Bootstrap3の場合

.field_with_errors {
  @extend .has-error;
  .form-control {
    color: $state-danger-text;
  }
}

※colorの「$state-danger-text」もBootstrap4以降で廃止

 

・Bootstrap4以降の場合

.field_with_errors {
  .form-control {
    @extend .is-invalid;
  }
}

 

ドロップダウンメニューについて

Railsチュートリアル(第6版)では、ドロップダウンメニューの追加の際にjQueryを使っていますが、Bootstrap5ではjQueryが不要になっています。そして、HTMLで付けるクラス名もBootstrap5用に変える必要があります。

 

・Bootstrap5の場合(一部抜粋)

  ・
  ・
<nav>
  <ul class="navbar navbar-nav navbar-right">
    <li><%= link_to "Home", root_path %></li>
    <li><%= link_to "Help", help_path %></li>
    <% if logged_in? %>
      <li><%= link_to "Users", "#" %></li>
      <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href="#" id="navbarDarkDropdownMenuLink"
           role="button" data-bs-toggle="dropdown" aria-expanded="false">
        Account
        </a>
        <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownMenuLink">
          <li><%= link_to "Profile", current_user, class: "dropdown-item" %></li>
          <li><%= link_to "Settings", "#", class: "dropdown-item" %></li>
          <li><hr class="dropdown-divider"></li>
          <li><%= button_to "Log out", logout_path, method: :delete, class: "dropdown-item" %></li>
        </ul>
      </li>
    <% else %>
      <li><%= link_to "Log in", login_path %></li>
    <% end %>
  </ul>
</nav>
  ・
  ・
  ・
  ・
  // ドロップダウンメニュー
  ul.dropdown-menu {
    li {
      margin-left: 0;
      a {
        color: black;
        text-decoration: none;
        &:hover {
          color: black;
        }
      }
    }
  }
  ・
  ・

 

チェックボックスについて

HTMLでチェックボックスを追加する際についても、class名「checbox inline」の部分はBootstrap5用に修正する必要がありそうですが、これはガイドの通りに実装してみてもイマイチ上手くいかなかったので、以下の通りに実装すると実現できました。

 

・Bootstrap5の場合(一部抜粋)

    ・
    ・
  <%= form_with(url: login_path, scope: :session, local: true) do |f| %>
      
    <%= f.label :email %>
    <%= f.email_field :email, class: "form-control" %>

    <%= f.label :password %>
    <%= f.password_field :password, class: "form-control" %>

    <%= f.label :remember_me, class: "form-check-label" do %>
      <%= f.check_box :remember_me %>
      <span>Remember me on this computer</span>
    <% end %>

    <%= f.submit "Log in", class: "btn btn-primary" %>
  <% end %>
    ・
    ・
    ・
    ・
.form-check-label {
  margin-top: -10px;
  margin-bottom: 10px;
  span {
    margin-left: 5px;
    font-weight: normal;
  }
}

#session_remember_me {
  width: auto;
  margin-left: 0;
}
    ・
    ・

 

ページネーションについて

Railsチュートリアル(第6版)では、ページネーションをするためにgem「bootstrap-will_paginate」を使っていますが、これはBootstrap5には対応していないため、別のgemを使う必要があります。

私の場合はgem「will_paginate-bootstrap-style」を利用し、以下のように実現しました。

# ページネーション用のGem
gem "will_paginate"
gem "will_paginate-bootstrap-style"

 

<% provide(:title, "All users") %>
<h1>All users</h1>

<%= will_paginate @users, previous_label: '← Previous', next_label: 'Next →' %>

<ul class="users">
<%= render @users %>
</ul>

<%= will_paginate @users, previous_label: '← Previous', next_label: 'Next →' %>

 

// ページネーション
ul.pagination {
  margin-top: 30px;
}

 

ユーザーの削除ボタンについて

上記でも書きましたが、Rails7ではdestroyアクションにはリンクではなく、ボタンを使った方がいい仕様になっているため、「button_to」を使ってユーザーの削除ボタンを実装します。

ただし、confirmの設定方法が変わっているのと、画面表示がボタンの表示になり、レイアウトが崩れてしまうため、CSSでレイアウトを修正する必要があります。

具体的には以下のように実装しました。

<li>
  <%= gravatar_for user, size: 50 %>
  <%= link_to user.name, user %>
  <% if current_user.admin? && !current_user?(user) %>
    | <%= button_to "delete", user, class: "button-#{user.id}", method: :delete,
    form: { data: { turbo_confirm: "You sure?" } } %>
  <% end %>
</li>

※confirmは「form: { data: { turbo_confirm: “You sure?” } }」で設定。またテスト用にclassに「button-#{user.id}」を設定して特定できるようにしています。

 

.users {
    ・
    ・
  // deleteボタン
  form.button_to {
    display: inline-block;
    margin-left: -5px;
  }
  button {
    background-color: white;
    border: none;
    color: var(--bs-link-color);
    &:hover {
      color: var(--bs-link-hover-color);
    }
  }
}

※ボタンが改行される問題を「form.button_to」の「display: inline-block;」で修正しています。

 

GitHubのREADME.mdファイル(Markdown)で空白行を入れる方法

GitHubのREADME.mdファイルで空白行を入れたい場合もあると思いますが、以下のように<br/>を間に挿入すると実現可能です。

1行目

<br/>

2行目

 

実際に試してみると、下図の通りになります。

 

RSpecでテスト用のヘルパーを作成する方法

RSpecでテスト用のヘルパーを作成するには、spec/support配下にヘルパー用のファイルを作成します。

例えばシステムスペック用のヘルパーファイルを作成した例は次の通りです。

module SystemSpecHelper
  # ログイン処理
  def log_in_as(user)
    visit login_path
    fill_in "Email", with: user.email
    fill_in "Password", with: user.password
    click_button "Log in"
  end
end

 

次にspec/rails_helper.rbのDir[Rails.root.join(‘spec’, ‘support’, ‘**’, ‘*.rb’)].sort.each { |f| require f }」のコメントを外して有効化し、RSpec.configure do |config|」内で作成したヘルパーファイルを読み込みます。これでRSpecでヘルパーを使用できます。

    ・
    ・
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }
    ・
    ・
RSpec.configure do |config|
    ・
    ・
  # テスト用のHelperをinclude
  config.include SystemSpecHelper, type: :system
end

 

factory_botで2種類目の設定を追加する時の注意点

RSpecでテストデータを作成する際にはfactory_botを使っていることが多いと思いますが、2種類目の設定を追加する際には、Class名を明示的に指定する必要があります。

FactoryBot.define do
  factory :user do
    name { "First User" }
    email { "first_user@example.com" }
    password { "password" }
    password_confirmation { "password" }
  end

  factory :other_user, class: User do
    name { "Other User" }
    email { "ohter_user@example.com" }
    password { "password" }
    password_confirmation { "password" }
  end
end

※「:user」はmodel名と同一なのでclass名を明示的に指定する必要はありませんが、「:other_user」はmodel名と異なるため、class名を明示的に指定する必要があります。

 



DockerのRails環境でcredentials.yml.encを編集する方法

私がRailsチュートリアル(第6版)を進める中でcredentials.yml.encを編集する際、編集用のエディタとしてはVScodeを利用しましたが、DockerのRails環境の場合はそれを実現させるのが少々難しいため、編集用のエディタとしては単純にVimを使った方が簡単です。

そして、DockerのRails環境でVimを使う際は、Dockerのコンテナ内にVimをインストールする必要があるため、上記で記載したDockerfileの中でVimをインストールしています。

ただし、通常の「Vim」をインストールするとクリップボード機能が使えず、外部アプリとのコピペができなくて非常に不便なため、クリップボード機能が使えるVimのパッケージをインストールするのがおすすめです。

私の場合はvim-gtkをインストールしましたが、クリップボード機能が普通に使える感じなので、比較的簡単にcredentials.yml.encの編集ができました。

 

尚、docker-composeでコンテナを起動中にcredentials.yml.encの編集をしたい場合は、次のコマンドを実行すると可能です。

$ docker compose exec -e EDITOR=vim web rails credentials:edit

※「exec」はコンテナ起動中に使うコマンドなので、コンテナを起動していない場合は「run」コマンドを使うと可能です。

 

そのほか、Vimを使うのは少々癖があって慣れが必要ですが、ファイルを編集する際は「i」キーを押して挿入モードにしてから修正し、修正が終わったら「esc」キーを押してノーマルモードにした後、上書き保存して終了するならコマンド「shift + zz」を押す、保存せずに終了するならコマンド「shift + zq」押すと終了できます。

 

RSpecなどのテスト時にコントローラーのインスタンス変数を使う方法

Railsチュートリアル(第6版)では、コントローラーのインスタンス変数をテストで使う際にassignsメソッドを利用しましたが、このメソッドの利用はRails5以降から非推薦になりました。

現在は「controller.instance_variable_get」メソッドを利用する(request specの場合)ことで、コントローラーのインスタンス変数を使えるようになります。

例えばコントローラーの@userを取得したい場合は、以下のようにして取得します。

user = controller.instance_variable_get("@user")

 

Rails7でjQueryを使わずに画像のファイルサイズをチェックする方法

Railsチュートリアル(第6版)では、HTML側でもjQueryを使用して画像のファイルサイズをチェックしていますが、Rails7ではそのままだとjQueryは使えないため、別途jQueryをインストールするか、JavaScriptで実装する必要があります。

特にRails7でBootstrapを使う場合もjQueryは使わない仕様に変更されていることから、今回はJavaScriptで実装することにしましたが、具体的には次の通りです。

 

・Rails7でJavaScriptで実装する場合

  ・
  ・
<script type="text/javascript">
// 画像ファイルのサイズチェック
// 画像ファイルのサイズは5MB以下とする
var filesizelimit = 1024 * 1024 * 5;

// input要素を指定
var inputfile = document.getElementById("micropost_image");

// changeイベントで呼び出す関数
var handleFileSelect = () => {
  var inputfilesize = inputfile.files;
  for (let i = 0; i < inputfilesize.length; i++) {
    // 画像ファイルサイズが制限を超える場合
    if (inputfilesize[i].size > filesizelimit) {
      // エラーメッセージを表示
      alert('ファイルサイズは1MB以下にしてください');

      // inputの中身をリセット
      inputfile.value = '';

      // 処理を終了
      return;
    }
  }
}

// ファイル選択時にhandleFileSelectを実行
inputfile.addEventListener("change", handleFileSelect);
</script>

※input要素の取得には、inputタグに付けたidを指定する。また、変数宣言時にvarを使っている場合は大丈夫だが、letやconstを使うとページを再読み込みしないと既に変数宣言されている旨のエラーが発生し、javascriptが上手く動作しないことがあるので注意。

 

Rails7で画像のリサイズ処理をする方法

Railsチュートリアル(第6版)では、画像のリサイズ処理でGem「mini_magick」を利用(環境にimagemagickはインストール済みを想定)していますが、Rails7からはActive Storageのデフォルトのバリアントプロセッサが「:vips」に変更されているため、そのままだと画像のリサイズ処理が上手くできません。

解決方法としては環境にvipsをインストールするか、Active Storageのバリアントプロセッサを「:mini_magick」に変更する必要がありますが、今回はRailsチュートリアルを参考にしているため、バリアントプロセッサを変更することにします。

Active Storageのバリアントプロセッサを変更するには、config/application.rbに「config.active_storage.variant_processor = :mini_magick」を設定します。

  ・
  ・
module アプリ名
  class Application < Rails::Application
    ・
    ・
    # Active Storageのバリアントプロセッサにmini_magickを設定
    config.active_storage.variant_processor = :mini_magick
    ・
    ・
  end
end

 

尚、mini_magickを利用するには環境に「imagemagick」がインストールされている必要がありますが、DockerのRails環境ではRubyのベースイメージに既にインストールされている?ようなので、Dockerfileで個別にインストールしなくても大丈夫でした。(コンテナ起動後にコマンド「docker compose exec web convert -version」を実行すると、インストール済みのimagemagickのバージョンを確認できます。)

 

Rails7でAjax(jQuery)の代わりにHotwire(Turbo)を使う方法

Railsチュートリアル(第6版)では、Ajax(jQuery)を使って非同期処理を行い、フォローやフォロー解除ボタンの更新を行なっていますが、Rails7ではそのままだとjQueryが使えないため、その代わりとしてHotwire(Turbo)を使うのが基本になりそうです。

そのため、フォローやフォロー解除ボタンによる非同期処理を、Hotwire(Turbo)で行う方法をまとめておきます。

※非同期処理をする部分が1箇所の場合はturbo_frameだけで実現できますが、2箇所以上ある場合はturbo_streamを使う必要があります。下記では2箇所以上更新するため、turbo_streamを使う例になっています。

 

①HTMLで非同期処理をしたい部分に「turbo_frame_tag」を付与

まずは下図のように、フォローボタン(またはフォロー解除ボタン)を押した後、ボタンの表示が変わり(フォロボタンならフォロー解除ボタンに変わること)、それに加えてユーザーのフォロワー数の表示についても更新したい場合を想定します。

 

そのためにはまず、HTMLファイルの象箇所を「<%= turbo_frame_tag “タグの名前” do %>」、「<% end %>」で囲みます。

・一つ目はボタンを表示させている部分のパーシャル「_follow_form.html.erb」

<%= turbo_frame_tag "follow_button" do %>
  <% unless current_user?(@user) %>
    <div id="follow_form">
      <% if current_user.following?(@user) %>
        <%= render "users/unfollow" %>
      <% else %>
        <%= render "users/follow" %>
      <% end %>
    </div>
  <% end %>
<% end %>

 

・二つ目はフォロワー数を表示させている部分のパーシャル「_stats.html.erb」

<%= turbo_frame_tag "stats_follow" do %>
  <% @user ||= current_user %>
  <div class="stats">
    <a href="<%= following_user_path(@user) %>" data-turbo=false>
      <strong id="following" class="stat">
        <%= @user.following.count %>
      </strong>
      following
    </a>
    <a href="<%= followers_user_path(@user) %>" data-turbo=false>
      <strong id="followers" class="stat">
        <%= @user.followers.count %>
      </strong>
      followers
    </a>
  </div>
<% end %>

※注意点として、turbo_frame_tagで囲った部分は監視対象となり、例えばリンクが上手く動作しなくなったりするため、リンク部分には属性「data-turbo=false」を付けて監視対象から外しています。

 

②対象のコントローラーのアクションのレスポンスに「turbo_stream」を指定

次にturbo_streamを使う場合は、対象のコントローラーのアクションのレスポンスで、「turbo_stream」を指定する必要があります。

※今回はrelationshipsコントローラーのcreateアクションとdestroyアクションを実行時に非同期処理をすることを想定しています。

class RelationshipsController < ApplicationController
  before_action :logged_in_user

  def create
    @user = User.find(params[:followed_id])
    current_user.follow(@user)

    # Rails7のHotwireで、SPA風な更新処理をしたい場合、
    # turbo_streamを返す(アクションに対するビューに処理を記述)
    respond_to do |format|
      format.turbo_stream
    end
  end

  def destroy
    @user = Relationship.find(params[:id]).followed
    current_user.unfollow(@user)

    # Rails7のHotwireで、SPA風な更新処理をしたい場合、
    # turbo_streamを返す(アクションに対するビューに処理を記述)
    respond_to do |format|
      format.turbo_stream
    end
  end
end

 

③対象のコントローラーのアクション名を付けた「アクション名_turbo_stream.erb」ビューを作成

次に対象のコントローラーのアクション名を付けた「アクション名_turbo_stream.erb」ビューを作成します。

今回の例ではrelationshipsコントローラーのcreateアクションとdestroyアクションが対象のため、「app/view/relationships」フォルダの直下に「create.turbo_stream.erb」と「destroy.turbo_stream.erb」を作成します。

 

④作成したビューにturbo_streamの処理を記述

最後に作成したビューにturbo_streamの処理を記述します。今回の例ではボタンの部分とフォロワーの表示部分の2箇所を更新したいため、それぞれのファイルに2つの処理を記述します。

・createアクションに対する処理

<%= turbo_stream.replace("follow_button", partial: "users/follow_form") %>
<%= turbo_stream.update("stats_follow", partial: "shared/stats") %>

※turbo_stream.replaceやturbo_stream.updateがやりたい処理の内容になっており(他にもいくつか種類があります)、パラメーターとしてはtabo_frame_tagで付けた名前と、そのtagがあるパーシャルを指定しています。

 

・destroyアクションに対する処理

<%= turbo_stream.replace("follow_button", partial: "users/follow_form") %>
<%= turbo_stream.update("stats_follow", partial: "shared/stats") %>

 

これでRailsチュートリアル(第6版)の中でAjax(jQuery)で行なっている処理と同じような処理を実現することができます。

実際に試した場合、次のようになります。

 

まだフォローしていないユーザーのページを開き、「Follow」ボタンを押した場合、「Unfollow」ボタンが表示され、加えてユーザーのフォロワー数も更新されます。

 



DockerのRailsアプリをRender.comにデプロイする方法まとめ(HerokuからRender.comへ移行)

Railsチュートリアル第6版や上記においては、本番環境にHerokuを利用していますが、残念ながら2022年11月28日より無料プランが廃止されるため、無料で学習を進めたい方は別のサービスへの移行が必要になります。(ただし、Herokuは非常にいいサービスではあるため、有料でも大丈夫な方はHerokuを使うのがおすすめだと思います。)

今までのHerokuのように全て無料でいい感じに利用できるわけではありませんが、近いサービスとして「Render.com」があるため、以下ではDockerのRailsアプリをRender.comにデプロイする方法(HerokuからRender.comへ移行)をまとめます。

 

Render.comの料金プランについて

Render.comには無料プランがありますが、Herokuと同様に将来的に有料になる可能性もあるのでその点はご注意下さい。詳しくはRender.comの料金プランページをご確認下さい。

※特にDB(PostgreSQL)の無料プランには制限(90日間は無料で使えますが、その後に有料プランに移行しないとDBが削除されます。おそらく再度作り直せばまた90日間無料で使えると思います。なので削除される数日前に自分で削除して作り直すとかの運用で問題なければ無料で使い続けられるかも?という感じです。)があるので注意

 

Render.comのアカウント登録方法

Render.comのアカウント登録をするには、まずはRender.com公式サイトにアクセスし、画面右上の「GET STARTED」をクリックします。

 

次にSign up画面が表示されるため、例えばGitHubを連携するなら「GitHub」ボタンをクリックします。

 

承認画面が表示されるため、「Authorize Render」をクリックします。

 

GitHubアカウントのメールアドレスが連携されて入力されるため、「COMPLETE SIGN UP」をクリックします。

 

これでメールアドレス宛に認証用のメールが送信されます。

 

送信されたメール内に記載のURLをクリックします。

 

これでRender.comのアカウント作成が完了です。

 

Render.comでDB「PostgreSQL」を作成する方法

本番環境のDBとしてRender.comのPostgreSQLを使う場合は、まず最初に作成しておきます。

DB「PostgreSQL」を作成するには、(一番最初なら)ダッシュボード画面の中央にある「New PostgreSQL」か、画面右上の「New +」のメニューにある「PostgreSQL」をクリックします。

 

PostgreSQLの作成画面が表示されるので、Name(Render上で表示される名前。後で変更も可能。)、Database(DB名)、User(ユーザー名)、Region(リージョン。一番近いのはシンガポール)、PostgreSQL Version(デフォルトは14。問題なければそのままでOK)をそれぞれ設定します。

 

そして画面下の料金プランから任意のものを選択しますが、無料プランを使いたい場合は「Free」を選択しておきます。

全ての設定が完了後、画面下の「Create Database」をクリックするとDBが作成されます。

 

DBが作成された後、Connectionsに接続情報が記載されているので、その中の「Internal Database URL(内部データベースURL)」をメモしておきます。(アプリ作成時の環境変数に設定します。)これでDBの作成は完了です。

 

Render.comでDockerのRailsアプリをデプロイする方法(HerokuからのDBデータ移行が不要な場合)

Render.comにデプロイする際には、連携するGitHubリポジトリの内容を元にデプロイ処理がされる(DockerのRailsアプリなら、ルートディレクトリ直下にあるDockerfileを元にデプロイ処理がされる)ため、事前に正しい設定でGitHubにコミットしておく必要(間違いがあるとデプロイ時に失敗します。)があります。

例えば上記に記載した内容を元に既にRailsアプリを作成しており、かつHerokuにあるDB(PostgreSQL)のデータの移行などが不要な場合は、Dockerfile、entrypoint.sh、config/database.yml、config/puma.rb、config/environments/production.rbをそれぞれ以下のように修正する必要があります。

 

①Dockerfileでyarn.lockから対象のパッケージをインストールするように修正

下記のように、最後のスクリプトを実行する前にコマンド「yarn install –frozen-lockfile」を実行してyarn.lockから必要なパッケージをインストールするように修正します。

・・・

# yarn.lockからインストール
RUN yarn install --frozen-lockfile

# コンテナ起動時に実行するスクリプト
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
・・・

 

②entrypoint.shで「rails db:migrate」を実行するように修正

以下のようにコマンド「bundle exec rails db:migrate」を追加し、最後にマイグレーションを実行するように修正します。(Dockerfileの最後でこのファイルが実行されるため)

・・・
# production環境の場合のみJSとCSSをビルド
if [ "$RAILS_ENV" = "production" ]; then
bundle exec rails assets:clobber
bundle exec rails assets:precompile
bundle exec rails db:migrate
fi
・・・

 

③config/database.ymlでproduction環境の設定を環境変数「DATABASE_URL」から読み取るように修正

production環境の設定については、defaultに設定した値と環境変数「DATABASE_URL」に設定した内部データベースURLから接続情報などを取得するように修正します。

・・・
# defaultは以下の設定のみにする
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

# productionは環境変数「DATABASE_URL」から内部データベースURLを読み込むようにする
production:
  <<: *default
  url: <%= ENV["DATABASE_URL"] %>
・・・

※開発環境で使うdevelopmentとtestについては、それぞれ個別にdatabase、username、password、hostを設定して下さい。

 

④config/puma.rbで「WEB_CONCURRENCY」の値を「4」に修正

以下のようにWEB_CONCURRENCYの値を「4」に修正します。

・・・
workers ENV.fetch("WEB_CONCURRENCY") { 4 }
・・・

 

⑤config/environments/production.rbで「config.public_file_server.enabled」の設定値を修正

以下のようにconfig.public_file_server.enabledの設定値を「ENV[“RAILS_SERVE_STATIC_FILES”].present? || ENV[“RENDER”].present?」に修正します。

・・・
config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? || ENV["RENDER"].present?
・・・

 

これで最低限必要な修正が完了したので、修正後のコードをGitHubへコミットしておいて下さい。(もしCircleCIを連携させている場合は、合わせてCircleCIの設定も見直すか、実行しないようにコミットメッセージに[skip ci]を含めるなどして対応して下さい。)

では、Render.comからデプロイ処理を進めるため、ダッシュボード画面の右上にある「New +」から「Web Service」をクリックします。

 

次にGitHubからリポジトリを連携する場合は、GitHubアイコン下の「+ Connect account」をクリックします。

 

次に「Only select repositories」を選んだ後、読み込みたいリポジトリを選択し、画面下の「Install」をクリックします。

 

次にGitHubアカウントのパスワードを入力後、「Confirm」をクリックします。

 

これで連携したGitHubから対象のリポジトリを読み込めたので、「Connect」をクリックします。

 

次にWeb Serviceの各種設定画面が表示されるため、Name(任意のサービス名を入力)、Environment(Dockerfileからデプロイする場合は「Docker」にする)、Region(東京はないので、近いシンガポールを設定)、Branch(使いたいブランチを指定できるが、基本的にmainでOK)を必要に応じてそれぞれ設定します。

 

次に画面下のプラン選択が可能ですが、無料プランを使いたいなら「Free」を選択します。

 

次に画面下にある「Advanced」をクリックします。

 

詳細画面が開くので、「Add Environment Variable」をクリックし、各種環境変数を設定します。

 

環境変数にはkeyとvalueを入力して設定します。環境変数を増やしたい場合は、下の「Add Environment Variable」をクリックして枠を増やします。

 

環境変数に設定すべき値の例としては以下の通りです。(DATABASE_URLとRAILS_MASTER_KEYは必須です。)

 

次に画面下のAuto-Deployの項目はデフォルトで「Yes」になっていますが、そのままだとGitHubにコードをプッシュしたタイミングで本番環境にもデプロイされてしまうので注意が必要です。CircleCIなどでデプロイをする想定の場合は「No」を設定して下さい。

全ての設定が完了後、画面下の「Create Web Service」をクリックするとデプロイが開始されます。

 

デプロイ開始後、作成したWebサービスの画面が表示されます。(処理中はステータスが「In progress」になっており、下の画面で処理のログが流れるので確認できます。)

 

デプロイ処理が完了後、ステータスが「Live(緑色)」ならデプロイ処理自体は正常終了しているため、画面左上のURLをクリックすると、デプロイした本番環境にアクセス可能です。

 

尚、もしデプロイに失敗した場合は、コードを修正してGitHubにコミット後、Webサービス画面の右上にある「Manual Deploy」から「Deploy latest commit」をクリックすると最新のコミット内容でデプロイ処理を行えます。

 

HerokuからRender.comへDB(PostgreSQL)データを移行したい場合

もしHerokuにあるDB(PostgreSQL)データをRender.comのDB(PostgreSQL)にそのまま移行したい場合は、次の手順を行います。

 

①以下のコマンドを実行し、HerokuのDB(PostgreSQL)でバックアップを作成する。

$ heroku pg:backups:capture --app herokuの対象アプリ名

※「herokuの対象アプリ名」はご自身の環境に合わせて指定して下さい。

 

②以下のコマンドを実行し、作成したバックアップファイル(latest.dump)をダウンロードします。

$ heroku pg:backups:download --app herokuの対象アプリ名

※「herokuの対象アプリ名」はご自身の環境に合わせて指定して下さい。また、バックアップファイル(latest.dump)はコマンド実行時のディレクトリ内にダウンロードされると思います。

 

③Render.comのDB(PostgreSQL)への接続情報を確認する

Render.comで作成したDB(PostgreSQL)のページを開き、Connectionsのところにある「PSQL Command」の内容を確認(メモ)しておきます。(ここから必要な接続情報を取得して利用)

 

具体的には以下のようなコマンドになっているので、このコマンドにある「PGPASSWORD=パスワード値」、「-h ホスト名」、「-U DBユーザ名」および、コマンドを加えたDB名「-d DB名」を接続情報として使います。

PGPASSWORD=パスワード値 psql -h ホスト名 -U DBユーザ名 DB名

 

④Render.comにデプロイする際に、ダウンロードしたバップアップファイル「latest.dump」をRender.comのDB(PostgreSQL)へインポートさせるため、一時的に「entrypoint.sh」でコマンド「pg_restore」を実行するように修正(無料プランだとshell機能が使えないためデプロイ時に実行させる)する。

・・・
# production環境の場合のみJSとCSSをビルド
if [ "$RAILS_ENV" = "production" ]; then
bundle exec rails assets:clobber
bundle exec rails assets:precompile
# 一時的にコマンド「pg_restore」を実行させる
PGPASSWORD=パスワード値 pg_restore --verbose --no-acl --no-owner -h ホスト名 -U DBユーザ名 -d DB名 latest.dump
fi
・・・

※上記でデータ移行が不要な場合はコマンド「bundle exec rails db:migrate」を実行するように修正しましたが、バックアップファイル「latest.dump」には全てのDBデータが含まれているため、コマンド「bundle exec rails db:migrate」を実行する前にコマンド「pg_restore」を実行しないと既にテーブルが登録されているなどのエラーが発生するのでご注意下さい。もし既にコマンド「bundle exec rails db:migrate」を実行してしまっている場合は、一度Render.comのDB(PostgreSQL)を削除して作り直して下さい。

 

⑤GitHubにコードをコミット後、Render.comへのデプロイ処理を実行する

上記で取得したバックアップファイル「latest.dump」と一時的にコマンド(pg_restore)を実行するように修正した「entrypoint.sh」および、上記の”Render.comでDockerのRailsアプリをデプロイする方法”で記載したデプロイ時に修正が必要な各種ファイル「Dockerfile、config/database.yml、config/puma.rb、config/environments/production.rb」(修正内容は上記をご確認下さい。)をそれぞれ修正した後にGitHubへコミットして下さい。

GitHubにコミット後、Render.comからデプロイ処理を実行すると、HerokuにあったDBデータもインポートされた状態で本番環境が構築されます。

 

⑥entrypoint.shに記載したコマンド「pg_restore」を削除し、コマンド「bundle exec rails db:migrate」に修正しておく

初回以降はコマンド「pg_restore」は不要なので削除し、次回以降は「rails db:migrate」が実行されるように修正して下さい。

・・・
# production環境の場合のみJSとCSSをビルド
if [ "$RAILS_ENV" = "production" ]; then
bundle exec rails assets:clobber
bundle exec rails assets:precompile
bundle exec rails db:migrate
fi
・・・

 

CircleCIからRender.comへデプロイさせる方法

上記では手動でデプロイする方法についてまとめましたが、ここではCircleCIからRender.comへデプロイする方法についてまとめます。

CircleCIからRender.comへのデプロイ処理を実行するには、webhook経由でデプロイする必要があるため、Render.comにある対象のWebサービスからDeploy Hook(デプロイ用のAPIアドレス)を確認します。

まずはRender.comの対象のWebサービスページを開き、画面左のメニュー「Settings」をクリックします。

 

そして画面下にあるDeploy HookのURLをメモ(コピー)しておきます。

 

次にCircleCIにある対象のプロジェクトの環境変数設定画面から、メモしたDeploy HookのURLを環境変数に設定します。

 

次に.circleci/config.ymlを以下のように修正し、Render.comへのデプロイ処理を追加します。

上記でも記載している通り、今までHerokuにデプロイしていた場合はワークフローにてジョブ「- deploy」を指定しているため、その部分をコメントアウトして新しく追加したジョブ「- deploy_render」を指定します。

・・・
# Render.comへのデプロイ用のジョブを追加
  deploy_render:
    machine:
      image: ubuntu-2204:current
    # 作業用のディレクトリを設定
    working_directory: ~/deploy_render
    steps:
      # リポジトリを作業用のディレクトリにpull
      - checkout
      # Render.comへのデプロイ処理
      - run:
          name: Render.comへのデプロイ処理
          command: curl -f $RENDER_DEPLOY_HOOK

workflows:
  test-and-deploy-wf:
    jobs:
      - test
      # デプロイ先をRender.comに修正
      #- deploy
      - deploy_render:
          requires:
            - test
          filters:
            branches:
              only: main

※Render.comへのデプロイ処理については、コマンド「curl -f $RENDER_DEPLOY_HOOK」で実行しています。オプションの「-f」を付けると、リクエストの戻り値が正常終了しなかった場合にエラーになります。

 

これでmainブランチにマージしたタイミングでRender.comへのデプロイ処理を実行することができますが、デプロイ処理の結果に関わらずCircleCIは正常終了するため、その点は注意が必要です。(デプロイ結果はRender.comで確認する必要がある)

 



最後に

今回はRailsチュートリアルをベースにカスタマイズする方法についてまとめました。

Railsチュートリアルを一度最後まで進めた後に、今回ご紹介した新しい技術を導入しながら再度Railsチュートリアルを進めることで、また一つ大きな成長に繋がっていくと思います。

後は新規機能の追加などを行えば、一応ポートフォリオとしても使えるようにはなる(工夫は必要なので注意)と思うので、現在Web系エンジニアを目指して頑張っている方は、ぜひ参考にしてみて下さい。

尚、この記事では色々と新しい技術についても触れていますが、この後はSPA構成やインフラとしてAWSを使う知識や経験を深めれば、最低限必要になる技術的な部分はある程度網羅できると思います。

 

合わせて読みたい👇

Railsチュートリアル(第6版)を進めるための参考資料

2022年7月16日

 

各種SNSなど

各種SNSなど、チャンネル登録やフォローをしていただけると励みになるので、よければぜひお願いします!

 

The following two tabs change content below.

Tomoyuki

SEを5年経験後、全くの未経験ながら思い切ってブロガーに転身し、月間13万PVを達成。その後コロナの影響も受け、以前から興味があったWeb系エンジニアへのキャリアチェンジを決意。現在はWeb系エンジニアとして働きながら、プロゲーマーとしても活躍できるように活動中。








シェアはこちらから


【2024年】おすすめのゲーミングPC

モンハンワイルズの発売日とPC版(Steam版)の推薦スペックが公開されたので、おすすめのゲーミングPCをご紹介!


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です