Zeit Nowの具体的なTips集

# 目的とターゲット
みなさんはZEIT Nowをご存知でしょうか？
ZEIT Nowは静的サイトやサーバレス向けのPaaSです。
今回Next.jsの練習でZEIT Nowを試してみたので、Tipsをまとめます。
ZEIT Nowを使ったことがない方やこれから使おうと考えている方のヒントになれば幸いです。
本記事では

- Zeit NowとGitHubの連携手順
- Zeit Nowで環境変数を使う手順
- Zeit NowとGoogle Cloud Storageの連携手順

についてご紹介します。

## ターゲット
- 駆け出しエンジニア
- Next.jsを少ない手順でデプロイしたい方

## バージョン

* Now 16.6.3
* Next.js 9.0.2
* NPM 6.13.4
* Node.js v10.16.0

## 用意するもの
- Zeit Nowのアカウント
- GitHubのアカウント
- Now cli
- VSCodeなどのエディタ

下記リンクから事前にZeit Nowに登録し、GitHubと連携させます。
https://zeit.co/onboarding
CLIは下記リンクをを参考に
https://zeit.co/download

```bash
$npm i -g now
```
でインストールできます。



# GitHubと連携する

https://zeit.co/new/nextjs
にアクセスし、プロジェクトテンプレートからNext.jsのプロジェクトを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/548808ec-2122-aa98-71c2-27cd9fefb75d.png)
「Create Git Repository」をチェックしGitHubのページから権限を変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/a278564a-9f65-3427-903d-b5ed04215f10.png)

「All repositories」を選択し、「Save」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/a0408317-87cc-8efc-4281-e53a6b418ac3.png)

権限を変更すると「Deploy」を押下するとデプロイできるようになります。publicリポジトリかprivateリポジトリかは用途に応じて選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/7abbaa75-5357-cce7-7a89-3b70a6cc7fc2.png)

これでダッシュボードの「Visit」を押下するとデプロイしたサイトにアクセスできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/5a54c41a-4da4-b7f7-187f-ec0d179286ab.png)



# 環境変数を使う
今回はNext.jsを使用するのでまずはNext.jsで環境変数を使用するようにコードを変更します。
https://github.com/zeit/next.js/tree/canary/examples/with-dotenv
を参考に

```bash
$npm i dotenv
```

でdotenvをインストールします。
加えてnext.config.jsに設定を追加します。

```next.config.js
require('dotenv').config()
module.exports = {
  webpack: config => {
    // Fixes npm packages that depend on `fs` module
    config.node = {
      fs: 'empty',
      
    }
    return config
  },
  env: {
    // Reference a variable that was defined in the .env file and make it available at Build Time
    TEST_VAR: process.env.TEST_VAR,
  }
}

```


次に、nowコマンドで環境変数を設定します。

```bash
$now secrets add test_var "variable from secrets"
```
設定した値は下記のように確認可能です。

```bash
$now secrets ls
```
設定した環境変数にコードからアクセスするには設定ファイルを設置します。

```now.json
{
  "build": {
    "env": {
      "TEST_VAR": "@test_var"
    }
  }
}
```

すると、コード内で下記の記述で環境変数にアクセスできます。

```javascript
process.env.TEST_VAR
```

環境変数にアクセスできていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/3705c717-813c-cc9b-3730-afeb4b9bccc6.png)

完成形は下記ブランチにまとめました。
https://github.com/tom-256/now_nextjs_example/tree/use-environment-variable


## ローカル環境の場合
ローカル環境で環境変数をチェックするときは.envファイルに下記のように設定します。

```:.env
TEST_VAR=test_var
```

.envはデフォルトでNowにデプロイされないのでご安心ください。  
https://zeit.co/docs/v2/build-step/#ignored-files-and-folders

# Google Cloud Storageと連携する

## Cloud Storageに画像をアップロードする
Cloud Storageでbucketを作成します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/822cd57c-9e54-cdda-f9c2-0e28bf04e008.png"  width=50%>

ファイルをアップロードを押下し、適当な画像を保存します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/02e80008-8575-3e77-3029-1f4ff79e408f.png"   width=50%>


AllUsersの読み取り権限を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/e2788712-d927-0eae-69f4-b415605f6bbd.png)


## NowにCloud Storage Integrationを追加する
[Google CloudのIntegration設定](https://zeit.co/integrations/gcloud)にアクセスし、Addを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/6625433c-81f1-e2a8-678b-08456f3595d2.png)

アカウントを選択し、Addを押下します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/2ce5ace6-2b56-0427-0e0c-33fdebe734d1.png" width=80%>

セレクトボックスからプロジェクト名を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/44c9268c-ded5-8995-0f29-5ca40d87dc40.png)

