Cloud Run + Go から Firestore へデータ追加(※エラー出る)

概要

※ Go アプリ適切でないためエラーでます

Firestore へデータ追加する Go アプリを Cloud Run へアップする。

Firestore は GCP プロジェクトごとに 1 つのみ。コレクションは複数作成可能。

チュートリアル

GCP コンソールより Firestore データベース作成

GCP コンソールから作成していく。

  • モード : ネイティブモード
  • ロケーション : asia-northeast1 (Tokyo)
  • コレクションを開始
  • コレクション : users

Firestore が有効になり users コレクションが作成された。こいつにデータ追加していく。

Firestore アクセス用 Go アプリ

※ Listen しないタイプなのでエラー出る

go プロジェクト作成。

mkdir go_docker
cd go_docker
go mod init github.com/runble1/go-firestore-add

firestore パッケージ追加。

go get cloud.google.com/go/firestore 

GCP 公式より Go の Firestore サンプルアプリを拝借。2種類のユーザを追加する。

  • YOUR_PROJECT_ID : 自分の
  • コレクション : users
// Sample firestore_quickstart demonstrates how to connect to Firestore, and add and list documents.
package main

// [START firestore_setup_client_create]
import (
	"context"
	"flag"
	"fmt"
	"log"

	"google.golang.org/api/iterator"

	"cloud.google.com/go/firestore"
)

func createClient(ctx context.Context) *firestore.Client {
	// Sets your Google Cloud Platform project ID.
	projectID := "YOUR_PROJECT_ID"

	// [END firestore_setup_client_create]
	// Override with -project flags
	flag.StringVar(&projectID, "project", projectID, "The Google Cloud Platform project ID.")
	flag.Parse()

	// [START firestore_setup_client_create]
	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}
	// Close client when done with
	// defer client.Close()
	return client
}

// [END firestore_setup_client_create]

func main() {
	// Get a Firestore client.
	ctx := context.Background()
	client := createClient(ctx)
	defer client.Close()

	// [START firestore_setup_dataset_pt1]
	_, _, err := client.Collection("users").Add(ctx, map[string]interface{}{
		"first": "Ada",
		"last":  "Lovelace",
		"born":  1815,
	})
	if err != nil {
		log.Fatalf("Failed adding alovelace: %v", err)
	}
	// [END firestore_setup_dataset_pt1]

	// [START firestore_setup_dataset_pt2]
	_, _, err = client.Collection("users").Add(ctx, map[string]interface{}{
		"first":  "Alan",
		"middle": "Mathison",
		"last":   "Turing",
		"born":   1912,
	})
	if err != nil {
		log.Fatalf("Failed adding aturing: %v", err)
	}
	// [END firestore_setup_dataset_pt2]

	// [START firestore_setup_dataset_read]
	iter := client.Collection("users").Documents(ctx)
	for {
		doc, err := iter.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatalf("Failed to iterate: %v", err)
		}
		fmt.Println(doc.Data())
	}
	// [END firestore_setup_dataset_read]
}

Dockerfile

Dockerfile 作成。

# 開発環境用、マルチステージビルド
FROM golang:1.17-buster as builder

# ワーキングディレクトリ
WORKDIR /app

# go.mod と go.sum をコピー
COPY go.* ./

# go.mod と go.sum に従ってパッケージダウンロード
RUN go mod download

# 全コピー
COPY . ./

# server という実行ファイルを作成
RUN go build -v -o server main.go

# 本番運用用、マルチステージビルド
FROM debian:buster-slim

# 環境整備
RUN set -x && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    ca-certificates && \
    rm -rf /var/lib/apt/lists/*

# 実行ファイルコピー
COPY --from=builder /app/server /app/server

# Run the web service on container startup.
WORKDIR /app
CMD ["/app/server"]

Container Registory へデプロイ。

gcloud builds submit --tag gcr.io/YOUR_PROJECT_ID/run-firestore --project=YOUR_PROJECT_ID

Image がアップされた。

Cloud Run デプロイ

先程アップした Image を指定し Cloud Run をデプロイ。

gcloud run deploy run-firestore \
--image gcr.io/YOUR_PROJECT_ID/run-firestore \
--platform managed \
--allow-unauthenticated \
--project=YOUR_PROJECT_ID

デプロイエラーと出る。

Deployment failed
ERROR: (gcloud.run.deploy) Cloud Run error: The user-provided container failed

Go アプリが Listen しないやつなので、Cloud Run のエンドポイントを作成できないため。

ただし、この状態でも Cloud Run インスタンスは作成され、Firestore にデータ追加が行われていた。

まとめ

Cloud Run から Firestore へアクセスできることを確認できた。
しかし、Cloud Run のエンドポイントは生成されず、エラーが発生している状態となる。

そのまま流用できるサンプルがなさそうなので、自作する。

エラー

ERROR: (gcloud.run.deploy) Cloud Run error: The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable.

コンテナが 8080 ポートで起動および Listen できないとエラー。

下記コマンドで Cloud Run デプロイ時に発生。

gcloud run deploy run-firestore \
--image gcr.io/be-nishiyama-wataru/run-firestore \
--platform managed \
--allow-unauthenticated \
--project=be-nishiyama-wataru

これでも Cloud Run は 作成されていた。

Firestore へのデータ追加も成功。

公式ドキュメントにデプロイした Go アプリが Listen しないタイプなため。

参考

golang-samples/firestore at main · GoogleCloudPlatform/golang-samples
Sample apps and code written for Google Cloud in the Go programming language. - golang-samples/firestore at main · GoogleCloudPlatform/golang-samples
クイックスタート: サーバー クライアント ライブラリの使用  |  Firestore  |  Google Cloud
Cloud Run のトラブルシューティング  |  Cloud Run のドキュメント  |  Google Cloud
Cloud Run に関する問題を解決する
Cloud runにおけるFirestore利用について
Cloud runにおけるFirestore利用について

コメント

タイトルとURLをコピーしました