[ Vue 3 ] Vue CLI を GCP App Engine に デプロイ する手順

Vue CLI (Vue3) で作成した サンプルアプリケーションを GCP App Engine に デプロイ する手順をまとめてみました。なお、こちらの記事 でまとめている通り、ライブラリの追加など、細かなカスタマイズが必要な場合は 同じ GCP であれば Cloud Run を用いる必要があります。

環境
npm: 7.23.0
node: v14.17.0
vue: @vue/cli 4.5.12

前提
GCP プロジェクト作成済み
GCP プロジェクトの課金設定済み
Google Cloud SDK (gcloud コマンド ) 導入済み

ローカル 側準備

Vue CLI プロジェクト の準備

まずは、任意のディレクトリに Vue CLI プロジェクト を作成していきます。 今回は vue3-cli という名称で プロジェクト を作成して進めていきます。

% vue create vue3-cli
Vue CLI v4.5.12
┌───────────────────────────────────────────┐
│                                           │
│   New version available 4.5.12 → 4.5.13   │
│                                           │
└───────────────────────────────────────────┘

? Please pick a preset:
  Default ([Vue 2] babel, eslint)
❯ Default (Vue 3 Preview) ([Vue 3] babel, eslint)
  Manually select features

起動確認していきます。

% cd vue3-cli
% sudo npm run serve

おなじみのトップ画面が表示され、Vue CLI プロジェクトが作成されたことが確認できます。

app.yaml の準備

App Engine のデプロイには Vue CLI プロジェクト の トップディレクトリ に app.yaml ファイルを配置する必要があります。 app.yaml ファイルがない場合、 デプロイ 時に以下のような エラー が出力されてしまいます。

ERROR: An app.yaml (or appengine-web.xml) file is required to deploy this directory as an App Engine application.

Vue CLI 用 app.yaml

以下の内容を app.yaml として、Vue CLI のトップディレクトリに配置してください。

runtime: nodejs14
env: standard

handlers:
- url: /
  static_files: dist/index.html
  upload: dist/index.html

- url: /(.*)
  static_files: dist/\1
  upload: dist/(.*)

この app.yaml ですが、 今回は ローカルの環境にあわせ nodejs14 としていますが、そのまま 推奨されている nodejs16 としても サンプルアプリに関しては動作するようでした。


Google App Engine 側準備

GCP への ログイン

最初に 対象となる GCP プロジェクトを選択していきます。 gcloud auth login を実行すると、ブラウザが起動します。既に ログイン済みの場合は 次の手順に進みます。

% gcloud auth login
Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?XXXXX

対象の Google アカウント を選択してすすめていきます。

アクセス権限確認が表示されますので、問題なければ Allow をクリックします。

対象となる GCP プロジェクト の選択

まず、 GCP Console のプロジェクトダッシュボードにいき、 プロジェクトID を確認します。

次に、gcloud config set project コマンドを利用して、対象となる プロジェクト を選択していきます。

% gcloud config set project sample-for-blog
Updated property [core/project].

以下のコマンドで、対象となるプロジェクトが確認できます。

% gcloud config list core/project
[core]
project = sample-for-blog

Vue CLI プロジェクト の ビルド

npm run build コマンドを実行して、デプロイ用のビルドイメージを作成します。

% npm run build

> [email protected] build
> vue-cli-service build


⠋  Building for production...

 DONE  Compiled successfully in 7151ms                                                                                                                                                 20:06:59

  File                                 Size                                                                       Gzipped

  dist/js/chunk-vendors.e1ffbd46.js    84.96 KiB                                                                  31.72 KiB
  dist/js/app.9de03c6e.js              4.47 KiB                                                                   1.60 KiB
  dist/css/app.fb0c6e1c.css            0.33 KiB                                                                   0.23 KiB

  Images and other types of assets omitted.

 DONE  Build complete. The dist directory is ready to be deployed.
 INFO  Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html

App Engine へ デプロイ

Vue CLI のトップディレクトリ (ここでは vue3-cli ディレクトリ) で、 gcloud app deploy コマンドを実行します。なお、後ほど説明しますが、 App Engine では サービス という単位で デプロイ することになります。先程の app.yaml では サービス を指定していないため、 default のサービスとして デプロイ することになります。

% gcloud app deploy
Services to deploy:

