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.
Understanding the default configuration
Here is the current default config for version 2 Show archive.org snapshot :
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 # (1)
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 # (2)
config.ignore_processing_errors = true
config.ignore_download_errors = true
config.validate_integrity = true # (3)
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 configuredstorage
for caching. Only set a value if you need a different type of cache storage. -
ignore_*_errors
means "do not raise exceptions on error" (during caching). If you're performing uploads async, i.e. uploading files to cache and using the cache key to later store the upload to a model, you may setignore_*_errors
tofalse
. This way, you'll be informed about errors already during upload, instead of later during model save. - Your ActiveRecord instances will receive validation errors where
validate_* = true
.
"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
.
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 astore_dir
instance method in your uploader (or anApplicationUploader
, if you have one). We have a separate card on how to do that.
We suggest you also clear thestore_dir
config setting to avoid any confusion:config.store_dir = nil # Configured in the uploader
-
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'sclean_cached_files!
method (see next item).
If you want to specify a custom directory, just set it in the configuration: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 yourschedule.rb
:every :day, at: '05:00', roles: [:cron] do runner 'ApplicationUploader.clean_cached_files!' end
-
When handling large files, consider enabling these options:
config.move_to_cache = true config.move_to_store = true
We have a separate card about that.
-
Store test files separately. Also add support for parallel tests. You can easily do that by setting
config.root
: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
.
Suggested configuration
In total, here is a suggested configuration that you can put into config/initializers/carrierwave.rb
:
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 # Configured in the uploader
# CarrierWave's `base_path` is not supposed to reference a file system path, but is 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
And don't forget about the recurring task to clean cached files.