GCPのすゝめ【Cloud Run編】

## 概要
Cloud Runを使う際の手順とまとめです。

**公式ドキュメント**
[Cloud Run](https://cloud.google.com/run?hl=ja)
[Cloud Build](https://cloud.google.com/cloud-build/docs/build-config?hl=ja#yaml_1)

**サンプルレポジトリー**
https://github.com/koffe0522/cloudrun-express


## 準備
[Docker for MAC](https://hub.docker.com/editions/community/docker-ce-desktop-mac)
[Docker for Windows](https://hub.docker.com/editions/community/docker-ce-desktop-windows/)
[Google Cloud SDK](https://cloud.google.com/sdk/docs?hl=ja#install_the_latest_cloud_tools_version_cloudsdk_current_version)

## Google Cloud Platform での設定
**※既存のprojectプロジェクトを使用する場合は以下コマンドのみ**

```bash
$ gcloud config set project <PROJECT_ID>
```
### projectの作成
projectの作成方法は、以下の２種類
- Cloud Consoleから作成
- gcloudコマンドライン ツールで作成

**公式ドキュメント**
[プロジェクトの作成と管理](https://cloud.google.com/resource-manager/docs/creating-managing-projects?hl=ja&visit_id=637360878744326321-2405605430&rd=1#console)

## ディレクトリー構成
```bash
.
├── .env
├── .dockerignore
├── Dockerfile
├── README.md
├── cloud-build.yml
├── docker-compose.yml
├── index.js
├── package.json
└── yarn.lock
```

## アプリケーションの作成
**※nodeプロジェクトが存在している場合は不要**

```bash
$ mkdir <project name>
$ cd <project name>
$ yarn init -y
$ yarn add express
# 開発用
$ yarn add -D nodemon
```

```js:index.js
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send(`Hello World!`);
});

const port = process.env.PORT || 8080;
app.listen(port, () => {
  console.log('Hello world listening on port', port);
});
```
以下を追加

```json:package.json
{
 ...
 "scripts": {
    "start": "node index.js",
    "dev": "PORT=3000 nodemon index.js"
  },
 ...
}
```

## ローカル開発環境設定
```docker-compose.yml
version: "3.6"
services:
  app:
    image: node:10
    env_file: .env
    tty: true
    ports:
      - "3000:3000"
    volumes:
      - .:/app
    working_dir: /app
    command: yarn run dev

```
**起動してみる**

```bash
$ docker-compose up -d
```

http://localhost:3000/

**停止する**

```bash
$ docker-compose down
```

## Buildの準備

```Dockerfile:Dockerfile
FROM node:10

WORKDIR /src

COPY package*.json ./
RUN yarn install \
  --prefer-offline \
  --frozen-lockfile\
  --non-interractive \
  --production=false

COPY . .

CMD ["yarn", "run", "start"]
```
```.dockerignore:.dockerignore
node_modules
npm-debug.log
```
```cloud-build.yml
steps:
  - name: gcr.io/cloud-builders/docker
    args:
      [
        "build",
        "-f",
        "Dockerfile",
        "-t",
        "gcr.io/<PROJECT_ID>/<image name 好きな名前>", # ①
        ".",
      ]
images:
  # ①と同じ
  - gcr.io/<PROJECT_ID>/<image name 好きな名前>

```

## Cloud Build & Deploy

**Cloud Buildの実行**

```bash
$ gcloud builds submit --project <PROJECT_ID> --config=cloud-build.yml

...
 Would you like to enable and retry (this will take a few minutes)? 
(y/N)?  y
```

```bash
$ gcloud beta run deploy <cloud-run-name> --region us-central1 --project <PROJECT_ID> --image <cloud-build.ymlのimages名> --platform managed

...
you like to enable and retry (this will take a few minutes)? (y/N)?  y
...
Allow unauthenticated invocations to [cloud-run-name] (y/N)?  y

Deploying container to Cloud Run service [cloud-run-name] in project [PROJECT_ID] region [us-central1]
✓ Deploying new service... Done.                                                                                                                                       
  ✓ Creating Revision... Deploying Revision.                                                                                                                           
  ✓ Routing traffic...                                                                                                                                                 
  ✓ Setting IAM Policy...                                                                                                                                              
Done.                                                                                                                                                                  
Service [cloud-run-name] revision [cloud-run-name-00000-xxx] has been deployed and is serving 100 percent of traffic at <URL> Routing traffic... 
```

表示されたURLにアクセスする

## 備考
- Cloud Run では8080ポートでないとエラーとなる