LoginSignup
1
0

More than 1 year has passed since last update.

Rails×RSpec×Docker×CircleCI

Last updated at Posted at 2021-11-22

はじめに

RailsアプリをDocker上で構築し、CircleCIを用いて、RSpecによる自動テスト、またHerokuへの自動デプロイの仕組みを実現していく。

環境

  • フレームワーク : Rails
  • テストフレームワーク : RSpec
  • データベース : MySQL
  • コンテナ : Docker(Docker Compose)
  • CI/CDツール : CircleCI
  • サーバー : Heroku

前提
GitHub、Herokuに登録済み
Docker、Docker Composeをインストール済み

参考
山浦清透さんのDocker超入門講座 合併版 | ゼロから実践する4時間のフルコースという動画を参考にさせていただく。

Docker環境でRailsアプリを作成

作業用ディレクトリを用意し、必要なファイルを作成する。
今回はqiita-railsというディレクトリ内で作業していく。

qiita-rails/
          ├ src/
              └ Gemfile
          ├ docker-compose.yml
          └ Dockerfile
Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 6.1.4', '>= 6.1.4.1'
docker-compose.yml
version: '3'
services:
  db:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - ./src/db/mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - ./src:/app
    ports:
      - "3000:3000"
    environment:
      RAILS_ENV: development
    depends_on:
      - db
Dockerfile
FROM ruby:2.7

RUN 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 nodejs yarn \
  && apt-get -y install imagemagick
WORKDIR /app
COPY ./src /app
RUN bundle config --local set path 'vendor/bundle' \
  && bundle install

作業用ディレクトリに移動後、Railsアプリを作成。

$ docker-compose run rails new . --force --database=mysql

Gemfileが更新されたのでコンテナのイメージをビルドし直す。

$ docker-compose build

database.ymlのdefaultのpasswordとhostを設定。

src/config/database.yml
.
.
.
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db
.
.
.

データベースを作成する。

$ docker-compose run web rails db:create

コンテナを起動する。

$ docker-compose up

ブラウザでlocalhost:3000を開き、以下の画面が表示されていれば成功。
rails_welcome.png

Herokuの設定

Heroku、Heroku Container Registryにログインし、アプリを作成。

$ heroku login
$ heroku container:login
$ heroku create qiita-rails

MySQL用のアドオンを追加する(Herokuにクレジットカードの登録が必要)。

$ heroku addons:create cleardb:ignite -a qiita-rails

database.ymlのproductionを設定する。

src/config/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 qiita-rails

でこれらの環境変数を確認し

$ heroku config:add

でそれぞれ設定していく。

作業用ディレクトリに、start.shを追加し、Dockerfileを編集する。

qiita-rails/
          ├ src/
          ├ docker-compose.yml
          ├ Dockerfile
                    └ 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
Dockerfile
FROM ruby:2.7

ENV RAILS_ENV=production

RUN 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 nodejs yarn \
  && apt-get -y install imagemagick
WORKDIR /app
COPY ./src /app
RUN bundle config --local set path 'vendor/bundle' \
  && bundle install

COPY start.sh /start.sh
RUN chmod 744 /start.sh
CMD ["sh", "/start.sh"]

Herokuに環境変数を追加する。

$ heroku config:add RAILS_SERVE_STATIC_FILES='true' -a qiita-rails

CircleCIでCI/CDを構築

事前にGitHubにリポジトリを作成しておく。

GemfileにRSpecを追加する。

Gemfile
group :development, :test do
  gem 'rspec-rails'
end

Gemfileが更新されたのでコンテナのイメージをビルドし直す。

$ docker-compose build

下記ののコマンドでwebコンテナの中に入り、bashが使えるようにるので、

$ docker-compose exec web bash

RSpecをインストールする。

$ rails generate rspec:install

CircleCIにGitHubでログインする。
スクリーンショット 2021-11-23 3.22.04.png

作業用ディレクトリに、.circleciディレクトリ、config.ymlを追加する。

qiita-rails/
          ├ src/
          ├ docker-compose.yml
          ├ Dockerfile
                    ├ start.sh
                    └ .circleci/
                    └ config.yml
.circleci/config.yml
version: 2.1
orbs:
  ruby: circleci/ruby@1.1.2
  heroku: circleci/heroku@1.2.3

jobs:
  build:
    docker:
      - image: circleci/ruby:2.7
    working_directory: ~/qiita-rails/src
    steps:
      - checkout:
          path: ~/qiita-rails
      - ruby/install-deps

  test:
    docker:
      - image: circleci/ruby:2.7-node
      - image: circleci/mysql:5.5
        environment:
          MYSQL_ROOT_PASSWORD: password
          MYSQL_DATABASE: app_test
          MYSQL_USER: root
    environment:
      BUNDLE_JOBS: "3"
      BUNDLE_RETRY: "3"
      APP_DATABASE_HOST: "127.0.0.1"
      RAILS_ENV: test
    working_directory: ~/qiita-rails/src
    steps:
      - checkout:
          path: ~/qiita-rails
      - ruby/install-deps
      - run:
          name: Database setup
          command: bundle exec rails db:migrate
      - run:
          name: yarn Install
          command: yarn install
      - run: 
          name: webpack
          command: bundle exec bin/webpack
      - run:
          name: Rspec
          command: bundle exec rspec

  deploy:
    docker:
      - image: circleci/ruby:2.7
    steps:
      - checkout
      - setup_remote_docker:
          version: 19.03.13
      - heroku/install
      - run:
          name: heroku login
          command: heroku container:login
      - run:
          name: push docker image
          command: heroku container:push web -a $HEROKU_APP_NAME
      - run:
          name: release docker image
          command: heroku container:release web -a $HEROKU_APP_NAME
      - run:
          name: database setup
          command: heroku run bundle exec rake db:migrate RAILS_ENV=production -a $HEROKU_APP_NAME

workflows:
  version: 2
  build_test_and_deploy:
    jobs:
      - build
      - test:
          requires:
            - build
      - deploy:
          requires:
            - test
          filters:
            branches:
              only: main

database.ymlのtestを設定する。

src/config/database.yml
.
.
.
test:
  <<: *default
  database: app_test
  host: <%= ENV.fetch('APP_DATABASE_HOST') { 'db' } %>
.
.
.
$ heroku config:add

でmaster.keyの値をHerokuの環境変数RAILS_MASTER_KEYとして追加する。

CicleCIのサイトにログイン後、Projects→qiita-rails→Project Settings→Environment Variables→Add Environment Variablesと進み、

  • Name:HEROKU_APP_NAME, Value:qiita-rails
  • Name:HEROKU_API_KEY, Value:(HerokuのサイトでAccount settingsから確認)

を追加する。

最後に

これで、gitにpush後GitHub上でCreate pull requestを行うと自動でRSpecによるテストが開始し、それが成功するとMerge pull requestが押せるようになり、Merge pull requestを実行するとまた自動でRSpecによるテストが開始し、それが成功すると自動でHerokuにデプロイされるという仕組みを実現することができた。
いずれサーバー環境をHerokuからAWSに切り替えようと考えている。

1
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
1
0