CI(継続的インテグレーション)/CD(継続的デリバリー)環境も含めて今すぐにRails6の開発環境が欲しいんだ……しかも無料で……
いろいろと設定するのめんどくさいな……あぁー後なんとなくDockerで開発したいよね……
そんな要望を叶えるために作成したのがこの記事になります!
CI(継続的インテグレーション)/CD(継続的デリバリー)環境なしだったらコマンド3つでRails6の開発環境を立ち上げることができます!
またCircleCIとHerokuを使用してCI(継続的インテグレーション)/CD(継続的デリバリー)環境も構築できるように説明しています
詳しくはtemplate_sample_rails_6のリポジトリを見てください!
改修箇所
自分が使いやすいようにいくつか改修しました
Docker化
コマンド1つで開発ができるようにDocker化しました
Docker内ではよく使う Redis、Sidekiqが既に導入済みです
データベースは PostgreSQL を使用します
RSpec
デフォルトでは Minitest ですが RSpec のほうが使い慣れているので RSpec を導入しています
テストデータ作成ツールの factory_bot、コードカバレッジを計測するツールの SimpleCov も導入済みです
ER図自動生成
Rails ERD を導入しているのでマイグレーションを実行した時、自動でER図が作成されるようになっています
デバッグツール
システムを開発するためには効率よくデバッグできることで開発スピードは格段に上がるためRails開発ではおなじみの binding.pry
を使用できる状態になっています
静的コード解析ツール
コードを一定の品質に保つために静的コード解析ツールを以下の3つが導入済みになっています
- Rubocop(Rubyの静的コードアナライザー及びコードフォーマッター)
- Rails Best Practices(Railsのベストプラクティスを教えてくれる)
- Brakeman(セキュリティの脆弱性チェック)
CI(継続的インテグレーション)/CD(継続的デリバリー)環境 - Lint/Test/Deploy
CircleCIにて自動テスト、静的コード解析、自動デプロイ(Heroku)を行うように設定ずみ
コードの状態
- Railsガイドで紹介されている rails generate scaffold HighScore game:string score:integer を叩いた状態
Rails6をDockerで動かす
下記コマンドを実行します
# ソースコードをcloneする
$ git clone https://github.com/dodonki1223/template_sample_rails_6.git
# cloneしてきたtempalte_sample_rails_6ディレクトリに移動
$ cd template_sample_rails_6/
# tempalte_sample_rails_6を動かす
$ docker-compose up rails
こちらのURL:http://localhost:3000/ にアクセスすることで動作確認できます
Dockerがインストールされていないと動かすことはできません
環境について
バージョン情報
ソフトウェアスタック | バージョン |
---|---|
Rails | 6.0.2.1以上 |
Ruby | 2.6.5 |
PostgreSQL | 12 |
Node.js | 12 |
Yarn | 12 |
Bundler | 2.1.2 |
Redis | 5.0 |
ローカルでの開発について
基本的にDockerを使用して開発を行えるようになっているのでPCにDockerがインストールされていれば問題ないです
PostgreSQLへの接続情報
DB情報 | 値 |
---|---|
Host | 127.0.0.1 |
User | root |
Password | |
Port | 5432 |
DatabaseName | dev_sample_db |
CI(継続的インテグレーション)/CD(継続的デリバリー)環境 - Lint/Test/Deploy
自動テスト、静的コード解析、WebアプリケーションのデプロイはCircleCIで実装されていてデプロイ先にはHerokuを使用しているのでCircleCIとHerokuの設定も必要になります
またCircleCIの通知用(デプロイの実行、完了通知)としてSlackも使用しているので自分用のWorkspaceを作成することをオススメします
設定
Heroku
Herokuを使用し簡単にWebアプリケーションをデプロイできるようにします
Heroku CLIのインストール
Herokuをコマンドラインから使用できるように Heroku CLI
をインストールします
下記コマンドを実行してインストールします
詳しくは公式ドキュメントを参照してください
$ brew tap heroku/brew && brew install heroku
Herokuにアプリケーションを作成する
template_sample_rails_6では Production環境
と Development環境
を作成します
Production環境
と Development環境
それぞれに自動でデプロイされる仕組みがCircleCIに組み込まれています
Production環境を作成する
# template-rails-prdの部分はアプリケーションの名前なので自由に決めてもらって構いません
$ heroku create template-rails-prd
Development環境を作成する
# template-rails-devの部分はアプリケーションの名前なので自由に決めてもらって構いません
$ heroku create template-rails-dev
Personal apps ページにアクセスして Production環境
と Development環境
がそれぞれできていればOKです
手動でデプロイする
HerokuへPushする
$ git push heroku master
https://dashboard.heroku.com/apps/アプリ名 にアクセスして下記のような表示なっていればOKです
Pushしたアプリケーションのマイグレーションを実行する
$ heroku run bin/rake db:migrate
Webアプリケーションがデプロイされたか確認する
$ heroku open
下記のように表示されていればで手動デプロイ完了です
Slack
CircleCIで デプロイ承認通知
と デプロイ完了通知
を行うために自分専用のワークスペースを作成し設定します
ワークスペースは作成してあることを前提に進みます
Incoming Webhookをインストール
https://ワークスペース名.slack.com/apps にアクセスし webhook
と入力します
検索のリストに出てきた Incoming Webhook
をクリックします
Slackに追加
をクリックします
通知させるチャンネル
を選択し Incoming Webhook インテグレーションの追加
をクリックします
このサンプルでは general
チャンネルに通知されるように設定しています
詳細の設定画面では 名前とアイコンをカスタマイズすることでなんの通知かわかりやすくなるので設定しておきましょう
設定を保存する
をクリックして下記の画面になれば大丈夫です
スタンプを追加する
通知用にカスタム絵文字を使用するので以下の3つを追加してください
追加する時は カスタム絵文字を追加する
をクリックしてください
- :circleci-fail:
- :circleci-pass:
- :github_octocat:
CircleCI
CircleCIで自動テスト、静的コード解析、Webアプリケーションのデプロイをできようにするため
CircleCIにプロジェクトの設定を行います
プロジェクトの設定を行う
こちらのURLに 「https://app.circleci.com/projects/project-dashboard/github/GitHubのユーザー名」 アクセスし対象のプロジェクトの Set Up Project
をクリックします
Start Building
をクリックします
config.yml
は既に存在しているので Add Manually
をクリックします
Start Building
をクリックします
CircleCIが実行されます。 main
をクリックして詳細を確認します
workflowの実行状態が確認できます
時間が経つとworkflowが失敗することが確認できます
これはCircleCIに環境変数など設定していないためです
環境変数の設定を行う
Project Settings
をクリックします
Environment Variables
メニューをクリックして環境変数を設定していきます
環境変数は下記の4つの設定が必要です
環境変数名 | 説明 |
---|---|
HEROKU_API_KEY | HerokuのAPIキー |
HEROKU_APP_NAME_DEVELOPMENT | HerokuのDevelopment環境のアプリ名 |
HEROKU_APP_NAME_PRODUCTION | HerokuのProduction環境のアプリ名 |
SLACK_WEBHOOK | SlackのWebHookのURL |
HEROKU_API_KEY
https://dashboard.heroku.com/account にアクセスしAPI Keyの Reveal
をクリックしてAPI KeyをコピーしてCircleCIに設定してください
HEROKU_APP_NAME_DEVELOPMENT、HEROKU_APP_NAME_PRODUCTION
https://dashboard.heroku.com/apps にアクセスして Development環境とProduction環境のアプリ名をコピーして設定してください
SLACK_WEBHOOK
Incoming Webhook
のページにアクセスし 設定を編集
をクリックします
編集画面の Webhook URL
の URLをコピーする
をクリックし環境変数に設定します
以下のようになっていればOKです
再度実行して正しく動作することを確認する
https://app.circleci.com/pipelines/github/GitHubのアカウント名/リポジトリ名 にアクセスします
失敗したWorkflowをクリックします
Rerun Workflow from Failed
をクリックして失敗した箇所から再度実行します
再度実行するとSlackにApprove通知が来るので Visit Workflow
をクリックします
Workflowへ飛ぶので 停止中の approval-job
をクリックします
もし処理を続行させたくない場合は Rerun
のところから Cancel Workflow
をクリックすることで処理を終了させることができます
Approve
をクリックし処理を続行させます
デプロイが完了するとSlackにデプロイ完了通知が来ます
これで自動デプロイ完了です
開発
開発環境にはRails以外にもRedisやSidekiq、Webpackerが導入されています
起動方法やコマンドの実行方法を解説します
Railsを起動する
$ docker-compose up rails
※PostgreSQL
、 Redis
も一緒に起動します
Webpackerを起動する
$ docker-compose up webpacker
Sidekiqを起動する
$ docker-compose up sidekiq
Runnerを起動する
Runnerはコマンドを実行するためのサービスになります
rakeコマンドやRSpecを実行するために使用します
$ docker-compose run runner
以下の説明は docker-compose run runner
実行後の説明になります
RSpecを実行する
起動後のRunnerはデフォルトだと RAILS_ENV=development
になっているためコマンドで明示的に RAILS_ENV=test
を指定して実行します
# bundle exec ありバージョン
$ RAILS_ENV=test bundle exec rspec --format progress
# bundle exec なしバージョン
$ RAILS_ENV=test rspec --format progress
RuboCopを実行する
# bundle exec ありバージョン
$ bundle exec rubocop --require rubocop-rspec -D -P
# bundle exec なしバージョン
$ rubocop --require rubocop-rspec -D -P
Rails Best Practicesを実行する
# bundle exec ありバージョン
$ bundle exec rails_best_practices .
# bundle exec なしバージョン
$ rails_best_practices .
Brakemanを実行する
# bundle exec ありバージョン
$ bundle exec brakeman
# bundle exec なしバージョン
$ brakeman
rakeコマンドを実行する
# bin/ ありバージョン
$ bin/rake about
# bin/ なしバージョン
$ rake about
railsコマンドを実行する
# bin/ ありバージョン
$ bin/rails g --help
# bin/ なしバージョン
$ rails g --help
DBに接続する
# bin/ ありバージョン
$ bin/rails dbconsole
# bin/ なしバージョン
$ rails dbconsole
その他
開発時のTipsを紹介します
やってもやらなくても良いです
GitHooksのpre-pushを使用する
pre-pushを使用してmaster、developmentブランチにpushする前に静的コード解析を実行してCIで落ちないようにします
CIの静的コード解析で落ちて修正するのは時間がかかるのでpush前に検知できた方が良いと思います
ローカルのgitを使用しているのでDockerで開発しているのにローカルの環境も整える必要があり2重管理になってしまうところが悩みどころです……
pre-pushファイルを動作させるためにテンプレートファイルをコピーする
$ cp .github/hooks/pre-push .git/hooks/pre-push
pre-pushのファイルに実行権限ないとhookされないので実行権限を与えてやる
$ chmod 755 .git/hooks/pre-push
解説
Docker
Docker環境に関しては以下の記事とリポジトリを参考に作成しました。ほとんどが以下の記事を真似ているので違う箇所と説明が足りない部分だけ解説します
まずは翻訳された記事から読むと良いでしょう(原文だとdocker-compose.ymlのバージョンが古くてハマります)
- Ruby on Whales: Dockerizing Ruby and Rails development
- クジラに乗ったRuby: Evil Martians流Docker+Ruby/Rails開発環境構築(翻訳)
- terraforming-rails/examples/dockerdev
Dockerfile
Dockerfileはほぼ一緒だと思います
docker-compose.yml
docker-compose.ymlは変更しているので説明します
サービスの一覧
サービス自体は参考した記事とリポジトリと一緒のような構成になっています
サービス名 | 概要 |
---|---|
rails | Railsアプリを動かすためのサービス |
runner | Railsと同じ環境でRailsアプリのコマンドを実行するためのサービス |
sidekiq | バックグラウンドジョブを実行するためのサービス |
redis | インメモリデータベースサービス |
webpacker | Rubyでwebpackを使用できるサービス(JavaScriptモジュールバンドラー) |
postgres | リレーショナルデータベースサービス |
共通化
extension-fields(Version3.4からの機能)を使用してservicesを共通化しています
共通名 | 概要 |
---|---|
x-app | Dockerfileで定義したアプリケーションコンテナの構築で必要な情報を提供する |
x-backend-volumes | Rubyのサービスで共有するボリュームを提供する |
x-backend | Rubyのサービスで共有する振る舞いを提供する |
rails
railsサービスの実行時には以下のコマンドを実行します
何も考えずにRailsが実行できるようにしています
# Gemのインストール
$ bundle install
# package.json にリスト化されている全ての依存関係を node_modules 内にインストールします
$ yarn install --check-files
# DBの作成&マイグレーションを実行
$ bin/rake db:create
$ bin/rake db:migrate
# `A server is already running` の回避
$ rm -f tmp/pids/server.pid
# Railsを実行
$ bundle exec rails server -b 0.0.0.0
下記コマンドに関しては初回起動時だけ必要なコマンドなので削除しても良いでしょう
$ bin/rake db:create
postgres
bin/rake db:create
を実行すると下記のようなエラーが出ます
FATAL: role "root" does not exist
Couldn't create 'test_eroge_release' database. Please check your configuration.
rake aborted!
PG::ConnectionBad: FATAL: role "root" does not exist
エラーを出さないために予め root
ユーザーを作成して置く必要があります
下記のSQLは postgres - Docker Hubの Initialization scripts
の項目を参考に起動時に実行されるように設定しています
-- rootユーザーを作成する
CREATE USER root WITH SUPERUSER;
-- root ROLEはログイン可能にする
ALTER ROLE root LOGIN;
Docker高速化
:cached
を使用しDocker for Macでホストのディレクトリをマウントした時の遅さを回避しています
:cached
設定はコンテナで実行された書き込みはホストにすぐに反映されるがホストで実行された書き込みは遅延が生じる可能性がある
詳しくは以下の記事を読むと良いでしょう
x-backend-volumes: &backend-volumes
volumes:
- .:/app:cached
永続化データはホストでマウントせずに Volumes を使用することにより遅さを回避
x-backend-volumes: &backend-volumes
volumes:
- bundle:/bundle
- rails_cache:/app/tmp/cache
- node_modules:/app/node_modules
- packs:/app/public/packs
CircleCI
Workflowで使用しているJobについて解説します
setup
setup以降のJobで使用するための資材を作成します
このJobで作成した資材は Workspace を使用してJob間でデータを共有します
lint
以下の3つの静的コード解析を実行します
- Rubocop
- Rails Best Practices
- Brakeman
setup
Jobが成功した時に実行されます
test
RSpecを実行しコードカバレッジも出力します
コードカバレッジは ARTIFACTS
に出力されます
以下のリンクをクリックしてください
コードカバレッジを確認できます
setup
Jobが成功した時に実行されます
document
Rails ERDを実行しER図を出力します
以下のリンクをクリックしてください
ER図を確認できます
setup
Jobが成功した時に実行されます
slack/approval-notification
Orbsの circleci/slack@3.4.2 を使用してSlackにCircleCIから承認通知を行います
circleci/slack@3.4.2 の approval-notification jobを使用しています
こちらのJobは lint
, test
Jobが成功した時に実行されます。また master
, development
ブランチでしか実行されません
approval-job
承認処理用のJobです
-
Approve
ボタンをクリックすると後続の Jobを実行させます -
Cancel
ボタンを押すと後続の処理を続行しません
処理を止めたい場合はWorkflowのキャンセルを行ってください
詳しくは ここのドキュメント を確認してください
こちらのJobは slack/approval-notification
Jobが成功した時に実行されます
deploy-heroku-development
HerokuのDevelopment環境へデプロイを実行します
こちらのJobは approval-job
Jobで Approve
ボタンが押された時に実行されます。また development
ブランチでしか実行されません
deploy-heroku-production
HerokuのMaster環境へデプロイを実行します
こちらのJobは approval-job
Jobで Approve
ボタンが押された時に実行されます。また master
ブランチでしか実行されません