Cloud Runを使って無料でリダイレクトサーバをたてる

## はじめに

[bocci bocci](https://boccibocci.com)を運営している@shoji-kaiです。
[前回の記事](https://qiita.com/shoji-kai/items/a6a32e05400a496ab280)でメルカリShopsにショップを開設した話を書きましたが、将来的には自分でショップを実装しようと思っています。
メルカリShopsは送料は安いのですが手数料が10%も取られるのでトータルで見るとあまり安くありません。むしろちょっと高い。
あとは、なによりも自分で構築したほうが楽しいですからね。
Netlify + Gatsby + Headless CMSなどを使ってJamstackなフロントエンドを作ってみようと妄想しています。(DevOpsエンジニアですが)

そんな計画もあるので、予めメルカリShopsに依存しないURLを自分で用意しました。

https://shop.boccibocci.com

今のところはメルカリShopsにリダイレクトさせて、将来的には自分のサイトにリダイレクトさせようと思っています。
そこでリダイレクトサーバが必要になるわけですが、今回はCloud Runを使って無料で用意しましたよ、というお話しです。

## Cloud Runの料金体系

Cloud Runの料金体系は以下のようになっています。
![スクリーンショット 2021-11-11 12.58.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1177074/0672dc66-aac7-4a16-064e-61bc7b3a886f.png)
「毎月200万リクエストは無料」なので、私のサイトでは必要十分というか、一生届かない数字でしょう。
CPUとメモリに関してはリダイレクトするだけなので無視して大丈夫かと思います。

## Cloud Runを起動する

gcloudコマンドを使ってCloud Runにリダイレクトサーバを立ち上げてみます。
Google Cloud SDKのインストール、GCPプロジェクトの作成手順などは割愛します。

### 0. 環境変数

まず最初に私の環境の情報を環境変数として登録しました。
こちらの環境変数に適宜ご自身の環境を設定してご確認ください。

```
export $PROJECT_ID=<プロジェクトID>
export $REGION=us-central1            # リージョン
export $REPOSITORY=test               # Artifact Registryのリポジトリ名
export $CONTAINER=nginx               # コンテナ名
export $SERVICE=test                  # Cloud Runのサービス名
export $DOMAIN=shop.boccibocci.com    # カスタムドメイン名
```

### 1. Artifact Registryにリポジトリを作成する

事前にDockerイメージの格納先となるリポジトリをArtifact Registryに作成しておきます。
Artifact Registryも十分な無料枠があるので料金が発生することはないでしょう。
Artifact Registryの料金体系については、[こちら](https://cloud.google.com/artifact-registry/pricing?hl=ja)に掲載されています。


```shell
gcloud artifacts repositories create --location=$REGION --repository-format=Docker $REPOSITORY
```

### 2. リダイレクト設定を組み込んだNginx(Dockerfile)を用意する

Hostがshop.boccibocci.comの場合はリダイレクトします。それ以外は401を返します。

```nginx:default.conf
server {
  listen 8080;
  server_name shop.boccibocci.com;
  return 302 https://mercariapp.page.link/?isi=667861049&ibi=com%2Ekouzoh%2Eios%2Emercari&link=https%3A%2F%2Fmercari%2Dshops%2Ecom%2Fshops%2FBaUb4miDEjn3qtr6x5yfrV&amv=89000&si=https%3A%2F%2Fassets%2Emercari%2Dshops%2Dstatic%2Ecom%2F%2D%2Fsmall%2Fplain%2FwSfrdHvvBPYpRwk2jWWpdg%2Epng&st=bocci%20bocci&apn=com%2Ekouzoh%2Emercari;
}

server {
  listen 8080 default_server;
  server_name _;
  return 401;
}
```

Dockerfileは以下のような感じです。

```dockerfile:Dockerfile
FROM nginx:1.20.1-alpine
COPY nginx.conf /etc/nginx/nginx.conf
COPY default.conf /etc/nginx/conf.d/default.conf
EXPOSE 8080
CMD ["nginx", "-g", "daemon off;"]
```

### 3. Dockerイメージをビルドする

私の環境がM1 Mac(arm64)なので、```--platform linux/amd64```でアーキテクチャを指定しています。
現状、Cloud Runはamd64/x86_64アーキテクチャしか対応していない、と思います。

```shell
docker image build --platform linux/amd64 -t "${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY}/${CONTAINER}" .
```

### 4. Dockerイメージをプッシュする

```shell
gcloud auth configure-docker "${REGION}-docker.pkg.dev"
docker image push "${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY}/${CONTAINER}"
```

### 5. Cloud Runにデプロイする

```shell
gcloud run deploy $SERVICE --image="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY}/${CONTAINER}" --region=$REGION --allow-unauthenticated
```

正常にデプロイされるとCloud RunからURLが発行されます。

```shell
% gcloud run services describe --region $REGION $SERVICE
✔ Service test in region us-central1

URL:     https://test-z2dhglvjpa-uc.a.run.app  # <= これ
Ingress: all
:
```

### 6. 確認する (401エラーになる)

Nginxの設定でshop.boccibocci.com以外は401を返すように設定したので、デフォルトURLでアクセスしても401が返ってきます。

```shell
% curl -I 'https://test-z2dhglvjpa-uc.a.run.app'
HTTP/2 401
content-type: text/html
:
```

## Cloud Runにカスタムドメインを設定する

shop.boccibocci.comでアクセスできるように、Cloud Runにカスタムドメインを設定していきます。

### 1. DNSレコードのドメイン所有権の確認

まずは自分がカスタムドメインの所有者であることをGoogleに証明する必要があります。
[Google Search Console](https://search.google.com/search-console/welcome)を開いてカスタムドメインを入力します。
![スクリーンショット 2021-11-11 16.45.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1177074/748ef669-1532-73e8-ae0a-9e4c7c783c13.png)

ご自身のドメイン名プロバイダにTXTレコードを追加します。
![スクリーンショット 2021-11-11 15.49.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1177074/70150c60-2a80-06b5-11b7-463a927f8edf.png)

正常に反映されると完了です。
![スクリーンショット 2021-11-11 15.54.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1177074/80b807bc-f040-e614-841c-67569a0dda53.png)

### 2. Cloud Runサービスとカスタムドメインをマッピングする

```
% gcloud beta run domain-mappings create --service $SERVICE --domain $DOMAIN --region $REGION
Creating......done.
Waiting for certificate provisioning. You must configure your DNS records for certificate issuance to begin.
NAME  RECORD TYPE  CONTENTS
shop  CNAME        ghs.googlehosted.com.
```

### 3. DNSプロバイダにCNAMEレコードを追加する

ご自身が契約しているDNSプロバイダのカスタムドメインに上記CNAMEレコードを追加します。
正常に反映されると以下のように応答されます。

```
% dig $DOMAIN +short
ghs.googlehosted.com.
172.217.161.243
```

### 4. カスタムドメインでCloud Runにアクセスしてみる

302が応答されていれば成功です。

```
% curl -I https://$DOMAIN
HTTP/2 302
content-type: text/html
location: https://mercariapp.page.link/?isi=667861049&ibi=com%2Ekouzoh%2Eios%2Emercari&link=https%3A%2F%2Fmercari%2Dshops%2Ecom%2Fshops%2FBaUb4miDEjn3qtr6x5yfrV&amv=89000&si=https%3A%2F%2Fassets%2Emercari%2Dshops%2Dstatic%2Ecom%2F%2D%2Fsmall%2Fplain%2FwSfrdHvvBPYpRwk2jWWpdg%2Epng&st=bocci%20bocci&apn=com%2Ekouzoh%2Emercari
:
```

## おわりに

Cloud Run以外にもGCPは無料枠が充実しているので助かります。
本当はTerraformとかでIaC化したほうがいいのですが、ここでは手順の説明をしやすくするためにgcloudコマンドで実行しました。
この記事がどなたかのお役に立てば幸いです。