Showing Posts From

Docker

ローカルDocker環境でSQSのモックElasticMQを利用する

ローカルDocker環境でSQSのモックElasticMQを利用する

AWS 環境で動作させるシステムの開発をしていて、ローカルの Docker 環境に SQS と同じ API で動作するモックを用意したくて ElasticMQ を利用してみました。[!CAUTION] 追記: 結局最終的に LocalStack を使いました。Docker イメージは幾つかありますが、roribio16/alpine-sqsを利用しました。 docker-compose.yml の用意 docker-compose の設定は以下のようにしました。 Node.js 環境も dokcer-compose で用意しておきます。 version: '3.7'services: # Node.js環境。開発時のnpmコマンド実行はここで行う。 node: image: node:12.18.3-alpine3.12 volumes: - ./:/project:delegated tty: true working_dir: /project environment: # AWS-SDKを動作させるのにダミーでいいので設定しておく必要がある AWS_REGION: ap-northeast-1 AWS_ACCESS_KEY_ID: local AWS_SECRET_ACCESS_KEY: dummy# 入力キュー # SQS互換のElasticMQを利用 input_queue: image: roribio16/alpine-sqs ports: # 管理画面へアクセスするポート - 9325:9325この alpine-sqs というイメージは default という名前のキューが最初から作成された状態で起動してくれます。 Node.js 環境の用意 コンテナを起動しておきましょう。 $ docker-compose up -dnode コンテナに入って作業します。alpine 版を使ってるので bash が入っていなくて sh を指定します[^1]。 [^1]: alpine を使っているのは、本番環境の Fargate 用コンテナをサイズの小さい alpine で作るつもりでいて、開発環境も同じに合わせたかったからです。debian を使った方が色々とカスタマイズが楽だと思います。 $ docker-compose exec node shここからは node コンテナ内でのコマンド実行の場合は、先頭を $ ではなく # で表します。 package.json を作成します。中身は適当でいいです。 # npm initAWS SDK をインストールします。 $ npm install aws-sdkAWS SDK でのアクセス まず送信用のスクリプトを作成します。 endpoint に用意した ElasticMQ のコンテナを指すように設定するのがポイントです。 const AWS = require('aws-sdk');const endpointUrl = 'http://input_queue:9324'; const queueUrl = endpointUrl + '/queue/default';const sqs = new AWS.SQS({ apiVersion: '2012-11-05', endpoint: endpointUrl, });const params = { // Remove DelaySeconds parameter and value for FIFO queues DelaySeconds: 10, MessageAttributes: { Title: { DataType: 'String', StringValue: 'The Whistler', }, Author: { DataType: 'String', StringValue: 'John Grisham', }, WeeksOn: { DataType: 'Number', StringValue: '6', }, }, MessageBody: 'Information about current NY Times fiction bestseller for week of 12/11/2016.', QueueUrl: queueUrl, };sqs.sendMessage(params, function (err, data) { if (err) { console.log('Error', err); } else { console.log('Success', data.MessageId); } });node コンテナ上で実行してみます。 # node send.jsホスト側のブラウザで http://localhost:9395/ にアクセスすると、管理画面でキューにメッセージが来ていることが確認できます。 (ただこの管理画面、キューからメッセージを削除しても削除したものも表示されます。それはそれで便利なんですが。) 次はポーリングを仕掛けて受信してみましょう。 const AWS = require('aws-sdk');const endpointUrl = 'http://input_queue:9324'; const queueUrl = endpointUrl + '/queue/default';const sqs = new AWS.SQS({ apiVersion: '2012-11-05', endpoint: endpointUrl, });async function poll() { const params = { QueueUrl: queueUrl, MaxNumberOfMessages: 10, WaitTimeSeconds: 20, MessageAttributeNames: ['Title', 'Author', 'WeeksOn'], }; return new Promise((resolve, reject) => { sqs.receiveMessage(params, (err, data) => { if (err) { console.error(err); reject(err); } else { console.log(data); resolve(data); } }); }); }async function main() { const data = await poll(); }main();node コンテナ上で実行します。 # node receive.js受信できればオッケーです。

