CircleCIでdockerイメージをbuild & pushする

## はじめに

githubにてmasterブランチにmergeされたときに、GCPのContainer Registryにimageをpushする

## CircleCIセットアップ

1. CIの実行ファイルを作成
1. CircleCIの管理画面でプロジェクト追加

### 1. CIの実行ファイルを作成

ルート直下に.circleciのフォルダを作成して、その中にconfig.ymlのファイルを作成する
（いったん、hello worldするだけ実行ファイル）

```yml
version: 2.1
jobs:
  build:
    docker:
      - image: circleci/ruby:2.6.5
    steps:
      - checkout
      - run: echo "hello world"
```

### 2. CircleCIの管理画面でプロジェクト追加

CircleCIのサイトからgithubログインして対象のリポジトリを追加して完了
そして、hello world確認！

<img width="534" alt="スクリーンショット 2020-08-08 19.40.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214984/ce80ae70-fbd5-8372-c938-a324bf54b823.png">

## config.ymlにdockerイメージビルドする処理を書く

1. Gcloud連携
1. dockerイメージをbuild & push
1. masterブランチへmergeされた時だけ実行する

### 1. Gcloud連携

公式ドキュメントを参考に進める
https://circleci.com/docs/ja/2.0/google-auth/

ciの実行環境にgcloudのsdkを加える

```yml
executors:
  docker:
    - image: google/cloud-sdk
```

Google Cloud SDK のツールを使用する前に、gcloud を承認する必要があるので、下記手順にしたがってサービスアカウントを作成する
https://cloud.google.com/sdk/docs/authorizing#authorizing_with_a_service_account

CircleCI にキーファイルをプロジェクト環境変数として追加する
https://circleci.com/docs/ja/2.0/env-vars/#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E5%86%85%E3%81%A7%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B

gcloudを使用してGoogle Cloud SDKを承認する
また、GCRにpushするのでその認証もする

```yml
version: 2.1
jobs:
  create_image:
    docker:
      - image: google/cloud-sdk
    steps:
      - run:
          name: Gcloud Config
          command: |
            echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=-
            gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
            gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE}
      - run:
          name: GCloud Auth configure-docker
          command: |
            gcloud auth configure-docker --quiet --project ${GOOGLE_PROJECT_ID}
#（workflowsは省略）
```

実行してみると、承認できていることが確認できた！

<img width="835" alt="スクリーンショット 2020-08-08 20.54.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214984/13201086-2f75-148b-156a-0506ae084767.png">


### 2. dockerイメージをbuild & push

まずは、CI環境でdockerを使えるようにする
なんとsetup_remote_dockerを追加するだけで完了！

```yml
version: 2.1
jobs:
  create_image:
    docker:
      - image: google/cloud-sdk
    steps:
      - run:
          name: Gcloud Config
          command: |
            echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=-
            gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
            gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE}
      - run:
          name: GCloud Auth configure-docker
          command: |
            gcloud auth configure-docker --quiet --project ${GOOGLE_PROJECT_ID}
      - setup_remote_docker
#（workflowsは省略）
```
https://circleci.com/docs/ja/2.0/building-docker-images/


次に、checkoutしてからdockerイメージをbuild & pushする

```yml
version: 2.1
jobs:
  create_image:
    docker:
      - image: google/cloud-sdk
    steps:
      - run:
          name: Gcloud Config
          command: |
            echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=-
            gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
            gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE}
      - run:
          name: GCloud Auth configure-docker
          command: |
            gcloud auth configure-docker --quiet --project ${GOOGLE_PROJECT_ID}
      - setup_remote_docker
      - checkout
      - run:
          name: Docker Build
          command: |
            docker build . -t gcr.io/${GOOGLE_PROJECT_ID}/gcp-rails_sports-rails_backend:${CIRCLE_SHA1}
      - run:
          name: Docker Push
          command: |
            docker push gcr.io/${GOOGLE_PROJECT_ID}/gcp-rails_sports-rails_backend:${CIRCLE_SHA1}
#（workflowsは省略）
```

build & push できていることを確認！




### 3. masterブランチへmergeされた時だけ実行する

最後にmasterのときだけcreate_imageのジョブを実行するようにfilterを追加して完成！🎉

```yml
version: 2.1
jobs:
  create_image:
    docker:
      - image: google/cloud-sdk
    steps:
      - run:
          name: Gcloud Config
          command: |
            echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=-
            gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
            gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE}
      - run:
          name: GCloud Auth configure-docker
          command: |
            gcloud auth configure-docker --quiet --project ${GOOGLE_PROJECT_ID}
      - setup_remote_docker
      - checkout
      - run:
          name: Docker Build
          command: |
            docker build . -t gcr.io/${GOOGLE_PROJECT_ID}/#{任意のイメージ名}:${CIRCLE_SHA1}
      - run:
          name: Docker Push
          command: |
            docker push gcr.io/${GOOGLE_PROJECT_ID}/#{任意のイメージ名}:${CIRCLE_SHA1}
workflows:
  build:
    jobs:
      - create_image:
          filters:
            branches:
              only: master
```