Cloud Storage*1使っていますか?
私は最近、画像の保存場所によく使っています。
最近使ったものだと、大学のプロジェクトで作っているWebアプリのユーザアバターを保存する場所として使っています。
さて、このCloud Storageですがテストを書いたりデバッグをする中でローカルで実行させたいという話題がでます。
そのため、このブログではCloud Storageをdocker-composeで実行させる方法とかちょっと便利な使い方とかを紹介します。
fake-server
Cloud Storageは公式でローカルのDockerイメージは提供されていません。
そのため、fsouza/fake-gcs-server
を使用します。
version: '3' services: gcs: image: fsouza/fake-gcs-server tty: true ports: - 4443:4443 volumes: - ./.data:/data/[bucket name] - ./.storage:/storage command: -scheme http -public-host ${URL:-localhost}:4443
ここで、注意しておきたいのがvolumes
の/data/
以下がbucket nameになる点です。ここで、bucket nameの空のディレクトリを作成しておかないとbucket nameを指定して接続した際にエラーが発生してしまいます。
また、fake-server実行時の-public-host
フラグはURLで画像にアクセスする際にはおそらく必須となります。
docker-composeの環境変数は.env
に書くかexport
するかで定義することができます*2。
さらに、fake-serverで保存されているファイルは.storage
にマウントすることでテストなどでちゃんと設定できているかも確認できます。(閲覧する場合、sudo chmod -R 755 .storage
で権限を変える必要があります。)
アプリケーションコード
これは、fake-serverが例を紹介しています。
おそらく、全てGoogle公式のGCSのパッケージを使用してアクセスできます。
Goとかはアクセスするのが一番簡単でSTORAGE_EMULATOR_HOST
の環境変数にfake-serverのホストを入れればそのままそこにアクセスしてもらえます。
// Set STORAGE_EMULATOR_HOST environment variable. err := os.Setenv("STORAGE_EMULATOR_HOST", "localhost:4443") if err != nil { // TODO: Handle error. } // Create client as usual. client, err := storage.NewClient(ctx) if err != nil { // TODO: Handle error. } // This request is now directed to http://localhost:4443/storage/v1/b // instead of https://storage.googleapis.com/storage/v1/b if err := client.Bucket("my-bucket").Create(ctx, projectID, nil); err != nil { // TODO: Handle error. }
https://pkg.go.dev/cloud.google.com/go/storage#section-readme
Node.jsなんかは、そういった便利な環境変数は定義できないのでStorageオブジェクトのコンストラクタに引数で指定します。
// Creates a client const storage = new Storage({ apiEndpoint: "http://localhost:4443", });
上記コードだとローカルしか実行できないので、以下のようにすると良さそうです。
let config = undefined; if(process.env.NODE_ENV !== "production") { config = { apiEndpoint: "http://localhost:4443", }; } const storage = new Storage(config);
公開する
GCP内の実行環境にデプロイすれば特に設定することもなく簡単にCloud Storageに接続できます。
// これで、何も設定しなくてもつながる(GCP内のサービスか、環境変数が設定されている場合) const storage = new Storage();
また、別の環境でも同じことをしたい場合はGOOGLE_APPLICATION_CREDENTIALS
の環境変数にサービスアカウントキーの絶対パスを指定することでも可能*3です。
まとめ
GCSは便利なのでみんな使おう!!!