๐ Filesystem Structure
LibreFolio keeps everything it stores in one data directory: the database, uploaded files, broker reports and logs. Its layout is all you need to know for backups and maintenance.
| Installation | Data directory |
|---|---|
| Host (Pipenv) | backend/data/prod/ in the project folder, or the path in LIBREFOLIO_DATA_DIR |
| Docker Compose | LibreFolio-data/ next to docker-compose.yml (/app/backend/data/prod-docker inside the container) |
๐๏ธ Directory Layout
backend/data/
โโโ ๐ prod/ # Production data (default)
โ โโโ ๐๏ธ sqlite/
โ โ โโโ ๐ app.db # Main SQLite database (WAL mode)
โ โโโ ๐ผ๏ธ custom-uploads/ # Files uploaded in the app
โ โโโ ๐ broker_reports/
โ โ โโโ ๐ฅ uploaded/ # Reports waiting to be read
โ โ โโโ โ
parsed/ # Reports read successfully
โ โ โโโ โ failed/ # Reports that could not be read
โ โโโ ๐ logs/ # Application log files
โ โโโ ๐ญ scenario_catalog/ # Optional: your own stress scenarios
โ โโโ ๐ scheduler_state.json # Last run of the scheduled syncs
โ
โโโ ๐งช test/ # Test data (completely isolated)
โโโ ๐๏ธ sqlite/app.db
โโโ ๐ผ๏ธ custom-uploads/
โโโ ๐ broker_reports/
โโโ ๐ logs/
๐ What's in Each Directory
๐๏ธ sqlite/
- ๐
app.dbholds all the structured data: users, brokers, transactions, assets, prices, FX rates and settings. - ๐
app.db-walandapp.db-shmare SQLite's working files (WAL mode), expected while the server runs: never copyapp.dbalone while the server is up. - ๐
app.db.post-migration.lockis an empty file used at startup: leave it in place. A file namedapp.db.pre-<fix>-<UTC time>.bakis a copy kept after a failed post-migration fix: delete it once you no longer need it.
๐ผ๏ธ custom-uploads/
Files uploaded in the app, such as those of the Files page, and the default avatars. Each file has a random name and a .json file next to it that describes it: keep the pairs together.
๐ broker_reports/
The broker reports uploaded for import, in one broker_<id>/ folder per broker:
- ๐ฅ
uploaded/โ waiting to be read - โ
parsed/โ read successfully - โ
failed/โ could not be read, kept so you can check why
A report moves from uploaded/ to parsed/ or failed/, so its original file is always in one of the three.
๐ logs/
- ๐
librefolio.logholds one JSON record per line; the server also prints the log to its console. - ๐๏ธ Every Monday (UTC) the file is archived and compressed (
.gz); the last 52 archives, one year, are kept. - ๐๏ธ
LOG_LEVELin.envsets how much is written (defaultINFO).
๐ถ Log levels โ what each one records
Each level also records all the more serious ones.
| 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 (default) |
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 |
- 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
๐ For developers: Data directory on disk โ every file, its format and the code that writes it, scenario_catalog/ included.
๐ Environment Variables
LIBREFOLIO_DATA_DIRmoves the production data directory, andLIBREFOLIO_TEST_DATA_DIRthe test one. A relative path starts from the project folder.- With Docker Compose the path inside the container is fixed: to keep the data elsewhere on the host, change the left side of the
./LibreFolio-data:/app/backend/data/prod-dockervolume indocker-compose.yml.
The other variables, and the .env file, are described in Configuration.
๐พ 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
With Docker Compose, the data directory is the LibreFolio-data/ folder on the host, so no Docker copy command is needed. Stop the container for a consistent copy:
docker compose stop librefolio
cp -r ./LibreFolio-data/ /path/to/backup/librefolio-$(date +%Y%m%d)/
docker compose start librefolio
๐ Back up the database without stopping the server
SQLite's online backup makes a consistent copy while the server runs. It needs the sqlite3 tool:
With Docker, the database is ./LibreFolio-data/sqlite/app.db. This copies the database only: copy the folders below as usual.
โ 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/โ The original broker reports, in case you need to import them againscenario_catalog/โ Your own stress scenarios, if you added any
If storage is limited, sqlite/app.db alone keeps all the structured data: files and reports can be uploaded again if you still have them.