Uploading Files to AWS S3 with Ruby on Rails

November 28, 2024

Setting up file uploads to AWS S3 can seem daunting, but with the right approach, it’s straightforward. This guide walks you through the process step by step, covering configuration, error handling, and best practices.


🚀 Need Expert Ruby on Rails Developers to Elevate Your Project?

Fill out our form! >>


1. Prerequisites

Before starting, ensure your Rails application supports file uploads. If not, check out tutorials on setting up file uploads with Active Storage.

The goal is to upload files to S3 and generate publicly accessible URLs that can be used in external services like Stripe Checkout.


2. Adding AWS SDK

Start by adding the required gem to your Rails app:

bundle add aws-sdk-s3

This gem integrates seamlessly with Active Storage’s storage.yml, which supports various storage providers like AWS, GCP, and Azure.


3. Setting Up S3

  • Create an S3 Bucket:
  1. Log in to the AWS Management Console.
  2. Navigate to S3 and create a bucket (e.g., creators-development) in a suitable region (e.g., us-east-1).
  3. Disable public access for now.
  • Create IAM User:
  1. Go to IAM and create a new user (e.g., active_storage_agent) with programmatic access.
  2. Assign the user S3 Full Access permissions.
  3. Save the Access Key ID and Secret Access Key securely.
  • Store Credentials in Rails: Add your keys to Rails credentials:

Add your keys to Rails credentials:

aws:
  access_key_id: "<your-access-key>"
  secret_access_key: "<your-secret-key>"

4. Update storage.yml:

  • Configure Active Storage to use your S3 bucket:

5. Update Environment

Configuration: Set the storage service in config/environments/development.rb:

config.active_storage.service = :amazon

Restart your Rails server after making these changes.


4. Handling Common Errors

  • CORS Issues: If uploads fail due to CORS (Cross-Origin Resource Sharing), update the CORS configuration in your S3 bucket permissions. Use the example provided in Rails documentation, or set up wildcard access (*) during development.
  • Debugging: Check logs for errors and ensure the keys in storage.yml match your Rails credentials.

5. Generating Public URLs

Localhost URLs aren’t publicly accessible, which is essential for Stripe Checkout. Use ngrok to expose your local server with a public URL.

  1. Start ngrok:
ngrok http 3000

2. Update config.hosts in application.rb:

config.hosts << "your-ngrok-subdomain.ngrok.io"

3. Restart your server and ensure URLs generated for uploaded files are publicly accessible.


6. Exporting Files to Stripe

When sending images to Stripe Checkout, generate a processed variant of the image URL using Active Storage:

product.photo.representation(resize_to_limit: [500, 500]).processed.url

This ensures the file is properly sized and accessible.


7. Production Considerations

  • Create a separate S3 bucket for production (e.g., creators-production).
  • Update config/environments/production.rb to use the production bucket.

This guide simplifies integrating AWS S3 with Rails for file uploads, leveraging tools like Active Storage and ngrok to create scalable, robust solutions. With this setup, you’re ready to handle file uploads effectively in development and production.

Happy coding! 🚀

Leave a comment