ローカル環境でS3の機能を擬似的に再現するモジュールを使ってみた

こんにちは。広告システム開発部の小林です。

私が参加しているプロジェクトでは、AWSのS3を使用しているのですが、phpunitなどのテスト実行時にS3へのアクセスが走ってしまうことがあります。
S3はアクセスとストレージ内のファイルの容量によって課金が発生するため、テスト実行時に費用が発生することを避けたいと思いました。
そこで、ローカルの閉じた環境下でS3を使用できないかと調べていたらs3rverというモジュールを見つけましたので紹介させていただきます。

s3rverとは

ローカル環境に擬似的にS3の機能を再現できる、Node.jsのnpmでインストール可能なモジュールです。

https://www.npmjs.com/package/s3rver

s3rverで再現可能なS3の機能

  • バケット
    • 作成
    • リスト表示(バケット、ファイル)
    • 削除
  • ファイル
    • 保存
    • 取得
    • 削除

では、実際に使ってみます。 今回はテストを実施する環境としてローカル環境のvagrant上に仮想環境を用意しました。

環境

CentOS : 6.7(仮想環境)

PHP : 5.6.19
AWS SDK for PHP : 2.0
Node.js : v0.11.16
npm : 2.3.0
s3rver : 1.0.2

s3rverのインストール

インストールはnpmコマンドで行います。 Node.jsとnpmのインストールについては割愛させていただきます。

$ npm install s3rver -g
$ s3rver --version
1.0.2

これでインストールは完了です。

s3rverの使い方

まずはオプションについてです。

$ s3rver --help

  Usage: s3rver [options]

  Options:

    -h, --help                  output usage information
    --version                   output the version number
    -h, --hostname [value]      Set the host name or ip for the server
    -p, --port <n>              Set the port of the http server
    -s, --silent                Suppress log messages
    -i, --indexDocument [path]  Index Document for Static Web Hosting
    -e, --errorDocument [path]  Custom Error Document for Static Web Hosting
    -d, --directory [path]      Data directory
    -c, --cors                  Enable CORS

主に使用するオプションは、以下になると思います。

  • -h, –hostname
    • 受け付けるホストの名前かIPアドレスを指定します。
  • -p, –port
    • 受け付けるポート番号の設定を行います。
    • デフォルトは 4568 となっています。
  • -d, –directory
    • ファイルを格納するためのディレクトリを指定します。

192.168.33.125(仮想環境へアクセス可能なIPアドレス)の/tmp/s3rverをs3rverのData directoryに指定するときのコマンド

$ s3rver -h 192.168.33.125 -d /tmp/s3rver
now listening on host 192.168.33.125 and port 4568

これでs3rverが起動したので擬似的にS3として使用することが可能です。

起動した状態で、http://192.168.33.125:4568 にブラウザでアクセスするとXMLが表示されます。 XMLの内容は、バケットの一覧となっています。

alt

注意点

s3rverが起動して使用できる状態にはなりましたが、注意点があります。

ファイルを指定したディレクトリに直接置いてもファイルとして認識されない

/tmp/s3rver/txt/test.txt としてファイルを設置してもs3rverでは認識されません。

各言語のAWS SDKなどを使用してs3rverへファイルをputするとs3rver上でファイルとして認識されます。 AWS SDKを使用する際、endpointは起動時に指定したURLに設定する必要があります。

phpでのファイルアップロードのサンプル (AWS SDKを使用します)

<?php // オートローダを登録
require('/var/www/vendor/autoload.php');

use Aws\Credentials\Credentials;
use Aws\S3\S3Client;

// S3へ接続の設定を行う
// ACCESS_KEY_ID, SECRET_ACCESS_KEYはs3rverを使用する場合はAWSのアカウントのACCESS_KEY_IDとSECRET_ACCESS_KEYを指定する必要はありません。
$credentials = new Credentials('ACCESS_KEY_ID', 'SECRET_ACCESS_KEY');
$s3 = S3Client::factory(
    [
        'region'      => 'ap-northeast-1',
        'version'     => '2006-03-01',
        'credentials' => $credentials,
        'endpoint'    => 'http://192.168.33.125:4568',
    ]
);

// ファイルをアップロードする
$result = $s3->putObject(
    [
        'Bucket' => 'txt',
        'Key'    => 'test.txt',
        'Body'   => 'Hello, world!'
    ]
);
?>

上記のサンプルコードを実行後にディレクトリを確認すると以下のようになります。

$ ls -l /tmp/s3rver/txt/
合計 4
drwxrwxr-x 2 vagrant vagrant 4096  7月 11 07:26 2016 test.txt

アップロード時にkeyに指定したtest.txtがディレクトリで作成されています。 test.txtの中身は以下のようになっています。

$ ls -al /tmp/s3rver/txt/test.txt/
合計 16
drwxrwxr-x 2 vagrant vagrant 4096  7月 11 07:26 2016 .
drwxrwxr-x 3 vagrant vagrant 4096  7月 11 07:26 2016 ..
-rw-rw-r-- 1 vagrant vagrant   13  7月 11 07:26 2016
.dummys3_content
-rw-rw-r-- 1 vagrant vagrant  197  7月 11 07:26 2016
.dummys3_metadata

.dummys3_contentがファイルの実体、.dummys3_metadataがファイルのメタデータとなっています。 この命名規則でファイルをディレクトリに設置すれば、aws sdkを通してputしなくてもs3rverにファイルとして認識させることは可能です。

ファイルについての注意点を記載しましたが、バケットは -d で指定したディレクトリに新規でディレクトリを作成することでバケットとして認識されます。

まとめ

簡単にですが、s3rverの使い方と注意点について紹介させていただきました。 s3rver起動後は、AWS SDK側への設定はendpointを指定するだけなので、特に意識することなく使うことができて非常に簡単だと思います。 テストや実際のAWS環境にアクセスすることなく実験したいときなどに使えると思いますので、機会があれば是非使ってみてください。