LoginSignup
16
14

More than 3 years have passed since last update.

簡単な静的ページと簡単なAPIサーバーをGoogle Cloud Runで動かす

Last updated at Posted at 2019-08-07

なにこれ

社内勉強会でdockerの概論的なものとマルチステージビルドについてのお話をしました。
単純にマルチステージビルドするサンプルだけだと、ちょっと内容としては寂しかったので、せっかくだから精神でCloud Runにイメージをデプロイして走らせてみます。

利用するプロジェクト

構成

$ tree -L 1
.
├── LICENSE
├── Makefile // docker-compose周りのビルド処理
├── README.md
├── app      // 雑な静的ページのプロジェクトディレクトリ
├── docker-compose.yml
└── server   // 雑なAPIサーバーのプロジェクトディレクトリ

静的ページ

.
├── Dockerfile
├── babel.config.js
├── nginx
│   └── default.conf // nginx定義ファイル(本番用)
├── package-lock.json
├── package.json
├── src              // ソースディレクトリ
├── vue.config.js
└── yarn.lock
  • 現状Cloud Runのポートが 8080 で固定されているのでnginx側で8080ポートを使うように default.conf を再定義
  • productionSourceMapはfalse
  • .env を作成してAPIサーバーのOriginを指定
  • サンプル自体は基礎から学ぶ Vue.jsの応用。いい本だからみんな買おう。

Dockerfileは以下のような形

# --- local ---
FROM node:8.15.0-alpine as build-vue
WORKDIR /app
COPY . .
RUN apk update && \
  npm install -g npm && \
  npm install -g yarn && \
  yarn install && \
  yarn run build

# --- production ---
FROM nginx:1.15.12-alpine as production-vue
COPY --from=build-vue /app/dist /usr/share/nginx/html
COPY --from=build-vue /app/nginx/default.conf /etc/nginx/conf.d/default.conf
EXPOSE 8080
CMD ["nginx", "-g", "daemon off;"]

APIサーバー

.
├── Dockerfile
├── Makefile   // go用各種ビルド処理
├── go.mod
├── go.sum
├── list.json  // 最強のクソ雑要素
└── main.go
  • ビルド周りの設定は全てMakefileで定義
  • realizeでホットリロード
  • 入力データを list.json に任せる雑設計

Dockerfileは以下のような形

# --- local ---
FROM golang:1.12-alpine as build-go
WORKDIR /go/server
COPY . .
RUN apk add --no-cache git make  && \
  go get github.com/oxequa/realize && \
  make build

# --- production ---
FROM alpine as production-go
WORKDIR /app
COPY --from=build-go /go/server/bin/server .
COPY --from=build-go /go/server/list.json .
RUN addgroup go \
  && adduser -D -G go go \
  && chown -R go:go /app/server
EXPOSE 8080
CMD ["./server"]
  • ローカルではgolangのalpineで開発、本番はただのalpineにバイナリファイルを上げる
  • ビルド周りはMakefileで定義
  • list.json で入力を定義しちゃっているのでこれも追加

docker-compose

フロントエンドとバックエンドを同じプロジェクトで管理するという取り回しにくい構成になっているので、docker-compoes側をちょっとひねります。

version: '3.5'
services:
  vue-app:
    stdin_open: true
    tty: true
    build:
      context: ./app    # フロント側のディレクトリ(Dockerfileのあるとこ)を渡してあげる
      target: build-vue # ローカルステージをターゲットに(as で指定した名前)
    command: yarn run serve
    volumes:
      - ./app:/app      # ホットリロードかけたいからbuild contextと同じ所を指定
    ports:
      - 39000:8080      # ポートは適当。被んなければいいっしょ精神
    depends_on:
      - go-app

  go-app:
    build:
      context: ./server # バックエンド側のディレクトリ(Dockerfileのあるとこ)を渡してあげる
      target: build-go  # ローカルステージ。名前もっと考えればよかった
    command: realize start --run
    volumes:
      - ./server:/go/server # ホットリロードかけたいからvolumeを指定
    ports:
      - 38080:8080      # ポートは適当。8080ついてればいいっしょ精神

重要な点としては

  1. build:でDockerfileと連携を取る
    • context にDockerfileのあるディレクトリを指定する
    • target に、Dockerfileで From <image名> as <stage名>のas以下の値を入れる
  2. volumesを指定してあげる
    • これがないとdocker-compose upした後にホストマシンでコードを書き換えてもリロードされない
    • イメージに直にsshして値を書き換えるとホットリロードしてくれるけど・・・
  3. 8080を叩くようにポートを指定
    • 現状Cloud Runのポートは8080
    • これのせいでnginxもdefault.confの書き換えが必要

Cloud Runにデプロイ

先にサービスの一覧を確認します。

$ gcloud beta run services list
WARNING: No target platform specified. This will be a required flag in a future version of the gcloud command-line tool. Pass the `--platform` flag or set the [run/platform] property to satisfy this warning.
Available platforms:
- gke: Cloud Run on Google Kubernetes Engine. Use with the `--cluster` and `--cluster-location` flags or set the [run/cluster] and [run/cluster_location] properties to specify a cluster in a given zone.
- managed: Fully managed version of Cloud Run. Use with the `--region` flag or set the [run/region] property to specify a Cloud Run region.

