Expensave
Self-hosted expense tracker for personal and family budget management
Alternative to: ynab, mint, monarch money, dollarbird

Expensave is a free, open-source, self-hosted expense tracker for personal and family budget management. It tracks spending on a shared calendar, supports multiple users and unlimited expense calendars, and can import bank statements in OFX/QFX, ISO 20022 XML, Revolut, and Dollarbird formats. Recurring expenses and spending reports help households monitor their finances, with a responsive UI and an installable mobile PWA.
Expensave Docker Compose example
Self-host Expensave on your own server, homelab, or VPS starting from this Docker Compose example.
It runs Expensave in Docker containers using the official algirdasc/expensave:latest, mariadb:11 images, with persistent volumes and automatic restarts preconfigured.
Review the environment variables and adjust them to your setup, save the file as compose.yml (or docker-compose.yml), and start the stack with docker compose up -d.
services:
application:
image: algirdasc/expensave:latest
restart: unless-stopped
environment:
# UI language as an ISO 639-1 code (e.g. en, lt, de, fr).
LOCALE: "en"
# Set to "yes" to disable public self-registration; new users must then be created from within the app.
REGISTRATION_DISABLED: "no"
# Container timezone as an IANA name (e.g. UTC, Europe/London).
TZ: "UTC"
depends_on:
database:
condition: service_healthy
database:
image: mariadb:11
restart: unless-stopped
environment:
# Generate a random MariaDB root password on first init; the app uses the dedicated user below, not root.
MARIADB_RANDOM_ROOT_PASSWORD: "yes"
# Database name — must match the application's built-in DATABASE_NAME default.
MARIADB_DATABASE: "expensave"
# Database user — must match the application's built-in DATABASE_USER default.
MARIADB_USER: "expensave"
# Database password — reachable only inside the compose network; must match the app's built-in DATABASE_PASS default.
MARIADB_PASSWORD: "expensave"
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mariadb-admin", "ping"]
retries: 5
timeout: 5s
volumes:
db_data: Prefer a managed setup? WinterFlow installs, configures, and updates Expensave for you using this same Docker Compose configuration.