Warm tip: This article is reproduced from stackoverflow.com, please click
amazon-s3 ruby-on-rails paperclip localstack

Different URLs for downloading and uploading with paperclip on S3 storage

发布于 2020-04-03 23:50:48

For local development I am using a localstack Docker Container as AWS Sandbox with this Paperclip configuration:

config.paperclip_defaults = {
  storage:        :s3,
  s3_credentials: {
    access_key_id:     ENV['AWS_ACCESS_KEY_ID'],
    secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
  },
  bucket:         'my-development',
  s3_region:      'localhost-region',
  s3_host_name:   'localhost:4572',
  url:            ':s3_path_url',
}

Links for download content are generated correctly and are working:

http://localhost:4572/my-development/files/downloads/be-fl-che-spezialtiefbau-mischanlage-750_ae0f1c99d8.pdf

But when I want to upload new files I get an Aws::Errors::NoSuchEndpointError based on a different URL:

https://my-development.s3.localhost-region.amazonaws.com/files/downloads/_umschlag-vorlage_c534f5f25e.pdf

I searched and debugged some hours but couldn't find out where this url is generated and why it uses amazonaws.com as host.

Any hint where to look at?

Questioner
Sven R.
Viewed
76
Sven R. 2020-02-10 18:34

I found a way to get it working.

Add explicit endpoint url to configuration

# config/environments/development.rb
config.paperclip_defaults = {
  storage:        :s3,
  s3_credentials: {
    access_key_id:     ENV['AWS_ACCESS_KEY_ID'],
    secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
  },
  s3_options:     {
    endpoint: 'http://localhost:4572/my-development',
  },
  bucket:         'my-development',
  s3_region:      'localhost-region',
  s3_host_name:   'localhost:4572',
  url:            ':s3_path_url',
}

As the url will be renamed with the bucket name by AWS Gem, the resulting domain will be my-development.localhost. I didn't found any other solution yet than to add this subdomain into my /etc/hosts:

127.0.0.1   localhost
127.0.0.1   my-development.localhost
255.255.255.255 broadcasthost
::1             localhost
::1             my-development.localhost

This is not very clean but works. Maybe I found a better work around later.