CircleCIでイメージをビルドしてGCRにプッシュする



## TL;DR

1. 「ストレージ管理者」の権限を付けたサービスアカウントを作成する(必要に応じて権限を絞りましょう)
2. CircleCIの環境変数にサービスアカウントのキーを設定する
3. `.circleci/config.yaml` でこんな感じのことをする

```shell
$ echo $GCP_SERVICE_KEY | gcloud auth activate-service-account --key-file -
$ gcloud auth configure-docker --quiet
$ # このへんでDockerイメージのビルドをする
$ docker push ${GCR_REPO}:${CIRCLE_SHA1}
```
具体的な `.circleci/config.yml` の設定例は後述します。

## サービスアカウントを作る

GCPのコンソールで「IAM」の「サービスアカウント」を開き、「サービスアカウントを作成」を押します。

![b3a54b3f-ee23-36c7-2fce-6c7017653e61.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49469/362f29a6-7f2c-c66d-896b-ec29bf46f282.png)

サービスアカウント名を入力し、「作成」ボタンを押します。「サービスアカウントID」と「サービスアカウントの説明」はお好みでどうぞ。

![スクリーンショット 2019-10-02 15.29.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49469/c790163f-c0a6-f82a-3274-bc6dce110d9b.png)

[アクセス制御の構成  |  Container Registry  |  Google Cloud](https://cloud.google.com/container-registry/docs/access-control?hl=ja)によると「ストレージ管理者」の権限付けると良いらしいので付けます(実際には権限を絞った方が良いかもしれません)。

![スクリーンショット 2019-10-02 15.42.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49469/8c27661e-bf19-bfe9-590d-b8f57df487a7.png)

次に「鍵の作成」ボタンを押してjsonのアクセスキーをダウンロードします。このファイルは公開しないようにしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49469/88478d38-1009-e24d-7cc4-e819c741caf3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49469/52533d30-a45e-fe19-9ad7-b9418f174272.png)


## CircleCIの環境変数を設定する

CircleCIのプロジェクトの設定から「Environment Variables」を開き、「Add Variable」ボタンを押します。

![4f68b01a-6f39-16a1-bd79-c4ce797436a6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49469/3591ad80-3adf-64b7-f688-d9dacac7b7e6.png)

今回は環境変数の名前を `GCP_SERVICE_KEY` にしました。 `Value` に先程ダウンロードした json ファイルの中身をコピペします。

![スクリーンショット 2019-10-02 16.04.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49469/156352d4-426b-8426-c2ab-97f1666e8898.png)

## CircleCIの設定ファイルを書く

### 注意点

> CircleCIは複数の Docker のバージョンをサポートしており、デフォルトは 17.03.0-ce です。
> [Docker コマンドの実行手順 \- CircleCI](https://circleci.com/docs/ja/2.0/building-docker-images/#%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B-docker-%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E5%A4%89%E6%9B%B4)

<!-- -->

> 警告: Docker 認証ヘルパーは、バージョン 18.03 以降でのみ使用してください。以前のバージョンの Docker クライアントのバグにより、認証ヘルパーが構成されていると、docker build の性能が大幅に低下します。
> [認証方法  \|  Container Registry  \|  Google Cloud](https://cloud.google.com/container-registry/docs/advanced-authentication?hl=ja)

CircleCIでデフォルトのバージョンのDockerを使うと `docker build` のパフォーマンスが低下すると考えられるため、明示的に新しいDockerのバージョンを指定しましょう。

### 設定例

以下、 設定の `jobs` 部分です。

```.circleci/config.yml
jobs:
  build:
    docker:
      - image: google/cloud-sdk:264.0.0
        enviromnent:
          GCR_REPO: ${gcr_repository_name}
    steps:
      - checkout
      - setup_remote_docker:
          docker_layer_caching: true
          version: 18.06.0-ce
      - run:
          name: Authenticate gcloud to push the image
          command: |
            echo $GCP_SERVICE_KEY | gcloud auth activate-service-account --key-file -
            gcloud auth configure-docker --quiet
      - run:
          name: Build the image
          command: |
            docker build -t ${GCR_REPO}:${CIRCLE_SHA1} .
      - run:
          name: Push the image
          command: |
            docker push ${GCR_REPO}:${CIRCLE_SHA1}
```