📂 Filesystem Structure
LibreFolio stores all persistent data in a structured directory under backend/data/. Understanding this structure is important for backup, debugging, and maintenance.
🗂️ Directory Layout
backend/data/
├── 📂 prod/ # Production data (default)
│ ├── 🗃️ sqlite/
│ │ └── 📄 app.db # Main SQLite database (WAL mode)
│ ├── 🖼️ custom-uploads/ # User-uploaded files
│ │ ├── 📄 {uuid}.{ext} # Binary file (image, document, etc.)
│ │ └── 📋 {uuid}.json # Metadata sidecar (uploader, date, MIME type)
│ ├── 📊 broker_reports/
│ │ ├── 📥 uploaded/ # Reports waiting to be parsed
│ │ ├── ✅ parsed/ # Successfully parsed reports
│ │ └── ❌ failed/ # Reports that failed parsing
│ └── 📝 logs/ # Application log files
│
└── 🧪 test/ # Test data (completely isolated)
├── 🗃️ sqlite/app.db
├── 🖼️ custom-uploads/
├── 📊 broker_reports/
└── 📝 logs/
📖 What's in Each Directory
🗃️ sqlite/app.db
The main SQLite database. Contains all application data: users, brokers, transactions, FX rates, settings, etc.
- 📝 Uses WAL (Write-Ahead Logging) journal mode for better concurrent access
- 📎 The
.db-waland.db-shmfiles are temporary WAL files — they're expected and managed by SQLite
Developer deep-dive: Database Schema
🖼️ custom-uploads/
Files uploaded by users through the Files page. Each upload creates two files:
- 📄
{uuid}.{ext}— The actual binary file (e.g.,a1b2c3d4.png) - 📋
{uuid}.json— Metadata including: original filename, MIME type, file size, upload date, uploader user ID
Developer deep-dive: File Upload Component
📊 broker_reports/
Broker report files for the BRIM (Broker Report Import Manager) system:
- 📥
uploaded/— Raw files as uploaded by users (CSV, Excel) - ✅
parsed/— Files that have been successfully processed (transactions extracted) - ❌
failed/— Files that failed parsing (kept for debugging — check logs for details)
Developer deep-dive: BRIM Architecture
📝 logs/
Application logs in structured JSON format (via structlog). Log files rotate weekly and are kept for 1 year (compressed with gzip).
The verbosity is controlled by the LOG_LEVEL environment variable.
What each level captures — each row shows which log levels are visible:
| LOG_LEVEL | 🔬 TRACE (5) | 🐛 DEBUG (10) | ℹ️ INFO (20) | ⚠️ WARNING (30) | ❌ ERROR (40) | 💀 CRITICAL (50) |
|---|---|---|---|---|---|---|
🔬TRACE |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
🐛DEBUG |
❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
ℹ️ INFO (default) |
❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
⚠️ WARNING |
❌ | ❌ | ❌ | ✅ | ✅ | ✅ |
❌ERROR |
❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
💀CRITICAL |
❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
What each level means:
| Level | What it captures |
|---|---|
🔬TRACE |
High-frequency granular data: individual FX rates parsed, per-asset price points |
🐛DEBUG |
Operational internals: which provider was used, intermediate results, algorithmic decisions |
ℹ️INFO |
Significant user operations: sync completed, import, login, resource created/deleted |
⚠️WARNING |
Recoverable anomalies: fallback activated, missing optional data, degraded mode |
❌ERROR |
Handled errors: failed operations, data corruption, provider unreachable |
💀CRITICAL |
Fatal errors that stop the process |
Recommended settings
- Production:
LOG_LEVEL=INFO— clean signal, no noise - Troubleshooting:
LOG_LEVEL=DEBUG— see what the system is deciding - Deep FX/price debugging:
LOG_LEVEL=TRACE— see every individual data point
🌍 Environment Variables
The storage paths and runtime behaviors of the filesystem are controlled by environment variables (such as LIBREFOLIO_DATA_DIR and LIBREFOLIO_TEST_MODE). For a complete list of all supported environment variables and how to configure them using the .env file, see the Configuration page.
💾 Backup
📦 Simple Backup
The easiest way to back up LibreFolio is to copy the entire data directory:
# Stop the server first (to ensure database consistency)
cp -r backend/data/prod/ /path/to/backup/librefolio-$(date +%Y%m%d)/
🐳 Docker Backup
If you are running LibreFolio via Docker Compose (the standard deployment method), the production data directory is bind-mounted directly to the ./LibreFolio-data directory on your host machine (and mapped to /app/backend/data/prod-docker inside the container).
Therefore, you do not need any special Docker copy commands; simply backing up the ./LibreFolio-data folder on your host machine is sufficient to secure your data.
✅ What to Back Up
At minimum, back up:
sqlite/app.db— All your data (users, transactions, settings, FX rates)custom-uploads/— User-uploaded files (avatars, documents)broker_reports/uploaded/— Original broker reports (in case you need to re-parse)
Database-only backup
If storage is limited, backing up just sqlite/app.db preserves all structured data. Files can always be re-uploaded.