Storage Configuration
Qarion supports multiple file storage backends for attachments (product files, meeting notes, ticket attachments). The storage backend determines where uploaded files are physically stored and how they are retrieved.
Supported Backends
| Backend | Identifier | Description |
|---|---|---|
| Filesystem | filesystem | Local server filesystem (default for development) |
| Amazon S3 | s3 | Amazon S3 or any S3-compatible object store (MinIO, DigitalOcean Spaces) |
| Google Cloud Storage | gcs | Google Cloud Storage buckets |
| Azure Blob Storage | azure | Microsoft Azure Blob Storage containers |
| Base64 | base64 | Inline base64 encoding in the database (legacy, not recommended for production) |
Configuring via Admin Panel
Navigate to Administration → System Settings → Storage to configure the storage backend. Settings saved here are stored in the database and take precedence over environment variables.
| Setting | Key | Description |
|---|---|---|
| Backend | storage.backend | One of: filesystem, s3, gcs, azure, base64 |
S3 Settings
| Setting | Key | Description |
|---|---|---|
| Bucket | storage.s3_bucket | S3 bucket name |
| Region | storage.s3_region | AWS region (e.g., eu-west-1) |
| Prefix | storage.s3_prefix | Optional path prefix within the bucket |
| Access Key | storage.s3_access_key | AWS access key ID |
| Secret Key | storage.s3_secret_key | AWS secret access key |
Google Cloud Storage Settings
| Setting | Key | Description |
|---|---|---|
| Bucket | storage.gcs_bucket | GCS bucket name |
| Prefix | storage.gcs_prefix | Optional path prefix |
| Credentials JSON | storage.gcs_credentials_json | Service account JSON key |
Azure Blob Settings
| Setting | Key | Description |
|---|---|---|
| Connection String | storage.azure_connection_string | Azure storage connection string |
| Container | storage.azure_container | Blob container name |
| Prefix | storage.azure_prefix | Optional path prefix |
Filesystem Settings
| Setting | Key | Description |
|---|---|---|
| Upload Directory | storage.local_dir | Local directory path for uploads |
Analysis Cover Image Search
Analysis cover images can be uploaded directly by users. Administrators can also enable provider-backed image search so users can choose suggested cover images from the analysis header.
Navigate to Administration → System Settings → Search to configure cover image search.
| Setting | Key | Description |
|---|---|---|
| Cover Image Provider | search.cover_image_provider | unsplash enables provider search; disabled turns off provider search. |
| Unsplash Access Key | search.cover_image_access_key | Unsplash Access Key used for provider search. Stored as a secret setting. |
| Cover Image Search Endpoint | search.cover_image_endpoint | Provider search endpoint. Defaults to the Unsplash photo search endpoint. |
| Cover Image Search Timeout | search.cover_image_timeout_seconds | Request timeout in seconds for cover image provider calls. |
When the provider is set to disabled, or when the access key is blank,
provider search is unavailable but direct cover image upload still works.
Embedded Maps
Documents and Analysis markdown assets can include embedded map attachments. Map rendering requires a MapLibre style URL. Navigate to Administration → System Settings → Maps to configure the style URL used by authenticated users.
| Setting | Key | Description |
|---|---|---|
| Map Style URL | maps.style_url | MapLibre style JSON URL. Accepts http(s) URLs or root-relative paths such as /map-style.json. |
When the style URL is blank, users can still create and edit map attachments,
but rendered map blocks show that map styling is not configured. The frontend
falls back to VITE_MAP_STYLE_URL only when the runtime /maps/config endpoint
does not provide a value.
Place search in the map editor is optional. If VITE_MAP_GEOCODER_URL is not
configured, users can still paste coordinates such as 52.3676, 4.9041 or
lat=52.3676 lng=4.9041.
Configuring via Environment Variables
For deployments where database-level configuration is not desired, set the following environment variables:
# Backend selection
STORAGE_BACKEND=s3
# S3 configuration
STORAGE_S3_BUCKET=qarion-attachments
STORAGE_S3_REGION=eu-west-1
STORAGE_S3_PREFIX=uploads/
STORAGE_S3_ACCESS_KEY=AKIA...
STORAGE_S3_SECRET_KEY=secret...
# Analysis cover image search
COVER_IMAGE_SEARCH_PROVIDER=unsplash
COVER_IMAGE_SEARCH_ACCESS_KEY=...
COVER_IMAGE_SEARCH_ENDPOINT=https://api.unsplash.com/search/photos
COVER_IMAGE_SEARCH_TIMEOUT_SECONDS=5
# Embedded maps
MAP_STYLE_URL=/map-style.json
VITE_MAP_STYLE_URL=/map-style.json
VITE_MAP_GEOCODER_URL=/geocode
Database settings (configured via the admin panel) always take precedence over environment variables.
How It Works
Qarion uses a factory pattern to resolve the active storage handler at runtime. The StorageHandlerFactory checks for database overrides first, then falls back to environment variable defaults. This means you can:
- Set environment variables as defaults for all instances
- Override per-instance via the admin panel
All attachment operations (upload, download, delete) go through the resolved storage handler, making the storage backend transparent to the rest of the application.
Best Practices
Use S3 or GCS for Production
Local filesystem storage is convenient for development but does not scale across multiple application servers. For production deployments, use S3, GCS, or Azure Blob Storage.
Set a Path Prefix
Use a path prefix to organize files within your bucket (e.g., qarion/prod/attachments/). This makes it easier to manage permissions, lifecycle rules, and backups.
Secure Your Credentials
Storage credentials should be treated as secrets. Use environment variables or a secrets manager rather than storing them in plaintext configuration files.
Learn More
- Space Administration — Managing space settings
- Data Catalog — Attaching files to products