AWS SDKをローカル開発環境で使用する際に、本番のAWSサービスの代わりにMinioを使用するケースについての説明です。
Minioは、S3互換のオブジェクトストレージを提供するオープンソースソフトウェアで、開発やテスト目的で使用されます。
環境
Docker-Compose内に、同一ネットワーク上で以下のコンテナーを構築しています:
• minioコンテナー(http://minio:9999 - アップロード時のエンドポイント)
• nodejsコンテナー(http://nodejs:3000)
目標:nodejsコンテナーからminioコンテナーへのファイルアップロード
上記の時、ローカル開発環境で連携時に設定パラメータの誤りによって頻繁に生じるエラーとその対処方法の記録。
本題
通常のS3操作では、以下の基本パラメータでS3Clientを生成するだけで十分です:
import {S3Client,PutObjectCommand} from '@aws-sdk/client-s3';
new S3Client({
credentials:{
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
},
region: process.env.AWS_REGION,
version: process.env.AWS_S3_VERSION
})
しかし、ローカル環境のMinioに接続する場合は、カスタムエンドポイントの指定が必要です。
return new S3Client({
endpoint: 'http://minio:9999',//ここ
forcePathStyle: true,//ここ
credentials:{
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
},
region: process.env.AWS_REGION,
version: process.env.AWS_S3_VERSION
})
大事なパラメータ
endpointの指定を忘れると、「AWSにそのアクセスキーは存在しない」というエラーが表示されます(ローカル環境で実行しているため、当然AWSに記録されているはずがなく、アクセスキーが間違っていると思い込んで何度も修正してしまいがちです)
InvalidAccessKeyId: The AWS Access Key Id you provided does not exist in our records.
なお、forcePathStyleの指定を忘れると、URLの形式がS3の仕様に従ってしまい、「見つからない」というエラーが発生します。MinioではURLのホスト名にバケット名を含める形式で指定する必要があります。
Error: getaddrinfo ENOTFOUND my-bucket.minio
endpoint:string | Endpoint | Provider<Endpoint> | EndpointV2 | Provider<EndpointV2>
カスタムエンドポイントは、S3のローカルバージョンを使用する場合などの特別な場合にのみ使用します。
S3のホスト名へのバケット名適用などのエンドポイント変換機能は、このカスタムエンドポイントでも利用可能です。
forcePathStyle:boolean
S3 オブジェクトのURLパス形式を強制的に変更するかどうかを指定するオプションです。
https://s3.amazonaws.com/<bucketName>/<key>
↓
https://<bucketName>.s3.amazonaws.com/<key>
trueに設定すると、URLのホスト名部分にバケット名が含まれる形式となります。
おまけ
以前にPHPでも同様のエラーが発生しました(学習していない)ので、参考として記録しています。
use Aws\S3\S3Client;
return new S3Client([
'endpoint' => "http://minio:9999",
'use_path_style_endpoint' => true,
'credentials' => [
'key' => config('filesystems.disks.s3.key'),
'secret' => config('filesystems.disks.s3.secret'),
],
'region' => config('filesystems.disks.s3.region'),
'version' => 'latest'
]);
参考
AWS SDK for JavaScript v3 https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-client-s3/Interface/S3ClientConfig/