Listed 0 items.

Listed 0 items. なので現状何もサービスが動いていないことが確認できます。

スクリーンショット 2019-08-07 11.26.06.png

デプロイ処理

例えば静的ページを以下のイメージ名でビルドした場合を考えます。

docker build -t gcr.io/sugoi-cloud-run-test/super-sugoi-sample-app app/

まず最初にGoogle Cloud Buildにイメージをアップロードします。

# 静的ページ側
$ gcloud builds submit --project sugoi-cloud-run-test --tag gcr.io/sugoi-cloud-run-test/super-sugoi-sample-app app/.

# API側
$ gcloud builds submit --project sugoi-cloud-run-test --tag gcr.io/sugoi-cloud-run-test/super-sugoi-sample-server server/.

スクリーンショット 2019-08-07 12.51.31.png
すごそう。

イメージが上がったら、デプロイを実行します。

$ gcloud beta run deploy super-sugoi-sample-app --image gcr.io/sugoi-cloud-run-test/super-sugoi-sample-app:latest --region asia-northeast1

実行するとWARNINGとかがモチャモチャ出た後、未認証の呼び出しを許可するかどうかを聞かれるので、yを入れておきます。

WARNING: No target platform specified. This will be a required flag in a future version of the gcloud command-line tool. Pass the `--platform` flag or set the [run/platform] property to satisfy this warning.
Available platforms:
- gke: Cloud Run on Google Kubernetes Engine. Use with the `--cluster` and `--cluster-location` flags or set the [run/cluster] and [run/cluster_location] properties to specify a cluster in a given zone.
- managed: Fully managed version of Cloud Run. Use with the `--region` flag or set the [run/region] property to specify a Cloud Run region.

Allow unauthenticated invocations to [super-sugoi-sample-app]
(y/N)?  y

Deploying container to Cloud Run service [super-sugoi-sample-app] in project [sugoi-cloud-run-test] region [asia-northeast1]
✓ Deploying new service... Done.
  ✓ Creating Revision...
  ✓ Routing traffic...
  ✓ Setting IAM Policy...
Done.
Service [super-sugoi-sample-app] revision [super-sugoi-sample-app-***] has been deployed and is serving traffic at https://super-sugoi-sample-app-***.a.run.app

ここまで行った段階で、もう一度listコマンドを試します。

$ gcloud beta run services list --region asia-northeast1

   SERVICE                    REGION           LATEST REVISION                SERVING REVISION               LAST DEPLOYED BY  LAST DEPLOYED AT
✔  super-sugoi-sample-app     asia-northeast1  super-sugoi-sample-app-***     super-sugoi-sample-app-***     ***               2019-08-07T03:54:55.770Z
✔  super-sugoi-sample-server  asia-northeast1  super-sugoi-sample-server-***  super-sugoi-sample-server-***  ***               2019-08-07T03:59:15.436Z

スクリーンショット 2019-08-07 13.05.52.png

ちゃんと入っているのでデプロイOKです。

デプロイコマンドの詳細については、公式も確認してください
FYI: https://cloud.google.com/sdk/gcloud/reference/beta/run/deploy

動作確認

デプロイできたので動作確認をします。
デプロイコマンド実行時にserving traffic at ~出てきたURLにアクセスしてみます。

API側


$ curl https://super-sugoi-sample-server-***.a.run.app/monsters | jq .

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   147  100   147    0     0   1732      0 --:--:-- --:--:-- --:--:--  1750
[
  {
    "id": 1,
    "name": "スライム",
    "max": 10,
    "hp": 10
  },
  {
    "id": 2,
    "name": "ゴブリン",
    "max": 50,
    "hp": 50
  },
  {
    "id": 3,
    "name": "ドラゴン",
    "max": 500,
    "hp": 500
  }
]

フロント側

$ open https://super-sugoi-sample-app-***.a.run.app/

スクリーンショット 2019-08-07 13.19.02.png

初期データが入っているので、ちゃんとAPI側を呼んだ結果が取れているのがわかりますね。

お片付け

遊んだものはちゃんと片付けましょう。

$ gcloud beta run services delete super-sugoi-sample-service --region asia-northeast1
$ gcloud beta run services delete super-sugoi-sample-app --region asia-northeast1

まとめ

簡単な静的ページとAPIサーバーをCloud Runにデプロイして挙動を試しました。

beta版ということで、8080ポート縛りなどがあるので、最初nginxのデプロイで困りましたし(docker run -p 8080:80 sugoi-sample-app:latestは動くのになんでや!ってなりました)、こちらの設計で言えばフロントとサーバーを同じプロジェクトに突っ込んで一つのdocker-composeで管理するというのも初めての体験だったので、ホットリロード動かない問題の原因とかbuild contextをどう置くかなど、色々学びができました(CI/CD考えると取り回しが悪いのでこのパターンは二度とやらないでしょうね)。

それでも、料金体系と開発の楽さを考えるとかなり可能性を感じます。
これからもちょくちょく使っていこうと思います。

16
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
14