kakakakakku blog

Weekly Tech Blog: Keep Learning!

Google Cloud エミュレーター「floci-gcp」を試す

はじめに

普段 AWS エミュレーターとして LocalStackFloci を使っている.実は Floci は Google Cloud エミュレーターとして floci-gcp を提供している.まだ AWS エミュレーターと比べるとサポートされているサービスは少なめだけど気になって試してみた \( 'ω')/

現時点では floci-gcp 0.4.0 が最新になる.

github.com

floci.io

環境

  • floci-gcp 0.4.0
  • gcloud CLI 575.0.0
  • Terraform Provider for Google Cloud Platform 7.39.0

セットアップ

floci-gcp の GitHub リポジトリにある README.mddocker-compose.yml を参考に compose.yml を作った.

services:
  floci-gcp:
    image: floci/floci-gcp:0.4.0
    ports:
      - 4588:4588
    volumes:
      - ./data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      FLOCI_GCP_HOSTNAME: floci-gcp
      FLOCI_GCP_BASE_URL: http://floci-gcp:4588
      FLOCI_GCP_SERVICES_DOCKER_NETWORK: floci_gcp_default
      FLOCI_GCP_SERVICES_CLOUDRUN_EXECUTION_URL_HOST_SUFFIX: localhost.floci.io
    networks:
      floci_gcp_default:
        aliases:
          - localhost.floci.io
          - container.localhost.floci.io

networks:
  floci_gcp_default:
    name: floci_gcp_default

そして floci-gcp を Docker Compose で起動する.

$ docker compose up -d
 ✔ Container gcp-floci-gcp-1  Started

ヘルスチェックエンドポイント /_floci-gcp/health を呼び出すとサービス別の状態を確認できる🎉

floci-gcp 0.4.0 では「16 サービス」サポートされているようだった.Google Cloud 公式でも gcloud beta emulators は提供されているけど,サービスが限定的でポートも独立して動くため,floci-gcp ではまとめて提供すると README に書いてあった.

$ curl -s http://localhost:4588/_floci-gcp/health | jq .
{
  "services": {
    "datastore": "running",
    "logging": "running",
    "monitoring": "running",
    "pubsub": "running",
    "gke": "running",
    "scheduler": "running",
    "iam": "running",
    "firestore": "running",
    "secretmanager": "running",
    "cloudfunctions": "running",
    "kms": "running",
    "cloudtasks": "running",
    "cloudsql": "running",
    "kafka": "running",
    "gcs": "running",
    "cloudrun": "running"
  },
  "version": "0.4.0"
}

1. Pub/Sub + Google Cloud Storage (GCS) + Python (Cloud Client Libraries)

以下のように Python (Cloud Client Libraries) スクリプトで Pub/Sub から取得したメッセージを使って Google Cloud Storage (GCS) バケットにオブジェクトを作るアーキテクチャを floci-gcp で試す.

まずは gcloud CLI で floci-gcp に Pub/Sub と Google Cloud Storage (GCS) バケットを作る.

$ export CLOUDSDK_API_ENDPOINT_OVERRIDES_PUBSUB=http://localhost:4588/
$ export CLOUDSDK_API_ENDPOINT_OVERRIDES_STORAGE=http://localhost:4588/
$ export CLOUDSDK_AUTH_DISABLE_CREDENTIALS=true
$ export CLOUDSDK_CORE_PROJECT=floci-local

$ gcloud pubsub topics create sandbox-topic
Created topic [projects/floci-local/topics/sandbox-topic].

$ gcloud pubsub subscriptions create sandbox-subscription --topic=sandbox-topic
Created subscription [projects/floci-local/subscriptions/sandbox-subscription].

$ gcloud storage buckets create gs://sandbox-bucket
Creating gs://sandbox-bucket/...

そして Pub/Sub にメッセージを2つ送る.

$ gcloud pubsub topics publish sandbox-topic \
    --message='{ "id": "id0001", "body": "This is message 0001." }'
messageIds:
- '1'

$ gcloud pubsub topics publish sandbox-topic \
    --message='{ "id": "id0002", "body": "This is message 0002." }'
messageIds:
- '2'

今回実行する app.py はこんな感じ❗️

import json
import os

from google.cloud import pubsub_v1, storage

project_id = os.environ['GOOGLE_CLOUD_PROJECT']

subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path(project_id, 'sandbox-subscription')

