alumni_lookup

Photo Storage Setup (S3 / Cloudinary)

Last Updated: December 2, 2025
Purpose: Configure image storage for alumni photos in production.

See Also: For full environment and deployment pipeline documentation, see:


Quick Setup for Alumni Photo Feature on Heroku + S3

1. Add Required Gems

bundle add aws-sdk-s3

2. Configure Storage (config/storage.yml)

# Add this to your existing storage.yml
amazon:
  service: S3
  access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
  secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
  region: us-west-2  # Choose region closest to your users
  bucket: alumni-lookup-<%= Rails.env %>
  public: false

3. Update Production Environment (config/environments/production.rb)

Add this line:

config.active_storage.service = :amazon

4. Create AWS Resources

S3 Bucket Setup:

  1. Login to AWS Console
  2. Create bucket: alumni-lookup-production
  3. Keep all default security settings (block public access)
  4. Add CORS configuration:
[
  {
    "AllowedHeaders": ["*"],
    "AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
    "AllowedOrigins": ["https://your-app-name.herokuapp.com"],
    "ExposeHeaders": ["ETag"]
  }
]

IAM User Setup:

  1. Create new IAM user: alumni-lookup-s3
  2. Attach this inline policy:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::alumni-lookup-production",
        "arn:aws:s3:::alumni-lookup-production/*"
      ]
    }
  ]
}
  1. Generate Access Key + Secret Key

5. Configure Rails Credentials

# Edit encrypted credentials
EDITOR="code --wait" rails credentials:edit

# Add these lines:
aws:
  access_key_id: AKIA...  # Your AWS Access Key
  secret_access_key: ...  # Your AWS Secret Key

6. Deploy to Heroku

# Commit changes
git add .
git commit -m "Add S3 configuration for production photo storage"

# Deploy
git push heroku main

# Set master key (copy from config/master.key)
heroku config:set RAILS_MASTER_KEY=your_master_key_here

7. Test Photo Upload

  1. Visit your Heroku app
  2. Find an alumni record
  3. Upload a test photo
  4. Verify it appears in your S3 bucket

Alternative: Cloudinary Setup

If you prefer Cloudinary for better image optimization:

1. Sign up for Cloudinary

2. Add Gems

bundle add cloudinary activestorage-cloudinary-service

3. Configure Storage

# Add to config/storage.yml
cloudinary:
  service: Cloudinary
  cloud_name: <%= Rails.application.credentials.dig(:cloudinary, :cloud_name) %>
  api_key: <%= Rails.application.credentials.dig(:cloudinary, :api_key) %>
  api_secret: <%= Rails.application.credentials.dig(:cloudinary, :api_secret) %>

4. Update Production Environment

# In config/environments/production.rb
config.active_storage.service = :cloudinary

5. Set Heroku Config

heroku config:set CLOUDINARY_URL=cloudinary://api_key:api_secret@cloud_name

Cost Comparison

S3 (Estimated monthly cost for 1000 alumni photos)

Cloudinary

Recommendation

For your alumni lookup app: Start with Cloudinary for the following reasons:

  1. Free tier will likely cover your needs
  2. Automatic optimization - converts to WebP, optimizes quality
  3. Built-in CDN - faster image delivery worldwide
  4. Simpler setup - no AWS account needed
  5. Better for Rails - designed specifically for web applications

You can always migrate to S3 later if you outgrow Cloudinary’s free tier.