Skip to content

πŸ“‚ 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-wal and .db-shm files 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).


🌍 Environment Variables

Variable Default Description
LIBREFOLIO_DATA_DIR ./backend/data/prod Override the production data directory path
LIBREFOLIO_TEST_MODE 0 Set to 1 to use backend/data/test/ instead of prod/
PORT 8000 Production server port
TEST_PORT 8001 Test server port (used when LIBREFOLIO_TEST_MODE=1)

πŸ’Ύ 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 running via Docker, the data directory is typically mounted as a volume:

# Find the volume
docker volume inspect librefolio_data

# Copy data out
docker cp librefolio-container:/app/backend/data/prod/ ./backup/

βœ… 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/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.


πŸ”§ Maintenance from Host Terminal

🐳 Docker exec

# Access the container shell
docker exec -it librefolio-container /bin/bash

# Run dev.py commands inside the container
./dev.py user list
./dev.py user reset admin newpassword
./dev.py db upgrade

πŸ’» Direct access (non-Docker)

# From the project root
./dev.py user list              # List all users
./dev.py user reset <user> <pw> # Reset a user's password
./dev.py user promote <user>    # Grant superuser privileges
./dev.py user demote <user>     # Remove superuser privileges
./dev.py db upgrade             # Apply pending migrations
./dev.py db create-clean        # Reset database (WARNING: deletes all data)

For a full list of CLI commands, see CLI Tools.