ruby-on-railsamazon-s3papercliplocalstack

Different URLs for downloading and uploading with paperclip on S3 storage


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?


Solution

  • 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.