ローカルDocker環境でS3Mockを利用する

ローカルDocker環境でS3Mockを利用する

AWS 環境で動作させているシステムの開発をしていて、ローカルの Docker 環境に S3 と同じ API で動作するモックがあったらいいなと思って調べたら、当然のようにありました。 S3 のモックサーバー候補 とりあえず見つかったのは以下です。abobe/S3Mock findify/S3Mock Fake S3 Mock S3 S3 Proxy上2つが有力候補。 3つ目の Fake S3 は古いバージョンはオープンソースだけど新しいバージョンは有料っぽい? 後ろ2つは adobe/S3Mock が似たようなプロジェクトとして紹介してました。 今回は findify/S3Mock を試した後に、結局 adobe/S3Mock を利用しました。[!CAUTION] 追記: 結局最終的に LocalStack を使いました。実際のプロジェクトでは TypeScript を使っているのですが、ここでは Javascript で解説します。 なぜ adobe/S3Mock にしたか? findify/S3Mock でデフォルトのバケットをコンテナ作成時に最初から作成しておく方法がすぐに分からなかったからです。 もちろん API を呼んで CreateBucket することはできます。 dokcer-compose.yml の用意 docker-compose の設定は以下のようにしました。 Node.js 環境も dokcer-compose で用意しておきます。 version: '3.7'services: # Node.js環境。開発時のnpmコマンド実行はここで行う。 node: image: node:12.18.3-alpine3.12 volumes: - ./:/project:delegated tty: true working_dir: /project environment: # AWS-SDKを動作させるのにダミーでいいので設定しておく必要がある AWS_REGION: ap-northeast-1 AWS_ACCESS_KEY_ID: local AWS_SECRET_ACCESS_KEY: dummy s3: image: adobe/s3mock environment: - initialBuckets=my-bucketinitialBuckets を指定することでコンテナ作成時にバケットも作成することができます。inisitalBuckets と複数形になっていますが、リストで複数作成させることができるようです。 - initialBuckets=my-bucket1,my-bucket2,my-bucket3Node.js 環境の用意 コンテナを起動しておきましょう。 $ docker-compose up -dnode コンテナに入って作業します。alpine 版を使ってるので bash が入っていなくて sh を指定します[^1]。 [^1]: alpine を使っているのは、本番環境の Fargate 用コンテナをサイズの小さい alpine で作るつもりでいて、開発環境も同じに合わせたかったからです。debian を使った方が色々とカスタマイズが楽だと思います。 $ docker-compose exec node shここからは node コンテナ内でのコマンド実行の場合は、先頭を $ ではなく # で表します。 package.json を作成します。中身は適当でいいです。 # npm initAWS SDK をインストールします。 $ npm install aws-sdkAWS SDK でのアクセス 適当に index.js とかの名前でファイルを作成しましょう。 まずは s3 クライアントオブジェクトを作成します。 const AWS = require('aws-sdk');const s3 = new AWS.S3({ apiVersion: '2006-03-01', // docker-compose環境の中ではサービス名がそのままホスト名として使える。s3コンテナの9090番ポートを指定。 endpoint: 'http://s3:9090', // S3Mock使う時は <バゲット名>.hostname:9090 でなく hostname:9090/<バゲット名> になってもらわないと困る s3ForcePathStyle: true, });endpoint と s3ForcePathStyle を指定する必要があります。 S3 の URL は昔は https://s3-<リージョン >.amazonaws.com/<バケット名> というパス形式と呼ばれるものが使われていました。 今は https://<バケット名>.s3-<リージョン>.amazonaws.com/ という仮想ホスト形式が使われています。 しかし S3Mock を使うときに仮想ホスト形式になってもらってはアクセスできないので、パス形式を利用するように指定しています。 9090 番ポートは HTTP 用で、9191 番ポートが HTTPS 用だそうです。HTTP しか試してませんが。 あとは普通に使ってもらえば大丈夫です。