response = subscriber.pull(
    request={'subscription': subscription_path, 'max_messages': 10},
)

gcs = storage.Client(project=project_id)
bucket = gcs.bucket('sandbox-bucket')

ack_ids = []
for received_message in response.received_messages:
    data = received_message.message.data
    body = json.loads(data)
    bucket.blob(f'{body["id"]}.json').upload_from_string(data)
    ack_ids.append(received_message.ack_id)

if ack_ids:
    subscriber.acknowledge(
        request={'subscription': subscription_path, 'ack_ids': ack_ids},
    )

最後に app.py を実行すると,期待通りに Google Cloud Storage (GCS) バケットにオブジェクトが作られていた👌

$ export PUBSUB_EMULATOR_HOST=localhost:4588
$ export STORAGE_EMULATOR_HOST=http://localhost:4588
$ export GOOGLE_CLOUD_PROJECT=floci-local

$ uv run app.py

$ gcloud storage ls gs://sandbox-bucket
gs://sandbox-bucket/id0001.json
gs://sandbox-bucket/id0002.json

$ gcloud storage cat gs://sandbox-bucket/id0001.json | jq .
{
  "id": "id0001",
  "body": "This is message 0001."
}

2. Terraform + Cloud Run

floci-gcp は Cloud Run もサポートしているため Terraform から Cloud Run をデプロイする.

まず provider.tf を実装する.プロバイダー設定の cloud_run_v2_custom_endpoint に floci-gcp を設定してある.

provider "google" {
  project = "floci-local"
  region  = "asia-northeast1"

  user_project_override = false

  cloud_run_v2_custom_endpoint = "http://localhost:4588/v2/"
}

さらに cloud-run.tf を実装する.他にも terraform.tf も必要だけど割愛する.

resource "google_cloud_run_v2_service" "sandbox" {
  name     = "sandbox-hello"
  location = "asia-northeast1"

  deletion_protection = false

  template {
    containers {
      image = "us-docker.pkg.dev/cloudrun/container/hello"
    }
  }
}

output "uri" {
  value = google_cloud_run_v2_service.sandbox.uri
}

Terraform でデプロイするときにイメージがないと以下のエラーが出るため事前に docker pull コマンドを実行しておく.

Error: Error waiting to create Service: Error waiting for Creating Service: Error code 13, message: Status 404: {"message":"No such image: us-docker.pkg.dev/cloudrun/container/hello:latest"}

そして Terraform でデプロイまで完了👌今回は http://sandbox-hello-1efb2c36c23f.asia-northeast1.run.localhost.floci.io:4588 という URL になっていた.

$ docker pull us-docker.pkg.dev/cloudrun/container/hello

$ terraform init
$ terraform plan
$ terraform apply

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

uri = "http://sandbox-hello-1efb2c36c23f.asia-northeast1.run.localhost.floci.io:4588"

実際に Cloud Run の URL にアクセスすると期待通りにアプリケーションにアクセスできた❗️アプリケーションの画像に関しては最初表示されてなくて,Docker Compose に FLOCI_GCP_SERVICES_CLOUDRUN_EXECUTION_URL_HOST_SUFFIX: localhost.floci.io を追加してうまく表示されるようになった.

This container does not seem to be running on Cloud Run. と表示されているのは興味深かった.GoogleCloudPlatform/cloud-run-hello の実装を見た感じだと,Cloud Run の metadata server にアクセスできずプロジェクト情報などが取得できていないようだった.

ちなみに floci-gcp の Cloud Run は内部的に指定したコンテナが起動するようになっているため,ここで docker ps コマンドを実行すると確認できる.

$ docker ps --format 'table {{.ID}}\t{{.Names}}\t{{.Image}}'

CONTAINER ID   NAMES                                                                                   IMAGE
e20301e49942   floci-cloudrun-sandbox-hello-sandbox-hello-00001-fdc4cce8-d9c5-4df5-999b-8926773a94e9   us-docker.pkg.dev/cloudrun/container/hello
dcaed8366a56   gcp-floci-gcp-1

まとめ

Floci が提供する Google Cloud エミュレーター floci-gcp を試してみた.2026年5月頃から開発がスタートしたプロジェクトでまだまだサポートされているサービスは多くないけど,今後どんどん発展していく可能性がありそう❗️応援したいと思う.

まだ floci-gcp で試せていないサービスもあるので引き続き使っていくぞ💪

関連記事

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com