1
1

More than 3 years have passed since last update.

ActiveStorageにLocalStackのS3を利用するまでの手順

Last updated at Posted at 2020-11-02

結構苦戦したので忘備録として書いとく。

LocalStackとは

この辺よんでください。
https://github.com/localstack/localstack
https://qiita.com/rio_matsui/items/e0c2c772d4579d00a312

LocalStackの設定

とりあえずdocker-compose.ymlには下記のように書く

  localstack:
    image: localstack/localstack:0.12.1
    environment:
      SERVICES: s3
      AWS_ACCESS_KEY: 1234
      AWS_SECRET_ACCESS_KEY: 12345678
      DEFAULT_REGION: ap-northeast-1
      DATA_DIR: /data
      START_WEB: 0
      HOSTNAME_EXTERNAL: localstack
      INIT_SCRIPTS_PATH: /root/init
    volumes:
      - localstack-data:/data
      - ./docker/localstack:/root/init
    ports:
      - 4566:4566

volumes:
  localstack-data:
    driver: local

以下説明

環境変数

SERVICES: s3

ここには使いたいサービスを記述する、複数使いたい場合はカンマ区切りで書く。

AWS_ACCESS_KEY: 1234
AWS_SECRET_ACCESS_KEY: 12345678

ここは適当でいい、SECRETは8文字以上じゃないと怒られる

DEFAULT_REGION: ap-northeast-1

ここもとりあえずお好みで。

DATA_DIR: /data

永続化させるデータの保存場所、Volumeを作成してこのディレクトリにマウントさせている。

START_WEB: 0

LocalStackには管理画面みたいなものが一応あるが、
使いたい場合はlocalstack/localstack-fullというイメージを使う必要がある。
localstack/localstackだと管理画面は使えないのだがログをみると起動しようとしてエラーを吐いているので無効にする。

HOSTNAME_EXTERNAL: localstack

理由はたぶんここに書かれているのと一緒。
これを書かないとRails側のコンテナからアクセスができない。
https://qiita.com/imunew/items/b74cecb7e12a9b9c4441

INIT_SCRIPTS_PATH: /root/init

初期化用のスクリプトの配置場所
ここに下記のようなのスクリプトを書いて置いておくと起動時に実行してくれる。

cd /root/init
# コンテナにはawslocalが入ってるのでそちらを使ってBucketを作成する
awslocal s3 mb s3://test-bucket

今回は作成したスクリプトをコンテナ側にマウントして実行するようにしている。

      - ./docker/localstack:/root/init

ここに書いてない環境変数はここを参照
https://github.com/localstack/localstack#configurations

Port

    ports:
      - 4566:4566

LocalStackでは4566でアクセスを受け付けているのでポートフォワーディングを設定いれておく
ちなみにawscliで叩く場合は下記のようにEndpointを指定する。

aws --endpoint=http://localhost:4566 s3 ls s3://test-bucket --recursive

コンテナ内からの場合はawslocalコマンドが入ってるのでそちらを使うほうが楽。

これで立ち上げるとS3にBucketが作成されているはず。

aws --endpoint=http://localhost:4566 s3 ls
2020-11-02 10:12:10 test-bucket

Rails側の設定

ActiveStorageでS3を使うための設定はこのあたりのページを参照。
https://qiita.com/tsubasan1122/items/0171fe04754a760f7e4a

ここではLocalStackを使うのに必要な設定だけを記載

storage.yml

localstack:
  service: S3
  access_key_id: 1234
  secret_access_key: 12345678
  region: ap-northeast-1
  endpoint: http://localstack:4566
  force_path_style: true
  bucket: test-bucket

以下説明

  service: S3
  access_key_id: 1234
  secret_access_key: 12345678
  region: ap-northeast-1

ここはLocalStack側の設定に合わせておく

  endpoint: http://localstack:4566
  force_path_style: true

awsのapiの叩き先をlocalstack側に変更するために設定する。
ただし、このままだとS3にアクセスする際にhttp://#{endpoint}.#{Bucket名}でアクセスしにいこうとするため
force_path_styleというオプションをtrueにして回避する。

これで、LocalStack側に保存されるようになったはず。
以下確認

# 適当に画像を保存
file = "1.jpg"
content_type = 'image/jpg'
image = Image.first
image.image.attach(io: File.open(file), filename: File.basename(file), content_type: content_type)

# S3の画像のキーを確認
image.image.attachment.blob.key
"p1fp3sd0mqxscrvcx960nqa7caal"

# localstack側に画像が保存されているか確認
aws --endpoint=http://localhost:4566 s3 ls s3://test-bucket                                                              
2020-11-02 11:59:17      14845 p1fp3sd0mqxscrvcx960nqa7caal # 同一のキーが存在する

その他

ファイルの保存はできるが、画像をブラウザに表示させようとしたときに取得されるURLのドメインが http://localstack:4566 になってしまう。
この辺は下記のページのようにURLを返すメソッドを作成して対応した。
https://qiita.com/shouta-dev/items/0b9569bf5522cca4cf3c

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1