I have a Rails 7 app running on Heroku. The app is simple, in theory: Users sign up, and can upload video files as part of a survey.
I'm using Carrierwave for the upload process, but ran into memory and timeout issues using Heroku. I've tried to implement the carrierwave-backgrounder
gem alongside sidekiq
and redis
.
I've pushed to a staging app on Heroku and the timeouts on form submit seem to be resolved, but the files aren't being uploaded to the S3 bucket. I've set the S3 credentials in the staging app's config vars the same as on the production app.
Inspecting the Video record in the rails console shows filenames in the relevant table columns, but no files are showing in the S3 bucket.
Video.rb:
class Video < ApplicationRecord mount_uploaders :video_files, VideoUploader store_in_background :video_filesend
carrierwave.rb
CarrierWave.configure do |config| config.fog_credentials = { provider: 'AWS', # required aws_access_key_id: ENV.fetch('AWS_ACCESS_KEY_ID'), # required unless using use_iam_profile aws_secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY'), # required unless using use_iam_profile use_iam_profile: true, # optional, defaults to false region: ENV.fetch('AWS_REGION') # optional, defaults to 'us-east-1' } config.fog_directory = ENV.fetch('S3_BUCKET_NAME') # required config.fog_public = false # optional, defaults to true config.fog_attributes = { cache_control: "public, max-age=#{365.days.to_i}" } # optional, defaults to {} # For an application which utilizes multiple servers but does not need caches persisted across requests, # uncomment the line :file instead of the default :storage. Otherwise, it will use AWS as the temp cache store. # config.cache_storage = :fileend
VideoUploader.rb
class VideoUploader < CarrierWave::Uploader::Base include ::CarrierWave::Backgrounder::Delay cache_storage CarrierWave::Storage::File def cache_dir"uploads_cache/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end storage :fog def store_dir"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end def extension_allowlist %w(mp4 mov avi) endend
initializers/carrierwave_backgrounder.rb
CarrierWave::Backgrounder.configure do |c| c.backend :sidekiq, queue: :carrierwaveend
initializers/sidekiq.rb
Sidekiq.configure_server do |config| config.redis = { url: ENV["REDIS_URL"], ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE } }endSidekiq.configure_client do |config| config.redis = { url: ENV["REDIS_URL"], ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE } }end
sidekiq.yml
:queues: - [carrierwave, 1] - default
redis.rb
$redis = Redis.new(url: ENV["REDIS_URL"], ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE })
Procfile
worker: bundle exec sidekiq -c 2