ビルドしたdockerイメージをGoogle Container Registryにpushする

Docker Engine 18.03から手順が変わっているようで、少しハマったので個人の備忘として。

# 公式ナレッジ

https://cloud.google.com/container-registry/docs/pushing-and-pulling?hl=ja#pushing_an_image_to_a_registry

公式はこちら。
GCPは公式ドキュメントがほとんど日本語化されていますが、量が膨大なので見つけにくいことも多いです。。

# 確認環境

- macOS Mojave 10.16.6
- Docker Desktop version 2.3.0.3  
Engine: 19.03.8
- Google Cloud SDK version 298.0.0

Google Cloud SDK は常になるべく最新版を使いましょう。
https://cloud.google.com/sdk/docs/quickstart-macos?hl=ja

```
$ gcloud components update
```

既にインストールされている場合は、上記コマンドでアップデートできます。

# 実際の流れ

PC上で必要な Dockerfile を書くところまでは予め行っておきます。
ここでは、tag名 `test-image` を Google Container Registry (GCR) にpushするものです。

## docker build

```
$ docker build -t test-image .
$ docker images        // ビルド結果の確認
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
test-image          latest              fa9cdfa2e722        24 seconds ago      147MB
php                 7.3-alpine3.12      898191dd6734        2 weeks ago         74.3MB
```

## Google認証

```
$ gcloud auth login                   // GCP自体の認証 (Google認証)
$ gcloud auth configure-docker        // gcloudでDockerが使えるよう認証
Adding credentials for all GCR repositories.
WARNING: A long list of credential helpers may cause delays running 'docker build'. We recommend passing the registry name to configure only the registry you are using.
After update, the following will be written to your Docker config file
 located at [/Users/kou/.docker/config.json]:
 {
  "credHelpers": {
    "gcr.io": "gcloud",
    "marketplace.gcr.io": "gcloud",
    "eu.gcr.io": "gcloud",
    "us.gcr.io": "gcloud",
    "staging-k8s.gcr.io": "gcloud",
    "asia.gcr.io": "gcloud"
  }
}

Do you want to continue (Y/n)?  Y        // "Y" を入力すると認証用json生成

Docker configuration file updated.
```

### gcloud auth configure-docker を飛ばすと…

以下のように、権限が足りずエラーになります。

**Docker Engine 18.02 以前の方法はもう使わないはず**なので、Docker と Google Cloud SDK を最新版にして再度試しましょう。

```
$ docker push asia.gcr.io/gcp-project-id/test-image
The push refers to repository [asia.gcr.io/gcp-project-id/test-image]
7b93f5969bbe: Preparing
f2190df73d84: Preparing
70871665c2de: Preparing
41a84b8edbaa: Preparing
76bcb8d3c55c: Preparing
eb933a8ebf3b: Waiting
763a2be1763a: Waiting
ba73bb9f4f5d: Waiting
cb2bbd887a61: Waiting
fe6f1373acef: Waiting
81c338ff74a3: Waiting
308ef7bef157: Waiting
d94df04fea90: Waiting
50644c29ef5a: Waiting
unauthorized: You don't have the needed permissions to perform this operation, and you may have invalid credentials. To authenticate your request, follow the steps in: https://cloud.google.com/container-registry/docs/advanced-authentication
```

## タギングとプッシュ

文法的には以下の通りです。

```
docker tag [SOURCE_IMAGE] [HOSTNAME]/[PROJECT-ID]/[IMAGE]:latest
docker push [HOSTNAME]/[PROJECT-ID]/[IMAGE]:latest

※ tagを "latest" にしたい場合はtag記載省略可能。
```

実行したコマンドイメージは以下の要領です。

```
$ docker tag test-image asia.gcr.io/gcp-project-id/test-image
$ docker push asia.gcr.io/gcp-project-id/test-image
The push refers to repository [asia.gcr.io/gcp-project-id/test-image]
c52988f2fb92: Pushed
1502c594c741: Pushed
c3b50c8c45a2: Pushed
15e5054fbc56: Pushed
393cd25efb77: Pushed
eb933a8ebf3b: Layer already exists
763a2be1763a: Layer already exists
ba73bb9f4f5d: Layer already exists
cb2bbd887a61: Layer already exists
fe6f1373acef: Layer already exists
81c338ff74a3: Layer already exists
308ef7bef157: Layer already exists
d94df04fea90: Layer already exists
50644c29ef5a: Layer already exists
latest: digest: sha256:90841da62962418578cb9b0f4bdfe7e2ac851eb9fdb86aa58a3a471a81eba7f9 size: 3249
```

`latest` のタグを付けたかったので入力は省略しました。

Fin ❤︎