Skip to main content
Premium

Configuration

Configure the module in the same initializer, after the require:

# config/initializers/habarico_uploads.rb
require "habarico_enterprise/uploads"

HabaricoEnterprise::Uploads::Config.enabled_providers = [:s3] # order = priority
HabaricoEnterprise::Uploads::Config.chunk_threshold = 5_242_880 # below this, FE uploads directly
HabaricoEnterprise::Uploads::Config.chunk_size = 5_242_880
HabaricoEnterprise::Uploads::Config.max_upload_size = nil # nil = no limit of your own
HabaricoEnterprise::Uploads::Config.dangerous_content_types =
HabaricoEnterprise::Uploads::Validations::DANGEROUS_CONTENT_TYPES # the built-in default; override or empty at your own risk

HabaricoEnterprise::Uploads::Config::S3.tmp_prefix = "tmp/uploads/"
HabaricoEnterprise::Uploads::Config::S3.presign_expiry = 3600
SettingDefaultWhat it does
Config.enabled_providers[]Ordered provider list (:s3, :tus); [] disables chunked upload entirely
Config.chunk_threshold5_242_880File size in bytes from which the chunked path is taken
Config.chunk_size5_242_880Size of one chunk / multipart part
Config.max_upload_sizenilLargest file (bytes) an upload may claim; nil applies no limit of your own. See Upload size limits
Config.dangerous_content_typesValidations::DANGEROUS_CONTENT_TYPESContent types refused by default; override or empty at your own risk. See The content-type blocklist
Config::S3.tmp_prefix'tmp/uploads/'Key prefix initiate writes temporary multipart objects under
Config::S3.presign_expiry3600How long (seconds) presigned PUT / upload_part URLs stay valid
Config::S3.initiate_urlderived from the drawn routePublic endpoint the frontend POSTs initiate requests to. Set it only to override the automatic value — e.g. when the admin is served behind a path the Rails app does not know about
Config::Tus.endpointnilPublic tusd (or tusd-proxy) endpoint the frontend uploads to; without it the tus provider is unavailable
Config::Tus.tmp_prefix'tmp/uploads/'Prefix tusd's pre-create hook rewrites upload IDs under; finalize refuses any upload_key outside of it
Config::Tus.tmp_rootnilFilesystem root tusd writes temp objects to — the same directory mounted as tusd's --upload-dir (see tus server setup)
caution

Config::Tus.tmp_root is a raw filesystem path, not an ActiveStorage::Service name. The Disk service shards objects into key[0..1]/key[2..3]/key subfolders, which would not match tusd's literal upload paths — that is why finalize reads the temp file straight off disk instead of through ActiveStorage.

Upload size limits​

The S3 provider presigns one URL per part, and the part count follows the size the client claims for a file nobody has uploaded yet. It therefore refuses outright, before anything is created in S3, any upload that would need more than Providers::S3::MAX_PARTS — 10 000 parts, S3's own multipart limit. That ceiling is not configurable: an upload past it could not be completed by S3 either way.

Config.max_upload_size is your own policy on top of that, and it is off by default. Left nil, the effective ceiling is MAX_PARTS * chunk_size — roughly 48.8 GiB at the default chunk size. Set it when your files are known to be far smaller:

HabaricoEnterprise::Uploads::Config.max_upload_size = 104_857_600 # 100 MiB

A field may also carry a size: validation of its own (see Upload validations). The two do not override each other — initiate applies whichever of the two is stricter, so Config.max_upload_size stays the app-wide ceiling no field can raise.

Either limit makes initiate answer 422 Unprocessable Entity — the request is well-formed, only the size it claims is not acceptable; the frontend shows the message on the file's row. The limit is a policy, not a guarantee — nothing verifies the claimed size against the bytes that actually arrive, so pair it with the lifecycle rule in S3 temporary file cleanup.

No per-field storage configuration​

Unlike the Python library, Ruby habarico assumes a single default ActiveStorage service for the whole app — there is no bucket/region/credentials setting here at all. The s3 provider reads them from ActiveStorage::Blob.service as-is; see Provider selection for what this means when a field's storage doesn't match.

See also​