descriptor:                  [DIRPATH/vue3-cli/app.yaml]
source:                      [DIRPATH/vue3-cli]
target project:              [sample-for-blog]
target service:              [default]
target version:              [20210911t200825]
target url:                  [https://sample-for-blog.an.r.appspot.com]
target service account:      [App Engine default service account]


Do you want to continue (Y/n)? 

Beginning deployment of service [default]...
Uploading 7 files to Google Cloud Storage
14%
29%
43%
57%
71%
86%
100%
100%
File upload done.
Updating service [default]...done.                                                                                                                                                            
Setting traffic split for service [default]...done.                                                                                                                                           
Deployed service [default] to [https://sample-for-blog.an.r.appspot.com]

You can stream logs from the command line by running:
  $ gcloud app logs tail -s default

To view your application in the web browser run:
  $ gcloud app browse

Unknown url handler type. が出力される場合

gcloud app deploy コマンド 実行時に、 以下のような エラー が出力されることがあります。

Unknown url handler type.

これは、 url の次の行以降で記載している部分の先頭に 空白(ブランク)が 2つ 入っていないことが原因です。 今回の例でいうと、static_files, upload の各行の先頭に 2つ の 空白(ブランク) を入れることで エラー が解消されます。

# "Unknown url handler type." because of single blank
Unknown url handler typhandlers:
- url: / 
 static_files: dist/index.html
 upload: dist/index.htmle.
#

# Work without Error because of double blank
handlers:
- url: / 
  static_files: dist/index.html
  upload: dist/index.html
##

デプロイ 確認

ブラウザで確認

デプロイ が完了した後、先程の デプロイログ のなかで表示された target url に記載された URL にアクセスすると、ローカルで起動したものと同じ内容で VUE CLI が表示していることが確認できます。

GCP Console で確認

以下の URL から GCP Console を開き、デプロイ先のプロジェクトを選択し、 左のメニューから App Engine を選択します。何もデプロイしていない状況では、何も表示されていなかったところに各種情報が表示されるようになりました。

https://console.cloud.google.com/


補足:サービスについて

app.yaml ファイルに service: として名称を定義することで、 1 つの プロジェクト 内に複数の サービス をデプロイすることが可能です。サービスを指定しない場合、 default というサービスにデプロイされることになります。 ただし、 初めて デプロイ する場合は、default サービス として デプロイ しないと以下のエラーが出力されデプロイすることができないことに注意してください。

The first service (module) you upload to a new application must be the 'default' service (module).


例えば、 runtime に nodejs16 を指定し、 service に nodejs16 を指定した app.yaml は以下の通りです。

runtime: nodejs16
env: standard
service: nodejs16

handlers:
- url: /
  static_files: dist/index.html
  upload: dist/index.html

- url: /(.*)
  static_files: dist/\1
  upload: dist/(.*)

なお、このときの target url は以下の様になり、default の URL とは異なるものが設定されます。

target url:                  [https://nodejs16-dot-sample-for-blog.an.r.appspot.com]

App Engine のサービスは、 マイクロサービス を実現する目的で提供されているようです。以下の概念図や、引用元である、 Microservices Architecture on Google App Engine  を確認してください。

引用元: Microservices Architecture on Google App Engine


デプロイ した サービス を非公開にする方法

デプロイしたサービスは、そのままでは全世界に公開されている状態ですので、非公開にしたい場合は、以下の方法を検討してください。

  • サービスの削除
  • アプリ(プロジェクト)  無効化
  • ファイアウォール の活用

default サービス 以外の削除

デプロイした サービス を削除するには、 GCP Console で App Engine を開き、左のメニューから サービス を選択します。表示された サービス にチェックを入れ、 「削除」 をクリックします。

確認メッセージで、 「削除」 をクリックすることでサービスが削除されます。

default サービス の削除 ( アプリ無効化 )

先程は、名称を付与した サービス について削除を実行しましたが、 default サービス に関しては削除することができません。代替案として、 アプリケーションを無効にする という方法が提供されています。

確認ダイアログが表示されるので、 アプリ ID を入力し、「無効にする」 をクリックします。

アプリケーションが無効化されると、以下のような画面が表示されます。 「アプリケーションを有効にする」ボタンから、再度有効にすることができます。

この状態でデプロイ先の URL にアクセスすると以下のように 404 エラー となります。

なお、 アプリ無効化 を実施すると、 AppEngine だけでなくプロジェクト内のその他のサービス( Firestore, Cloud Functions 等 ) も合わせて無効になってしまうの点に注意してください。

default サービスへのアクセス無効化

アプリ無効化 ではプロジェクト内の他のサービスにも影響が出てしまうため、それは困るという場面もあるかと思います。その場合、 ファイアウォール ルール を編集し default サービスへのアクセス無効化 を検討するとよいかもしれません。ここでは手っ取り早く、 アクセスを拒否する方法を紹介します。

初期状態であれば、 GCP Console から ファイアウォール ルール を選択すると 以下のように 「すべての通信を許可するデフォルト設定」 が一つ設定されていると思いますので、これを編集していきます。

「一致したときのアクション」 から 「許可しない」を選択し 「保存」 をクリックします。

この状態でデプロイ先の URL にアクセスすると以下のように 404 エラー となります。


まとめ

  • Vue.js などの Node.js アプリ をデプロイするには App Engine, または Cloud Run を用いる
  • Vue CLI の場合、 プロジェクトトップディレクトリに app.yaml を配置する必要がある
  • デプロイは gcloud app deploy コマンドを用いる
  • App Engine は サービス単位でデプロイする構造
  • デフォルトサービスは削除不可。 アプリ無効化 や ファイアウォール ルール を活用する方法を検討する

関連記事