devops

CircleCI+Herokuで始めるCI/CD

Introduction

こんにちは,CI/CDしてますか??

ReactJSで予約フォームを作っています.
予約フォームをDockerlizeしてどこのホスティングサービスで動かそうか迷っていました.

下記の記事を見つけ,Herokuをホスティングサービスに選びました.
Building Docker Images with heroku.yml Is Generally Available

いちいち手動でDockerlizeしてbuildしてdeployとクソ面倒くさいことはしたくなかったので,CircleCIでCI/CDの設定も行いました.

Architecture

  • Github
    CircleCIと連携します.
  • CircleCI
    継続的インテグレーション(デリバリー)サービスです。
    コミットからデプロイまでのパイプラインを作成し、継続的な統合/配信を使用してソフトウェア開発プロセスを自動化できます。
    https://circleci.com/product/
  • Heroku
    アプリケーションの開発から実行、運用までのすべてをクラウドで完結できる PaaS(サービスとしてのプラットフォーム)です。
    https://jp.heroku.com/

構成としてはこのようになります.
structure-image

  1. 開発者がコードをGithubにデプロイ
  2. GithubへのデプロイをCircleCIが検知
  3. CircleCIがイメージのビルドを行う
  4. イメージのビルドが終わったらHerokuへデプロイ
  5. HerokuがDockerを動かす

Dependency

  • create-react-app
  • Docker

SetUp

まずは事前準備をしていきます.

Heroku

Herokuのダッシュボード,もしくはCLIツールでHerokuアプリを作ります.

React Code

create-react-appで作られるページをDockerで動かします.

http://localhost:3000 にアクセスしてReactのデフォルトページが表示されることを確認します.

Dockerlize

ReactのソースコードをDockerで動かせるようにイメージを作成します.

続いてdocker-compose.ymlファイルを作成します.

yml:docker-compose.yml
version: "3"

services:
contact:
build: .
image: samplepage:0.9
container_name: samplepage
tty: true
ports:
- "5000:5000"
volumes:
- yarn-cache:/Users/daichi/Library/Caches/Yarn/v4

volumes:
yarn-cache:

<pre><code><br />これでdocker-compose up -d で http://localhost:5000 でReactのsamplepageが確認できるようになりました.

## Push Code to Github
ReactのソースコードをGithubにPushします.
リポジトリはPublicでもPrivateでも問題ありません.

サンプルとして.gitignoreファイルを載せておきます.

.gitignore
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

*.bk

SetUp CircleCI

CircleCIでアカウントを作成し,Githubアカウントも連携します.
連携が完了すると,GithubのリポジトリがCircleCIのADD PROJECTSにリスト表示されるので,samplepageを選択します.

事前準備としてCircleCIの環境変数にHerokuの情報を設定する必要があります.
CircleCIのダッシュボード画面からSETTINGS→Githubのアカウント→対象のリポジトリと移動します.
Environment Variablesで環境変数を設定します.

  • HEROKU_API_KEY
    heroku auth:token コマンドで表示されるTokenをセットする.
    Tokenが表示されない場合はheroku authorizations:create -d "getting started token" コマンドでTokenを作成する.
  • HEROKU_APP_NAME
    Herokuで作成したアプリの名前をセットする.
  • HEROKU_API_TOKEN
    https://dashboard.heroku.com/account のAPI Keyの値をセットする.
  • HEROKU_LOGIN
    Herokuにログインするメールアドレスをセットする.

CircleCIはDockerを使ってソースコードをビルドします.
CircleCIのDockerでDockerイメージを作成し,Herokuへデプロイする.circleci/config.ymlファイルを作成し,githubにソースコードをPushするとCicleCIでbuild,deploy to herokuが出来るようになります.

yml:.circleci/config.yml
version: 2
jobs:
build:
machine:
image: circleci/classic:edge
steps:
- checkout
- run:
name: docker-compose build
command: docker-compose build
deploy:
machine:
image: circleci/classic:edge
steps:
- checkout
- run:
name: "build docker image"
# registry.heroku.com/${HEROKU_APP_NAME}/webは変更することは出来ません.
command: docker build --rm=false -t registry.heroku.com/${HEROKU_APP_NAME}/web .
- run:
name: setup heroku command
# CircleCIからHerokuへデプロイするためのスクリプトを実行
command: bash .circleci/setup_heroku.sh
- run:
name: heroku maintenance on
# Herokuのアプリをメンテナンス中にする
command: heroku maintenance:on --app ${HEROKU_APP_NAME}
- run:
# HEROKU_AUTH_TOKEN is generated by <code>heroku auth:token</code>
name: "push container to registry.heroku.com"
# Herokuへログインし,作成したイメージをPush,Releaseします.
command: |
docker login --username=_ --password=$HEROKU_AUTH_TOKEN registry.heroku.com
docker push registry.heroku.com/${HEROKU_APP_NAME}/web
heroku container:push web --app ${HEROKU_APP_NAME}
heroku container:release web --app ${HEROKU_APP_NAME}
- run:
name: heroku maintenance off
# メンテナンスモードをオフにします.
command: heroku maintenance:off --app ${HEROKU_APP_NAME}
workflows:
version: 2
build_and_deploy:
jobs:
# - build
- deploy:
# requires:
# - build
filters:
branches:
only: master

<pre><code><br />filters: branch でmasterブランチにデプロイされたときだけ,deploy jobを実行するようにしています.

最後にCircleCIからHerokuへデプロイするためのスクリプトを作成します.
これはCircleCI上のDockerで実行されるものなので必須です.

bash:heroku_setup.sh
# git remote add heroku https://git.heroku.com/circleci-demo-python-flask.git
wget https://cli-assets.heroku.com/branches/stable/heroku-linux-amd64.tar.gz
sudo mkdir -p /usr/local/lib /usr/local/bin
sudo tar -xvzf heroku-linux-amd64.tar.gz -C /usr/local/lib
sudo ln -s /usr/local/lib/heroku/bin/heroku /usr/local/bin/heroku

cat > ~/.netrc << EOF
machine api.heroku.com
login $HEROKU_LOGIN
password $HEROKU_API_KEY
EOF
# machine git.heroku.com
# login $HEROKU_LOGIN
# password $HEROKU_API_KEY

# Add heroku.com to the list of known hosts
ssh-keyscan -H heroku.com >> ~/.ssh/known_hosts

これで事前準備は完了しました.

Deploy

githubへPushするとCircleCIでJobが走ります.

Conclusion

すごい簡単にCI/CD設定ができました.感動です.

ただCircleCIでのイメージのビルドで毎回,yarn install, yarn buildをしているので1デプロイあたり4分ぐらいかかってしまいます.
ここをCircleCIのcacheを使うか,dockerのマルチステージ機能を使うかで解消したいと思います.

-devops
-, ,

Translate »