LocalStack は、AWS のサービスを開発環境において擬似的に使用できるモックフレームワークです。
定番の S3 から Lambda まで多くのサービスを開発環境で体験できます。
本記事では、Railsチュートリアルの SampleApp を使用し、コンテナ環境で実装します。
コンテナの設定は、Railsチュートリアルの開発環境を Docker でもっと便利にしなイカ!? - Qiitaの続きとなります。
今回の実装コードは右の通りです=>(実装コード --github)
- 実行環境
- Ruby: 2.4.9
- Rails: 5.1.2
- fog: 1.14.0
- carrierwave: 1.1.0
- references
□ LocalStack の設定
■ コンテナの追加
- version 0.11.0 から
http://localhost:4566
で全ての endpoint を受け付けている。 -
SERVICES
により、モックするサービスを定義する。 -
DATA_DIR: /tmp/localstack/data
により、投稿画像を永続化する。 -
volumes
で設定したディレクトリにスクリプトを配置すると、コンテナ生成時に実行してくれる( 詳細は後述 )。 - なお、access key 等を設定する必要はない。
./docker-compose.yml
...
smtp:
...
+ localstack:
+ image: localstack/localstack
+ ports:
+ - 8080:8080 # dashboard
+ - 4566:4566 # edge port
+ environment:
+ SERVICES: s3
+ AWS_DEFAULT_REGION: ap-northeast-1
+ DATA_DIR: /tmp/localstack/data
+ volumes:
+ - ./docker/localstack/:/docker-entrypoint-initaws.d
volumes:
...
■ 初期設定スクリプト
S3 保存用のバケットを生成する必要があるため、次のファイルを作成すること。
./docker/localstack/setup_s3.sh
awslocal s3 mb s3://microposts
□ 既存ファイルの修正
■ 保存場所を S3 に固定
app/uploaders/picture_uploader.rb
class PictureUploader < CarrierWave::Uploader::Base
...
- if Rails.env.production?
- storage :fog
- else
- storage :file
- end
+ storage :fog
...
end
■ carrier_wave の初期設定を変更
- 変更内容
- 本番環境でのみ設定が有効化されていたため、常に有効化した。
- LocalStack にアップロードするための設定として、本番環境以外における設定を追加した。
- 参考 URL
config/initializers/carrier_wave.rb
CarrierWave.configure do |config|
config.fog_credentials = {
:provider => 'AWS',
:region => ENV['S3_REGION'],
:aws_access_key_id => ENV['S3_ACCESS_KEY'],
:aws_secret_access_key => ENV['S3_SECRET_KEY'],
}
config.fog_directory = ENV['S3_BUCKET']
unless Rails.env.production?
config.fog_credentials.merge!(
{
# [app -> localstack] コンテナ間の通信用に設定 ( http://localstack:4566 )
:endpoint => ENV['S3_ENDPOINT'],
# デフォルトだと S3_BUCKET がサブドメインとなり接続できないため true に設定
:path_style => true,
}
)
# endpoint がコンテナ間の通信用であるため、ホスト側から画像にアクセスするための URL ( http://localhost:4566 )
config.asset_host = "#{ENV['S3_ASSET_HOST']}/#{ENV['S3_BUCKET']}"
end
end
■ 環境変数の設定
./docker-compose.yml
...
app:
...
environment:
APP_DATABASE_HOST: db
APP_DATABASE_USERNAME: root
APP_DATABASE_PASSWORD: pass
+ S3_REGION: ap-northeast-1
+ S3_ACCESS_KEY: dummy
+ S3_SECRET_KEY: dummy
+ S3_BUCKET: microposts
+ S3_ENDPOINT: http://localstack:4566
+ S3_ASSET_HOST: http://localhost:4566
...
□ テスト投稿
投稿前 |
---|
![]() |
投稿成功! |
---|
![]() |
□ 余談: 投稿画像の永続化
前述の通りDATA_DIR
を追加すると、投稿画像の永続化が可能となるが、コンテナ停止再起動でのみ有効となる。
もし、コンテナ削除時でもデータを保持したい場合、次の通り設定すること。
また、この設定の場合、意識的に volume を削除しないと保存容量が膨れ上がるため、注意する必要あり。
./docker-compose.yml
services:
datastore:
image: busybox
volumes:
- bundle_install:/usr/local/bundle
- db_data:/var/lib/postgresql/data
+ - localstack_data:/tmp/localstack
...
localstack:
image: localstack/localstack
ports:
- 8080:8080 # dashboard
- 4572:4572 # s3
environment:
SERVICES: s3
AWS_DEFAULT_REGION: ap-northeast-1
DATA_DIR: /tmp/localstack/data
volumes:
- ./docker/localstack/:/docker-entrypoint-initaws.d
+ - localstack_data:/tmp/localstack
volumes:
bundle_install:
db_data:
+ localstack_data:
□ メモ
コンテナから S3 保存を確認
docker-compose exec localstack ash
aws --endpoint-url=http://localstack:4572 s3 ls s3://${バケット名}
S3 に保存したファイルをコンテナ内にダウンロード
docker-compose exec localstack ash
aws --endpoint-url=http://localstack:4572 s3 cp #{key} ~/
cat ~/#{key}
ブラウザからファイルを確認
open http://localhost:4572/#{バケット名}
# TODO: ファイルの中身は 403 によりアクセス不可,何かしら設定が必要なはず
open http://localhost:4572/#{key}