pavlog

ウェブエンジニアがあれやこれやを書きます

【CI/CD】now + CircleCI を使ってお手軽にリリースプロセスを自動化して、最速でデプロイする

f:id:paveg:20190321040810p:plain

みなさんCI/CD回してますか?

アジャイル開発手法*1は、開発を行なう上で有効なケースが多く、そういった手法で開発を進める上では、CI/CDを使うことがとても生産性に寄与します。ソースコードへ変更が行われる度に自動でコードテストを行ったり・デプロイをすることによって実行忘れやオペレーションミスを防ぎ、かつ品質を高めることが可能です。

CI/CDとは「Continous Integration/Contiious Delivery」の略で、日本語では継続的インティグレーション/継続的デリバリーといいます。CI/CDは1つの技術を指すものでなく、ソフトウェアの変更を常にテストして自動で本番環境にリリース可能な状態にしておく、ソフトウェア開発の手法を意味します。CI/CDを取り入れると、バグを素早く発見したり、変更を自動でリリースしたりできるようになります。

CI/CDのエキスパートが解説:CI/CDとは何か? なぜ今、必要とされるのか? (1/3):CodeZine(コードジン)

小さい粒度の変更を素早くテスト・リリースしてフィードバックを得るイテレーションを回し続けることは開発を続ける上で非常にメリットがあります。

最近だと、jawsdays で登壇されてた方のスライドがとてもよかったです( ポジティブな Toriさん )。


上記のスライドほど複雑なことはしないですが、今回は個人開発でもお手軽に継続的なインテグレーションを回す環境をnowcircleCI を使って作ってみます。


今回使用するサービス・プラットフォーム


What is now


now とは Next.js を開発しているzeitが提供するサーバーレスでデプロイが可能な新しい PaaS*2 です。

Now makes serverless application deployment easy.

Don’t spend time configuring the cloud. Just push your code.

Now - ZEIT

簡単な now の設定や使い方については以前の記事をご参照ください。

www.pavlog.tokyo

サーバーレスで高速にデプロイを可能にするためのプラットフォームであると覚えておくと良いです。


What is CircleCI


CircleCI とは「継続的インテグレーションと継続的デリバリー」、つまりCIにおけるリーディングソフトウェアです*3

circleci.jp

CircleCI はWebサービスなので、登録を行うことですぐ使い始めることが可能です。

最近のウェブアプリケーション開発を行なっている会社では結構CircleCIを使っている企業は多いと思います。

自動デプロイのための準備


ここからが本題です。今回は nowCircleCI を使って、自動デプロイの設定をしていきます。

事前に circleCIのプロジェクトセットアップと now の登録は済ませておいてください。

実際に僕が今運用をしているrepositoryを使って説明します。

( create-react-app から作成した作りかけのポートフォリオサイトです。)

用意しないといけないのは、下記のファイルです。

  • now.json
    • now の設定ファイル
  • .circleci/config.yml
    • CircleCI の設定ファイル
  • Dockerfile
    • Pull Requestでのデプロイに必要

now.json


{
  "version": 2,
  "name": "portfolio",
  "builds": [
    {"src": "package.json", "use": "@now/static-build", "config": {"distDir": "build"}}
  ],
  "routes": [
    {"src": "/static/(.*)", "headers": {"cache-control": "s-maxage=31536000,immutable"}, "dest": "/static/$1"},
    {"src": "/favicon.ico", "dest": "/favicon.ico"},
    {"src": "/asset-manifest.json", "dest": "/asset-manifest.json"},
    {"src": "/manifest.json", "dest": "/manifest.json"},
    {"src": "/precache-manifest.(.*)", "dest": "/precache-manifest.$1"},
    {"src": "/service-worker.js", "headers": {"cache-control": "s-maxage=0"}, "dest": "/service-worker.js"},
    {"src": "/(.*)", "headers": {"cache-control": "s-maxage=0"}, "dest": "/index.html"}
  ],
  "alias": [
    "pavlog"
  ]
}

.circleci/config.yml


version 2.1を使って config.yml を記述しています。

now というジョブが重要で、今回の設定の肝となります。

nowのグローバルインストールと now(デプロイコマンド)の実行をトークンを指定して行なっています。

またブランチにmasterブランチを指定することによって、PRがマージされたタイミングでデプロイが実行されます。

version: 2.1
defaults: &defaults
  working_directory: ~/repo
  docker:
    - image: circleci/node:11.12

commands:
  prepare:
    steps:
      - checkout
      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "package.json" }}
            - v1-dependencies-
      - run: npm install
      - save_cache:
          paths:
            - node_modules
          key: v1-dependencies-{{ checksum "package.json" }}

