LoginSignup
9
7

More than 3 years have passed since last update.

[Rails]自動テスト〜自動デプロイまでをDockerコンテナで実行する方法

Last updated at Posted at 2019-04-28

こちらの記事の続きです

RSpec on DockerでChromeブラウザテストを行う方法
DockerでのRuby on Rails環境構築を一つずつ詳解する
CircleCI→herokuのCI/CDパイプライン構築手順

手順としては上記記事の続きであり
・Dockerでの開発環境を構築している
・単体テスト・統合テストをDockerコンテナ内で実行できる
・Github→CircleCI→herokuのCI/CDパイプラインを構築している
を前提としています。
今回はこれらを組み合わせて
CicleCIでの自動テスト環境にdocker-composeを利用していきたいと思います。
これにより開発環境、テスト環境、本番環境の環境差分が無くなります。

CircleCIでDocker使用時はMachine Executor

CircleCIでは通常はdocker環境でテストを実行させるように
config.ymlを設定しますがdocker-composeを自分で使いたい場合は
MachineExecutor(VM環境)を選択します。
(CircleCIのDocker環境ではdocker-composeのvolumesが実行できません)

Machine Executorを使ったconfig.yml

config.yml
version: 2.0
jobs:
  build:
    machine: true
    steps:
      - run:
          name: Start container
          command: docker-compose up -d

基本的には
CircleCI→herokuのCI/CDパイプライン構築手順
こちらで書いたconfig.ymlと同じです。
相違点はdockerとimageを書いていた部分を「machine: true」に変更します。
これでCircleCIのLinuxVM上でコマンドが実行されます。

HerokuのContainerRegistryでデプロイ

次にheroku本番環境でもDockerコンテナが実行可能です。
サービス名はContainer Resigtryという名前で下記リンクが公式です。
Container Registry公式

$ heroku container:login --app APP_NAME
$ heroku container:push web --app APP_NAME
$ heroku container:release web --app APP_NAME

上記のコマンドのみでherokuでDockerコンテナを実行することができます。
container:pushで、Dockerfileを元にimage build、とheroku registryへのpushが実行されます。
そしてcontainer:relaseでpushしたイメージがリリースされます。
remoteが複数になるとapp名が必要になるので念のため
--appで明示的に指定しています。

また、初回はAPP,DB作成のため以下のコマンドが必要になります。

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

つまりheroku containerコマンドをcircleci/config.ymlに
記述すればデプロイが可能ですね。

.circleci/config.yml の設定

heroku cointainer:loginが必要なので
公式にあるように以下のコマンドが必要です。

#heroku container:login
docker login --username=_ --password=${HEROKU_API_KEY} registry.heroku.com

.circleci/config.yml 完成版

そして完成版がこちらになります。

.circleci/config.yml
version: 2.0
jobs:
  build:
    machine: true
    working_directory: ~/repo
    steps:
      - checkout
      - run:
          name: Start container
          command: docker-compose up -d

      - run: docker-compose exec web rails db:create
      - run: docker-compose exec web rails db:schema:load

      - run:
          name: run tests
          command: |
            mkdir /tmp/test-results
            TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | \
              circleci tests split --split-by=timings)"

             docker-compose exec web rspec \
              --format progress \
              --format RspecJunitFormatter \
              --out /tmp/test-results/rspec.xml \
              --format progress \
              $TEST_FILES

      - store_test_results:
          path: /tmp/test-results
      - store_artifacts:
          path: /tmp/test-results
          destination: test-results

  deploy_stage:
    machine: true
    steps:
      - checkout
      - run:
          name: install Heroku CLI
          command: curl https://cli-assets.heroku.com/install.sh | sh
      - run:
          name: heroku maintenance on
          command: heroku maintenance:on --app ${HEROKU_APP_NAME_STAGE}
      - run:
          name: deploy to heroku_staging
          command: |
            docker login --username=_ --password=${HEROKU_API_KEY} registry.heroku.com
            heroku container:push web --app ${HEROKU_APP_NAME_STAGE}
      - run:
          name: rails db migrate
          command: heroku run rails db:migrate --app ${HEROKU_APP_NAME_STAGE}
      - run:
          name: release app
          command: heroku container:release web --app ${HEROKU_APP_NAME_STAGE}
      - run:
          name: heroku maintenance off
          command: heroku maintenance:off --app ${HEROKU_APP_NAME_STAGE}

  deploy_prod:
    machine: true
    steps:
      - checkout
      - run:
          name: install Heroku CLI, if necessary
          command: curl https://cli-assets.heroku.com/install.sh | sh
      - run:
          name: heroku maintenance on
          command: heroku maintenance:on --app ${HEROKU_APP_NAME_PROD}
      - run:
          name: deploy to heroku_staging
          command: |
            docker login --username=_ --password=${HEROKU_API_KEY} registry.heroku.com
            heroku container:push web --app ${HEROKU_APP_NAME_PROD}
      - run:
          name: rails db migrate
          command: heroku run rails db:migrate --app ${HEROKU_APP_NAME_PROD}
      - run:
          name: release app
          command: heroku container:release web --app ${HEROKU_APP_NAME_PROD}
      - run:
          name: heroku maintenance off
          command: heroku maintenance:off --app ${HEROKU_APP_NAME_PROD}

workflows:
  version: 2
  build-deploy:
    jobs:
      - build
      - deploy_stage:
          requires:
            - build
          filters:
            branches:
              only:
                - staging
      - deploy_prod:
          requires:
            - build
          filters:
            branches:
              only:
                - master

必要な環境変数は
HEROKU_API_KEY、HEROKU_APP_NAME_STAGE、HEROKU_APP_NAME_PRODです。
それぞれCircleCIのUIから設定してください。

これで自動テストと、検証環境、本番環境への自動デプロイ。
そしてそれらがDockerコンテナで実行されるCI/CDが構築できました。

注意点

Dockerfileに下記の記述が無いとherokuコンテナで
railsが起動しない場合があるので注意が必要です。

Dockerfile

 CMD ["rails", "server", "-b", "0.0.0.0"]

ここの設定については
DockerでのRuby on Rails環境構築を一つずつ詳解する
こちらで書いています。

9
7
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
9
7