Skip to content

๐Ÿ“‚ 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.db holds all the structured data: users, brokers, transactions, assets, prices, FX rates and settings.
  • ๐Ÿ“Ž app.db-wal and app.db-shm are SQLite's working files (WAL mode), expected while the server runs: never copy app.db alone while the server is up.
  • ๐Ÿ”’ app.db.post-migration.lock is an empty file used at startup: leave it in place. A file named app.db.pre-<fix>-<UTC time>.bak is 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.log holds 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_LEVEL in .env sets how much is written (default INFO).
๐Ÿ“ถ 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_DIR moves the production data directory, and LIBREFOLIO_TEST_DATA_DIR the 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-docker volume in docker-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:

sqlite3 backend/data/prod/sqlite/app.db ".backup '/path/to/backup/app.db'"

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:

  1. sqlite/app.db โ€” All your data (users, transactions, settings, FX rates)
  2. custom-uploads/ โ€” User-uploaded files (avatars, documents)
  3. broker_reports/ โ€” The original broker reports, in case you need to import them again
  4. scenario_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.