Why host your finances on your own server
Entrusting financial data to a third-party service means accepting their storage conditions, data-sharing practices, and commercial longevity. Several popular services raised prices by 30 to 60 percent between 2023 and 2025, or simply shut down. Self-hosting addresses a legitimate concern: "my financial data is too sensitive for a server I manage myself." In practice, a properly configured VPS provides encryption in transit (TLS), PostgreSQL volume encryption at the disk level, automated backups, and access restricted to your IP address or private network. That is a smaller attack surface than a SaaS that aggregates data from tens of thousands of users.
What Maybe offers
Maybe combines budget management, investment tracking, and net worth calculation in a single self-hostable interface.
- Net worth dashboard (assets, liabilities, evolution over time)
- Transaction tracking with automatic categorization and customizable rules
- Bank account connections via Plaid (US and Canada) or manual entry
- Investment and stock portfolio tracking with real-time prices via Synth Finance
- Budgets and savings goals by category
- Exportable monthly and annual reports
- Optional AI assistant (requires an OpenAI key) for spending analysis
- Multi-account interface: partner, household members, or clients
System requirements
Maybe is a Ruby on Rails application running four Docker services: the web server, a Sidekiq worker for async tasks, PostgreSQL 16, and Redis. For personal use or a small team, a VPS with 2 vCPU and 2 GB RAM is sufficient. For professional use with multiple users and active bank syncing, 4 GB RAM is recommended. Port 3000 must be reachable (or proxied from port 443 via a reverse proxy). Allocate 5 GB of storage for application data and the database, plus space for backups.
Installing Maybe on a VPS with Docker Compose
Installation relies on Docker Compose and a .env file. The steps below start from a fresh Debian 12 VPS.
Install Docker Engine
On Debian/Ubuntu:
curl -fsSL https://get.docker.com | sh. Verify the installation withdocker run hello-world. Docker Compose v2 is included from Docker Engine 23 onward.Create the working directory
Run
mkdir -p /opt/maybe && cd /opt/maybe. This directory will hold yourcompose.ymland.envfiles.Download the official Compose file
Retrieve the example provided by the project:
curl -o compose.yml https://raw.githubusercontent.com/maybe-finance/maybe/main/compose.example.yml. This file defines the four services (web, worker, db, redis) and the named volumes.Create the .env file
Create
/opt/maybe/.envwith the following content:SECRET_KEY_BASE=$(openssl rand -hex 64),POSTGRES_PASSWORD=a_strong_password,SELF_HOSTED=true,APP_DOMAIN=finance.your-domain.com. Generate a strong secret key withopenssl rand -hex 64.Start the services
From
/opt/maybe, rundocker compose up -d. Docker pulls theghcr.io/maybe-finance/maybe:stableimages along with PostgreSQL 16 and Redis, then starts the containers. Database initialization takes one to two minutes.Configure a reverse proxy
Place Nginx or Caddy in front of port 3000 to serve Maybe over HTTPS. With Caddy: add
finance.your-domain.com { reverse_proxy localhost:3000 }to yourCaddyfile. Caddy handles the Let's Encrypt certificate automatically.Create the first account
Visit
https://finance.your-domain.com. Maybe displays a sign-up form on the first launch. InSELF_HOSTED=truemode, the first account created becomes the administrator. Disable public registrations in settings if the instance is personal.
Connecting bank accounts
Maybe supports two methods for linking accounts. Automatic connection via Plaid covers US and Canadian banks: add your Plaid API credentials (PLAID_CLIENT_ID and PLAID_SECRET) to .env, then link accounts from the interface. For European or other banks, manual transaction entry remains the main method. Maybe accepts CSV file imports in a standard format, allowing migration from a spreadsheet or a bank export. Investment tracking relies on the Synth Finance API for stock prices: add a SYNTH_API_KEY to enable automatic portfolio valuation.
PostgreSQL backup and encryption
The PostgreSQL database is stored in the maybe_postgres-data Docker volume. To back up regularly: create a script that runs docker exec maybe-db-1 pg_dump -U maybe_user maybe_production | gzip > /backups/maybe-$(date +%Y%m%d).sql.gz, then schedule it with a systemd timer or cron. For a complete 3-2-1 strategy, send these encrypted dumps to S3-compatible object storage using Restic or rclone. Maybe also supports storing application files on Amazon S3 or Cloudflare R2 via the ACTIVE_STORAGE_SERVICE, S3_ACCESS_KEY_ID, and related variables. Encryption of sensitive data in the database (API keys, tokens) relies on ACTIVE_RECORD_ENCRYPTION_* keys — if you do not set them explicitly, they are derived from your SECRET_KEY_BASE.
Restrict access to your Maybe instance by placing it behind a VPN (Tailscale, Headscale) or by filtering access by IP in Nginx with allow 203.0.113.10; deny all;. A personal financial instance does not need to be publicly accessible: private access dramatically reduces the attack surface without compromising usability.
Troubleshooting: common errors
The most common errors after installing Maybe on a VPS, and how to fix them.
web exited with code 1on startup: the database is not ready yet. Check withdocker compose logs dbthat PostgreSQL has started, then rundocker compose restart web worker.- Blank page or 500 error after sign-up: verify that
SECRET_KEY_BASEis set and non-empty in.env. A missing key prevents Rails from decrypting the session. PG::ConnectionBadin web logs: theDB_HOSTvariable must bedb(the Docker service name), notlocalhost. Check your.env.- Async tasks (bank sync, reports) do not run: the
workerservice is not running. Check withdocker compose psthat all four services are inrunningstate. - Regression after update: after
docker compose pull, rundocker compose up --no-deps -d web workerrather thandocker compose up -dto avoid unnecessarily recreating database containers.
Comparison: self-hosted Maybe, YNAB, and Monarch Money
This table compares self-hosted Maybe with the main personal finance SaaS applications.
Scroll the table
| Criteria | Maybe (self-hosted) | YNAB | Monarch Money |
|---|---|---|---|
| Annual cost | VPS cost (~$5-10/month) | $109/year | $99.99/year |
| Data control | Full — data on your server | None — data at YNAB | None — data at Monarch |
| Bank connection | Plaid (US/CA) or manual | Plaid (US/CA/EU partial) | Plaid (US/CA) |
| Investment tracking | Yes (via Synth Finance) | Not native | Yes |
| Net worth dashboard | Yes | No | Yes |
| AI assistant | Optional (OpenAI key required) | No | Yes (included) |
| Maintenance required | Yes — manual updates | No | No |
| License | AGPLv3 (open source) | Proprietary | Proprietary |
Further reading
The article on hosting PostgreSQL on a VPS covers fine-tuning the database engine for production workloads. The 3-2-1 backup strategy with Restic and S3 explains setting up encrypted, versioned retention. To secure access to your Maybe instance without a full VPN, the Nextcloud article provides an example Nginx configuration with basic authentication.