jobs:
  now:
    <<: *defaults
    steps:
      - prepare
      - run:
          name: install now
          command: sudo npm install -g --unsafe-perm now
      - run:
          name: deploy
          command: |
            now -t ${ZEIT_TOKEN}
            now alias pavlog -t ${ZEIT_TOKEN}

workflows:
  deploy:
    jobs:
      - now:
          filters:
            branches:
              only: master

トークンを取得する


こちらからデプロイ用のトークンを取得します。

f:id:paveg:20190321032842p:plain

CREATEを押してから、任意の名前をつけてCREATE TOKENを実行しTokenを作成します。

f:id:paveg:20190321032938p:plain

作成後に、トークンをクリップボードにコピーしてください。

次にCircleCIで下記のようなURLから環境変数の設定行います。

  • usernameは個人のgithub user name
  • reponameは個人のgithub repo name

https://circleci.com/gh/username/reponame/edit#env-vars

f:id:paveg:20190321033307p:plain

valueへ先ほどコピーしたTokenを貼り付けて Add Variableを押します。

Dockerfile


ARG NODE_VERSION=11.12.0
FROM node:${NODE_VERSION}-alpine as build
ENV NODE_ENV production
WORKDIR /usr/src/app
COPY package.json package-lock.json ./
RUN npm install
COPY . ./
RUN npm run build

FROM nginx:1.15.2-alpine
COPY --from=build /usr/src/app/build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

実際に自動デプロイを行う


修正PRの作成


~/src/github.com/paveg/portfolio master*
❯ git checkout -b check-auto-deployment
Switched to a new branch 'check-auto-deployment'
...

~/src/github.com/paveg/portfolio check-auto-deployment*
❯ git add README.md public/index.html src/containers/About/About.tsx

~/src/github.com/paveg/portfolio check-auto-deployment*
❯ git commit -m "Fix README.md and public/index.html"
[check-auto-deployment 8781373] Fix README.md and public/index.html
 3 files changed, 4 insertions(+), 4 deletions(-)

~/src/github.com/paveg/portfolio check-auto-deployment
❯ git push origin check-auto-deployment
Enumerating objects: 17, done.
Counting objects: 100% (17/17), done.
Delta compression using up to 8 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (9/9), 823 bytes | 205.00 KiB/s, done.
Total 9 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), completed with 5 local objects.
remote:
remote: Create a pull request for 'check-auto-deployment' on GitHub by visiting:
remote:      https://github.com/paveg/portfolio/pull/new/check-auto-deployment
remote:
To https://github.com/paveg/portfolio
 * [new branch]      check-auto-deployment -> check-auto-deployment

Githubへ移動し、Pushした変更をMasterへマージするPRを作成します。

PR作成後


PRを作成すると、設定済みのnowはdeployを開始します。

f:id:paveg:20190321034438p:plain

deploy完了後は、ステージング環境としてデプロイ先にアクセスが可能です。

f:id:paveg:20190321034630p:plain

https://portfolio-q8oqbi0i1.now.sh/

修正に問題がないので、マスターへ向けてマージします。

すると、今後はmasterブランチでフィルタしていた処理が、CircleCIにて実行されます。

f:id:paveg:20190321035037p:plain

マージ前にステージングデプロイは行なってくれるので、ここであれこれ触ることも可能です。 最高ですね。

プロダクションリリース後

zeitのWebページより、プロジェクトダッシュボードを確認するとリリースが完了していることがわかります。

f:id:paveg:20190321035257p:plain

また、先ほどステージングリリースの際に使ったブランチも残っていることが確認可能です。

ブランチ名がそのままurlへと反映されてますね。

https://portfolio-git-check-auto-deployment.pavegy.now.sh/

まとめ

  • nowでお手軽に確認できるstaging環境の作成が可能
  • now + circleCIで、自動リリースプロセスが作成可能
  • 普通にCIrcleCIいらなかったわ

気をつけることは、private repositoryにしても静的ファイルが全て見えちゃうはずなので、課金が必須だということぐらいです。

鍵とかの管理は気をつけましょう。circleCIのenvとかでやりましょうね。

よかったら記事のシェアをお願いします 🙄

追加調査


普通にCIrcleCIとかいらなかったわ

zeit.co

Githubと繋いでインテグレーションを有効にしてmasterにpushしてください。

CircleCIとかいりませんでした。本当にありがとうございました。

時間返して…😇 now最高なんやな…

*1:プロダクトを少しずつ開発していく手法

*2:Platform as a Service - アプリケーションを実行するためのプラットフォームをインターネットを介して提供するサービスのこと

*3:米Forrester社が挙げています