create a service account keyを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/6d6ac47a-d35c-575d-c33a-fb002b958315.png)

Google Cloudコンソールが開くのでサービスアカウントのセレクトボックスで「新しいサービスアカウント」を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/111ff421-2051-614d-5fac-fffb363790fa.png" width=50%>

サービスアカウント名、役割（今回はCloudStorageを使うのでストレージ管理者を選択）を入力して作成を押下します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/e7b83694-4089-d6ec-4c94-5306cd09300c.png" width=50%>

jsonファイルがダウンロードされるので、その中身をコピーしてテキストエリアに貼り付け、Connectを押下します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/aa22cbcf-65de-0cf6-124b-1296aa58f40e.png" width=70%>

認証に成功すると下記の画面に遷移します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/92ca06c5-3d4e-1255-482f-2dd3ac07c745.png" width=50%>



バケット一覧が表示され、連携していることが確認できます。Cloud Storageの欄で「Add To Project」を押下します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/960bafc4-1f19-5ebb-8b88-e5704f77100f.png" width=50%>


すると、下記コマンドでglcoudのクレデンシャルが追加されていることが確認できます。

```bash
$now secrets ls | grep gcloud
```

integrationの設定は下記URLで確認できます。
https://zeit.co/dashboard/integrations

## 環境変数を設定する
ここまでで`process.env.GCLOUD_CREDENTIALS`でGoocle Cloudのクレデンシャルにアクセスできるようになります。  
つまり、now.json側に環境変数の設定は必要ありません。
ただし、今回はNext.jsを使っているので、Next.js側に設定が必要になります。

```javascript:next.config.js
  env: {
    // Reference a variable that was defined in the .env file and make it available at Build Time
    TEST_VAR: process.env.TEST_VAR,
    GCLOUD_CREDENTIALS: process.env.GCLOUD_CREDENTIALS,
  }
```

コードは下記のようになります。

```javascript:pages/api/image.js
  const storage = new Storage({
    projectId: process.env.GCLOUD_PROJECT_ID,
    credentials: JSON.parse(
      Buffer.from(process.env.GCLOUD_CREDENTIALS || "", "base64").toString()
    )
  });
```
ここまでのコードは下記ブランチにまとめました。
https://github.com/tom-256/now_nextjs_example/tree/cloud-storage-integration
上記コードはCloud Storageのバケット名なども環境変数に入れたので、Now Cliで登録することをお忘れなく。
すると下記のようにCloud Storageの画像が読み込めることが確認できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/ef2c71ef-9993-f20c-e167-2e92baee02dd.png" width=50%>

ローカル環境で`process.env.GCLOUD_CREDENTIALS`にアクセスする場合は、下記のようにbase64エンコードした結果を、`.env`に貼り付けます

```bash
$cat service-account-key.json | base64
```
```:.env
GCLOUD_CREDENTIALS="上記の出力結果"
```



# その他Tips
## 検索しづらさ
NowはそのままGoogle検索してもなかなか情報が見つかりづらいです。
「Zeit Now xxx」のように検索するとよいでしょう。

## 更新頻度の多さ
情報の更新頻度が高いのでなるべく公式に近い情報を参照しましょう。（本記事はあくまで2019年12月時点の情報です。）
私は公式ドキュメント、GitHubリポジトリ、Spectrumなどで情報を集めました。

https://zeit.co/docs
https://github.com/zeit/now
https://spectrum.chat/zeit/now?tab=posts

（今回の記事を書いてる途中でNowのバージョンがあがっていました。）  

# まとめ
今回は以下のことを実施しました。

- NowとGitHubを連携させる  
リモートブランチにプッシュするごとにデプロイ  
- Nowで環境変数を使う  
CLIで環境変数を登録し、now.jsonに記述する
- NowとGoogle Cloud Storageを連携させ画像を表示させる  
Integrationの設定からサービスアカウントキーを作成し登録する

実施した結果はこちらです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108210/ef2c71ef-9993-f20c-e167-2e92baee02dd.png" width=50%>

リポジトリは下記です。（今後Now側で環境変数を変更した場合や、Cloud Storageに変更を加えた場合は動かなくなるのでご了承ください。）
https://github.com/tom-256/now_nextjs_example/

今回は駆け出しエンジニアの方向けに画像を多めにしてみました。
Next.js以外にもNuxt.jsなどのフレームワークにも対応しているので、[ドキュメント](https://zeit.co/docs/v2/build-step/#optimized-frameworks)や[サンプルリポジトリ](https://github.com/zeit/now-examples)を探して自分の好みの環境で試してみるとよいでしょう。
みなさんもZeit Nowを使って気軽に開発を始めてみてはいかがでしょうか？