Posted 5 days ago. Visible to the public. Linked content. Auto-destruct in 55 days

Updated: CarrierWave: Default Configuration and Suggested Changes

Card has been rewritten. Suggestions are more concrete, and card contains a suggested initializer.

Changes

  • -The [current default configuration of CarrierWave](https://github.com/carrierwaveuploader/carrierwave/blob/13330a70323cde83b319520f5c1874227de79cdf/lib/carrierwave/uploader/configuration.rb) looks like this. Make sure to check and (if necessary) configure these defaults when adding CarrierWave to a project.
  • +CarrierWave comes with a set of default configuration options which make sense in most cases. However, you should review these defaults and adjust for your project wherever necessary.
  • +You will also find suggestions on what to change below.
  • -```
  • - config.permissions = 0644
  • - config.directory_permissions = 0755
  • - config.storage_engines = {
  • - :file => "CarrierWave::Storage::File",
  • - :fog => "CarrierWave::Storage::Fog"
  • - }
  • - config.fog_attributes = {}
  • - config.fog_credentials = {}
  • - config.fog_public = true
  • - config.fog_authenticated_url_expiration = 600
  • - config.fog_use_ssl_for_aws = true
  • - config.fog_aws_accelerate = false
  • - config.store_dir = 'uploads'
  • - config.cache_dir = 'uploads/tmp'
  • - config.delete_tmp_file_after_storage = true
  • - config.remove_previously_stored_files_after_update = true
  • - config.downloader = CarrierWave::Downloader::Base
  • - config.root = lambda { CarrierWave.root }
  • -config.base_path = CarrierWave.base_path
  • - config.enable_processing = true
  • - config.ensure_multipart_form = true
  • -```
  • +## Undestanding the default configuration
  • -Only set `cache_storage` when you need it to be different from the base `storage`.
  • -```
  • - config.storage = :file # or :fog
  • -config.cache_storage = nil
  • -```
  • +Here is the [current default config for version 2](https://github.com/carrierwaveuploader/carrierwave/blob/v2.2.3/lib/carrierwave/uploader/configuration.rb):
  • -When handling large files, you should [consider setting these to `true`](/makandra/46224).
  • -```
  • - config.move_to_cache = false
  • - config.move_to_store = false
  • +```ruby
  • +config.permissions = 0644
  • +config.directory_permissions = 0755
  • +config.storage_engines = {
  • + :file => "CarrierWave::Storage::File",
  • + :fog => "CarrierWave::Storage::Fog"
  • +}
  • +config.storage = :file
  • +config.cache_storage = nil
  • +config.fog_attributes = {}
  • +config.fog_credentials = {}
  • +config.fog_public = true
  • +config.fog_authenticated_url_expiration = 600
  • +config.fog_use_ssl_for_aws = true
  • +config.fog_aws_accelerate = false
  • +config.store_dir = 'uploads'
  • +config.cache_dir = 'uploads/tmp'
  • +config.delete_tmp_file_after_storage = true
  • +config.move_to_cache = false
  • +config.move_to_store = false
  • +config.remove_previously_stored_files_after_update = true
  • +config.downloader = CarrierWave::Downloader::Base
  • +config.ignore_integrity_errors = true
  • +config.ignore_processing_errors = true
  • +config.ignore_download_errors = true
  • +config.validate_integrity = true
  • +config.validate_processing = true
  • +config.validate_download = true
  • +config.root = lambda { CarrierWave.root }
  • +config.base_path = CarrierWave.base_path
  • +config.enable_processing = true
  • +config.ensure_multipart_form = true
  • +```
  • +
  • +Notes:
  • +
  • +* If no `cache_storage` is set, CarrierWave uses the configured `storage` for caching. Only set a value if you need a different type of cache storage.
  • +* Even though `ignore_integrity_errors = true` sounds like you'd want that to be set to `false`, CarrierWave will actually not ignore errors with the default settings. Your ActiveRecord instances will receive validation errors, because e.g. `validate_integrity = true` is set.
  • +
  • +
  • +## Suggested changes
  • +
  • +* We strongly suggest some kind of nested directory structure for performance reasons, unless you know you will be storing only a few files.
  • + For that, implement a `store_dir` instance method in your uploader (or an `ApplicationUploader`, if you have one). We have [a separate card on how to do that](/makandra/498180).
  • + We suggest you also clear the `store_dir` config setting to avoid any confusion:
  • + ```ruby
  • + config.store_dir = nil
  • + ```
  • +
  • +* Do not implement `cache_dir` as an instance method on your uploader classes.
  • + While that works for uploading files and re-displaying uploaded (but not yet fully stored) files on form round trips, it breaks CarrierWave's `clean_cached_files!` method (see next item).
  • + If you want to specify a custom directory, just set it in the configuration:
  • + ```ruby
  • + config.cache_dir = ...
  • + ```
  • +
  • +* Enable cleaning up old files from the cache directory. CarrierWave provides `CarrierWave::Uploader::Base.clean_cached_files!` for that already, but you need to call regularly from your preferred scheduler. For example, when using whenever, you should have something like this in your `schedule.rb`:
  • + ```ruby
  • + every :day, at: '05:00', roles: [:cron] do
  • + runner 'ApplicationUploader.clean_cached_files!'
  • + end
  • + ```
  • +
  • +* When handling large files, consider enabling these options:
  • + ```ruby
  • + config.move_to_cache = true
  • + config.move_to_store = true
  • + ```
  • + We have [a separate card](/makandra/46224) about that.
  • +
  • +* Store test files separately. Also add support for parallel tests. You can easily do that be setting `config.root`:
  • + ```ruby
  • + config.root = "#{Rails.public_path}/system/#{Rails.env}#{ENV['TEST_ENV_NUMBER']}".freeze
  • + ```
  • +
  • +* For debugging purposes (e.g. trying to hunt down a staging bug locally), it might make sense to allow reading files from a separate environment. You you could read from an ENV variable instead of using your `Rails.env`.
  • +
  • +In total, here is a suggested configuration that you can put into `config/initializers/carrierwave.rb`:
  • +```ruby
  • +UPLOADER_ENV = (ENV['UPLOADER_ENV'] || Rails.env.to_s).freeze
  • +
  • +CarrierWave.configure do |config|
  • + config.root = "#{Rails.public_path}/system/#{UPLOADER_ENV}#{ENV['TEST_ENV_NUMBER']}".freeze
  • + config.cache_dir = File.join(config.root, 'upload_cache').freeze
  • + config.store_dir = nil # computed per record by an instance method; we remove the static value to avoid confusion.
  • +
  • + # CarrierWave's `base_path` and not supposed to reference a file system path, but used for URL generation.
  • + # Hence, it needs to be relative to the public directory, and start with a slash.
  • + config.base_path = config.root.delete_prefix(Rails.public_path.to_s).freeze
  • +
  • + # Optional: Move files instead of copying. Improves performance when dealing with large files, but may introduce caveats.
  • + # config.move_to_cache = true
  • + # config.move_to_store = true
  • +end
  • ```
  • -When these errors are ignored, caching will fail silently. Un-ignoring will raise appropriate exceptions.
  • -"Integrity" is about valid files, e.g. matching extension white- or blacklists. "Processing" is about `process` calls, e.g. for changing image resolution. "Download" is when CarrierWave loads a file from a remote location via `remote_<mounted_as>_url`.
  • -```
  • - config.ignore_integrity_errors = true
  • - config.ignore_processing_errors = true
  • - config.ignore_download_errors = true
  • -```
  • -
  • -These add ActiveRecord validations, so you will still be informed of errors (see above) as validation errors.
  • -```
  • - config.validate_integrity = true
  • - config.validate_processing = true
  • - config.validate_download = true
  • -```
  • +(And don't forget about the recurring task to clean cached files.)

Does your version of Ruby on Rails still receive security updates?
Rails LTS provides security patches for unsupported versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2).

Owner of this card:

Avatar
Arne Hartherz
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Arne Hartherz to makandra dev
This website uses short-lived cookies to improve usability.
Accept or learn more