easly1989/cloudbank

a webapp version of the one and only homebank app

Go

1

617 commits

updated Sep 28, 2026

See the code

See what people are saying

SourceMessageScoreDate

CloudBank 3.5 - a self-hosted web port of HomeBank: personal finance in one Docker container (r/selfhosted)

I've used HomeBank for years, but it only runs on a desktop, and I wanted my finances on my phone without handing them to a cloud service. So I built **CloudBank**: a clean-room web port of HomeBank that you host yourself. It has been public since June 2026: 1.0 reached parity with HomeBank, and…

0

Sep 28, 2026

README

CloudBank logo

CloudBank

Your money, self-hosted.
A free, web-based personal finance manager — a from-scratch web port of HomeBank.

Try the live demo

Made-up data in a throwaway account, deleted when you stop using it. What the demo is.

CI status Open issues Container image License: AGPL v3

Buy me a coffee Donate via PayPal Donate via Stripe Donate via Liberapay Sponsor on GitHub


CloudBank is a free, self-hosted, web-based personal finance manager — a from-scratch web port of the excellent HomeBank desktop application. It aims for feature parity with HomeBank while being built for the browser and the cloud: a single Docker container you run yourself, with your data living in a SQLite database on a volume you control.

Status: production-ready. 1.0 reached HomeBank parity; the 2.x line added deep personalization and interop, and the 3.x line the post-parity capabilities — automatic bank sync, 2FA, an installable PWA, and opt-in AI. 3.2 redesigned the whole interface, and 3.5 made it fit a phone. See the CHANGELOG.

Try it first: the live demo is one click, no sign-up, with a year of made-up data. It is deleted after two hours without use, so nothing you put in it stays — what the demo is.

Why

HomeBank is a fantastic GTK desktop app, but it is desktop-only. CloudBank brings the same workflow — accounts, a powerful transaction register, scheduled transactions, budgets, rich reports, and multi-format import (including native HomeBank .xhb import and export) — to a web UI you can reach from any device, while keeping the data on your own server.

CloudBank is an independent, clean-room reimplementation. It does not copy or link any HomeBank source code; the original is referenced only for its documented behavior and file formats, and CloudBank tracks parity with current and future HomeBank releases. CloudBank is released under the AGPL-3.0 (HomeBank itself is GPL-2+).

Screenshots

DashboardRegister — bulk actions on a selection
DashboardBulk actions in the register
Bills — last payment & next occurrenceBank-sync review — resolve possible duplicates
BillsBank-sync review
Interactive reportsAppearance — theme, accent, sidebar
ReportsSettings
Customizable, free-form dashboardImport & export — HomeBank .xhb, backup & restore
Customize the dashboardExport

The screenshots use the demo's made-up data. e2e/screenshots.mjs retakes them all.

Features

  • Accounts of every HomeBank type (bank, cash, checking, savings, credit card, liability, asset, investment) with per-account currency, a default payment mode, and the full set of flags, showing both today's balance and a projected future balance.
  • Transactions with 12 payment types, the cleared/reconciled status lifecycle, category splits, free tags, internal transfers (including cross-currency), a right-click context menu, and multi-selection bulk actions — set category / payee / payment mode / status / tags (add or replace) or delete across many rows at once, with shift-click range selection — plus duplicate detection.
  • Register view with running balance, rich filtering (including a show/hide future transactions toggle), columns you can show, hide, resize and reorder, a selection total (net + income/expense split of the currently selected rows), a reconciliation workflow that marks where the reconciled rows sit when a status filter hides them, double-click-to-edit, a privacy switch that blurs names and amounts for a screenshot, and full-text search across memo, payee, category and info.
  • Entering a transaction happens in a sheet beside the ledger, so the rows and the running balance stay in view. You choose which fields it shows and which wait under More details, and Save and keep carries the fields over to the next entry.
  • Scheduled transactions with automatic posting (optionally pre-registering up to 3 months ahead, HomeBank style), a per-week/month/year income & expense summary, the recurring amount shown in the schedules grid, templates (a dedicated management area, and offered when entering a transaction), and assignment rules for auto-categorization.
  • Budgets and reports that answer first: where the money went, what came in and went out, what your accounts hold and will hold with what is scheduled, and what a car costs — for any month, quarter or year, with saved views and CSV/PNG downloads.
  • Savings goals — manual piggy-bank goals with contribute / withdraw, a progress bar and an optional target date (included in wallet backup/restore).
  • Bills — a focused "what's due" view showing one row per bill with its last successful payment and its next occurrence (due / overdue), one-click posting, and a quick "add a bill" form (name, amount, account, day of month → a monthly scheduled outflow).
  • Import: HomeBank .xhb, QIF, OFX/QFX, CSV, ISO 20022 CAMT.053 — with an import assistant. Export: HomeBank .xhb, QIF, CSV.
  • Automatic bank sync — pull new transactions straight from your bank, run through your assignment rules and reconciled against what you already have: a bank row that matches an existing manual or scheduled transaction (amount + nearby date) is merged into it instead of duplicated, imported with the right status (booked → reconciled, pending → cleared) and a sensible default payment mode. Three providers, all bring-your-own-credentials so CloudBank never sees your bank login: SimpleFIN (worldwide; a ~$15/year SimpleFIN Bridge subscription) and Enable Banking (EU/EEA + UK via PSD2 — a free sandbox to test, your own production application for real accounts). Plus Pluggy (Latin America — free for personal use via Meu Pluggy, where you link the banks and CloudBank just reads them). Pluggy is experimental and needs real-world testing — it follows the published API but has not been run against a live Latin American bank by the maintainers, so if you use it, please open an issue with anything that looks wrong, however small. A personal (restricted) Enable Banking production app can only sync accounts you link to it in its panel — the bank-sync guide walks through it.
  • Review — lists imported transactions still needing a category (set it inline) and finds possible duplicates that slipped through, with per-pair merge, edit, delete, or "not a duplicate" (remembered, so it isn't shown again). An account with something to review says so in its register ("3 to review"), and the button opens Review on that account; a linked account also shows when it last synced, with a Sync button. The connections themselves are set up in Settings → Bank sync & AI.
  • Multi-currency with manual and online (ECB / frankfurter.app) exchange rates.
  • Multi-user (managed by the admin from Settings → People), responsive UI, English and Italian.

Make it yours

  • A dashboard that opens with what needs doing — overdue bills, possible duplicates and other things waiting on you sit above the widgets, and one period control (month to all time) sets the span for the whole page.
  • Fully customizable, free-form dashboard — place and resize widgets anywhere on a grid, and add multiple instances of any widget from a palette, each with its own settings. A varied widget library covers the standard cases (base-currency totals, quick-add, income/expense, accounts, spending donut, budget gauge, upcoming) plus building blocks for a custom layout (single account balance, recent transactions, a key-figure big-number, and free-text notes). Pick an account and Add opens the entry sheet; the Upcoming panel splits into Recurring / Future / Reminders with post / skip / edit. In edit mode, Tidy re-packs the widgets with no gaps and Reset restores the default layout. Existing dashboards migrate automatically, and the grid stacks to one column on phones.
  • Themes — light / dark / auto plus an accent-colour picker; your choice persists per user across devices.
  • Collapsible sidebar and a reorderable navigation — rename or add groups, hide pages, and optionally show up to three account balances below it.
  • Smart amount entry (HomeBank style) — type 12.40 or 12,40 and both are read as decimals (toggleable per user).
  • Dates rendered everywhere in your configured format.
  • Page tours — each main page offers a short tour the first time you open it, and the ? in its header replays it. Settings → General can turn the offers off or reset them.

Secure & on every device

  • Two-factor authentication (TOTP) — optional per-user 2FA with authenticator apps (QR enrolment + one-time recovery codes) and a two-step login.
  • Personal API tokens — scoped, revocable bearer tokens for programmatic access.
  • Installable PWA — a web-app manifest, icons and an offline app shell, so CloudBank installs to your phone's home screen or your desktop.
  • Web push notifications — opt-in browser push for schedule / bill due reminders.
  • Encrypted secrets at rest — set CB_SECRET_KEY to encrypt bank credentials, AI keys and other secrets in the database (see Configuration).

Optional AI (bring-your-own-key)

  • Category suggestions — provider-agnostic; suggests a category for a transaction from its description.
  • Natural-language entry — type "coffee 3.50 yesterday" and get a pre-filled transaction to review. Your API key is stored server-side, is write-only, and is never returned to the browser.

Quick start

You need Docker with the Compose plugin. Create a docker-compose.yml (or copy the one in this repo):

services:
  cloudbank:
    image: ghcr.io/easly1989/cloudbank:main # latest stable release (see tags below)
    container_name: cloudbank
    restart: unless-stopped
    ports:
      - "8080:8080"
    environment:
      # Set to "false" only for a plain-HTTP LAN install without TLS in front.
      CB_SECURE_COOKIES: "false"
    volumes:
      - cloudbank-data:/data

volumes:
  cloudbank-data:

Then start it and open the app:

docker compose up -d
# open http://localhost:8080 and complete the first-run admin setup

That is the whole install — one container, no external database. Your data lives in the cloudbank-data volume (a SQLite database under /data). Back it up by copying that volume, or use the in-app wallet backup (Settings → Import & export) and the admin full-database backup.

Running behind HTTPS (recommended for anything beyond a trusted LAN)? See docs/reverse-proxy.md. Coming from the HomeBank desktop app? See docs/migrate-from-homebank.md.

Install as an app (PWA)

CloudBank is an installable Progressive Web App — there is nothing extra to build, generate or host. The web-app manifest, the service worker (offline app shell) and the icons are produced automatically when the frontend is built and are baked into the same container image; the running app just serves them.

To install, open your CloudBank URL in a browser and:

  • Chrome / Edge (desktop) — click the install icon in the address bar (or menu → Install CloudBank…).
  • Android (Chrome) — menu → Add to Home screen / Install app.
  • iOS/iPadOS (Safari) — Share → Add to Home Screen.

It then launches in its own window like a native app, and updates itself to the latest version on the next launch after you deploy a new image.

Requires HTTPS. Browsers only register a service worker and offer installation over a secure context — i.e. HTTPS (plain http://localhost is the only exception, for local testing). Put CloudBank behind TLS (docs/reverse-proxy.md) and keep CB_SECURE_COOKIES at its default; over plain HTTP the browser won't offer "Install" and offline support / push notifications won't work.

Documentation

Configuration

Env varDefaultDescription
CB_ADDR:8080Address the HTTP server listens on.
CB_DATA_DIR/dataDirectory holding the SQLite database and backups.
CB_LOG_LEVELinfodebug, info, warn, or error.
CB_SECURE_COOKIEStrueSet false for plain-HTTP LAN installs (no TLS).
CB_RATE_URL(frankfurter.app)Override the online exchange-rate API root (e.g. a mirror).
CB_VAPID_SUBJECTmailto:cloudbank@localhostContact sent to browser push services with each web-push message. Set it to a mailto: or https: address of yours.
CB_SECRET_KEY(none)If set, encrypts secrets at rest (bank credentials, AI keys, 2FA & push keys). Use a strong, high-entropy value — generate one with openssl rand -base64 48 rather than a hand-picked passphrase. Keep it stable — losing it makes encrypted secrets unrecoverable.
CB_BANK_SYNC_INTERVAL1hHow often the background job checks for connections due to sync. Each connection has its own interval (default daily, configurable per connection), so this only bounds how promptly a due one is picked up. Set 0/off to disable background sync (manual "Sync now" still works).
CB_ENABLEBANKING_BASE_URL(Enable Banking's API)Diagnostics and testing only: points Enable Banking calls at another API root.
CB_BANK_SYNC_DEBUG_PENDING(off)Diagnostics only. When set, each auto-sync makes one extra transaction_status=PDNG call per account and logs the provider's exact response, to investigate why an ASPSP returns no pending transactions. Leave off in normal use — the extra call spends the PSD2 daily budget.
CB_OIDC_ISSUER(none)OIDC/SSO issuer URL (e.g. https://auth.example.com/realms/main). Setting issuer + client id + client secret + redirect URL enables a "Sign in with …" button alongside local login.
CB_OIDC_CLIENT_ID(none)OIDC client id registered with the provider.
CB_OIDC_CLIENT_SECRET(none)OIDC client secret.
CB_OIDC_REDIRECT_URL(none)Absolute callback URL registered with the provider: https://<your-host>/api/v1/auth/oidc/callback.
CB_OIDC_SCOPESopenid profile emailSpace-separated scopes requested (must include openid).
CB_OIDC_NAMESSOLabel shown on the sign-in button ("Sign in with <name>").
CB_OIDC_AUTO_PROVISIONfalseWhen true, first SSO login for an unknown identity creates a local (non-admin) account; otherwise the account must already exist (matched by verified email) or login is refused.

The :demo build reads a few more, all prefixed CB_DEMO_ (idle timeout, user and transaction limits, the per-address rate, proxy hops); they are listed with their defaults in server/internal/config and do nothing in an ordinary build.

Container images and tag convention

Images are published to GHCR: ghcr.io/easly1989/cloudbank.

⚠️ Read this — the tag scheme is intentional and unconventional:

TagMeaning
:mainLatest stable release — use this for a stable self-hosted install.
:latestNightly build from the main branch — bleeding edge, may break.
:vX.Y.ZA specific released version (e.g. :v3.1.5). Also :vX.Y.
:demoThe public demo — throwaway accounts, never for real money.

In other words, :latest is the development nightly, and :main is the stable release. This is the opposite of the usual Docker convention, so pin deliberately.

Availability: :latest is published on every push to main (nightly workflow). :main and the version tags are published by the Release workflow — either by publishing a GitHub Release, or by running that workflow manually from the Actions tab (it has a workflow_dispatch trigger, with an optional version input). If a pull fails with unauthorized, the GHCR package is private: make it public (package → Settings → Change visibility) or docker login ghcr.io with a token that has read:packages.

:demo is a different program, built with --build-arg DEMO=1 and published by the Docker demo workflow: with every published release (not prereleases), from the release's tag, and when the workflow is run by hand. There is no setup and no login: one button makes an account with a year of made-up data. Accounts are deleted after two hours without use and every night at 03:00 UTC. Admin, restore, attachments, AI, push, API tokens, two-factor and OIDC are switched off, and bank sync talks to a pretend bank. Run it without a volume, so a redeploy starts empty; it refuses to start on a data directory that holds real accounts. It is tuned with CB_DEMO_* variables (see server/internal/config); behind a proxy, set CB_DEMO_PROXY_HOPS so the per-address limit sees the visitor and not the proxy. What a visitor sees is described in docs/demo.md.

License

CloudBank is licensed under the GNU Affero General Public License v3.0 — see LICENSE. If you run a modified version as a network service, the AGPL requires you to offer your modified source to its users.

Support the project

CloudBank is an open-source labour of love. If it's useful to you, consider a donation — it genuinely helps and is much appreciated. ♥ The easiest way is Buy Me a Coffee. If you prefer another, the donation page lists them all: PayPal, Stripe, Liberapay or GitHub Sponsors.

Credits

Inspired by and aiming for parity with HomeBank by Maxime Doyen. CloudBank is built and maintained by Carlo Ruggiero (@easly1989) and is not affiliated with or endorsed by the HomeBank project.

easly1989/cloudbank

a webapp version of the one and only homebank app

Go

1

617 commits

updated Sep 28, 2026

See the code

See what people are saying

SourceMessageScoreDate

CloudBank 3.5 - a self-hosted web port of HomeBank: personal finance in one Docker container (r/selfhosted)

I've used HomeBank for years, but it only runs on a desktop, and I wanted my finances on my phone without handing them to a cloud service. So I built **CloudBank**: a clean-room web port of HomeBank that you host yourself. It has been public since June 2026: 1.0 reached parity with HomeBank, and…

0

Sep 28, 2026

README

CloudBank logo

CloudBank

Your money, self-hosted.
A free, web-based personal finance manager — a from-scratch web port of HomeBank.

Try the live demo

Made-up data in a throwaway account, deleted when you stop using it. What the demo is.

CI status Open issues Container image License: AGPL v3

Buy me a coffee Donate via PayPal Donate via Stripe Donate via Liberapay Sponsor on GitHub


CloudBank is a free, self-hosted, web-based personal finance manager — a from-scratch web port of the excellent HomeBank desktop application. It aims for feature parity with HomeBank while being built for the browser and the cloud: a single Docker container you run yourself, with your data living in a SQLite database on a volume you control.

Status: production-ready. 1.0 reached HomeBank parity; the 2.x line added deep personalization and interop, and the 3.x line the post-parity capabilities — automatic bank sync, 2FA, an installable PWA, and opt-in AI. 3.2 redesigned the whole interface, and 3.5 made it fit a phone. See the CHANGELOG.

Try it first: the live demo is one click, no sign-up, with a year of made-up data. It is deleted after two hours without use, so nothing you put in it stays — what the demo is.

Why

HomeBank is a fantastic GTK desktop app, but it is desktop-only. CloudBank brings the same workflow — accounts, a powerful transaction register, scheduled transactions, budgets, rich reports, and multi-format import (including native HomeBank .xhb import and export) — to a web UI you can reach from any device, while keeping the data on your own server.

CloudBank is an independent, clean-room reimplementation. It does not copy or link any HomeBank source code; the original is referenced only for its documented behavior and file formats, and CloudBank tracks parity with current and future HomeBank releases. CloudBank is released under the AGPL-3.0 (HomeBank itself is GPL-2+).

Screenshots

DashboardRegister — bulk actions on a selection
DashboardBulk actions in the register
Bills — last payment & next occurrenceBank-sync review — resolve possible duplicates
BillsBank-sync review
Interactive reportsAppearance — theme, accent, sidebar
ReportsSettings
Customizable, free-form dashboardImport & export — HomeBank .xhb, backup & restore
Customize the dashboardExport

The screenshots use the demo's made-up data. e2e/screenshots.mjs retakes them all.

Features

  • Accounts of every HomeBank type (bank, cash, checking, savings, credit card, liability, asset, investment) with per-account currency, a default payment mode, and the full set of flags, showing both today's balance and a projected future balance.
  • Transactions with 12 payment types, the cleared/reconciled status lifecycle, category splits, free tags, internal transfers (including cross-currency), a right-click context menu, and multi-selection bulk actions — set category / payee / payment mode / status / tags (add or replace) or delete across many rows at once, with shift-click range selection — plus duplicate detection.
  • Register view with running balance, rich filtering (including a show/hide future transactions toggle), columns you can show, hide, resize and reorder, a selection total (net + income/expense split of the currently selected rows), a reconciliation workflow that marks where the reconciled rows sit when a status filter hides them, double-click-to-edit, a privacy switch that blurs names and amounts for a screenshot, and full-text search across memo, payee, category and info.
  • Entering a transaction happens in a sheet beside the ledger, so the rows and the running balance stay in view. You choose which fields it shows and which wait under More details, and Save and keep carries the fields over to the next entry.
  • Scheduled transactions with automatic posting (optionally pre-registering up to 3 months ahead, HomeBank style), a per-week/month/year income & expense summary, the recurring amount shown in the schedules grid, templates (a dedicated management area, and offered when entering a transaction), and assignment rules for auto-categorization.
  • Budgets and reports that answer first: where the money went, what came in and went out, what your accounts hold and will hold with what is scheduled, and what a car costs — for any month, quarter or year, with saved views and CSV/PNG downloads.
  • Savings goals — manual piggy-bank goals with contribute / withdraw, a progress bar and an optional target date (included in wallet backup/restore).
  • Bills — a focused "what's due" view showing one row per bill with its last successful payment and its next occurrence (due / overdue), one-click posting, and a quick "add a bill" form (name, amount, account, day of month → a monthly scheduled outflow).
  • Import: HomeBank .xhb, QIF, OFX/QFX, CSV, ISO 20022 CAMT.053 — with an import assistant. Export: HomeBank .xhb, QIF, CSV.
  • Automatic bank sync — pull new transactions straight from your bank, run through your assignment rules and reconciled against what you already have: a bank row that matches an existing manual or scheduled transaction (amount + nearby date) is merged into it instead of duplicated, imported with the right status (booked → reconciled, pending → cleared) and a sensible default payment mode. Three providers, all bring-your-own-credentials so CloudBank never sees your bank login: SimpleFIN (worldwide; a ~$15/year SimpleFIN Bridge subscription) and Enable Banking (EU/EEA + UK via PSD2 — a free sandbox to test, your own production application for real accounts). Plus Pluggy (Latin America — free for personal use via Meu Pluggy, where you link the banks and CloudBank just reads them). Pluggy is experimental and needs real-world testing — it follows the published API but has not been run against a live Latin American bank by the maintainers, so if you use it, please open an issue with anything that looks wrong, however small. A personal (restricted) Enable Banking production app can only sync accounts you link to it in its panel — the bank-sync guide walks through it.
  • Review — lists imported transactions still needing a category (set it inline) and finds possible duplicates that slipped through, with per-pair merge, edit, delete, or "not a duplicate" (remembered, so it isn't shown again). An account with something to review says so in its register ("3 to review"), and the button opens Review on that account; a linked account also shows when it last synced, with a Sync button. The connections themselves are set up in Settings → Bank sync & AI.
  • Multi-currency with manual and online (ECB / frankfurter.app) exchange rates.
  • Multi-user (managed by the admin from Settings → People), responsive UI, English and Italian.

Make it yours

  • A dashboard that opens with what needs doing — overdue bills, possible duplicates and other things waiting on you sit above the widgets, and one period control (month to all time) sets the span for the whole page.
  • Fully customizable, free-form dashboard — place and resize widgets anywhere on a grid, and add multiple instances of any widget from a palette, each with its own settings. A varied widget library covers the standard cases (base-currency totals, quick-add, income/expense, accounts, spending donut, budget gauge, upcoming) plus building blocks for a custom layout (single account balance, recent transactions, a key-figure big-number, and free-text notes). Pick an account and Add opens the entry sheet; the Upcoming panel splits into Recurring / Future / Reminders with post / skip / edit. In edit mode, Tidy re-packs the widgets with no gaps and Reset restores the default layout. Existing dashboards migrate automatically, and the grid stacks to one column on phones.
  • Themes — light / dark / auto plus an accent-colour picker; your choice persists per user across devices.
  • Collapsible sidebar and a reorderable navigation — rename or add groups, hide pages, and optionally show up to three account balances below it.
  • Smart amount entry (HomeBank style) — type 12.40 or 12,40 and both are read as decimals (toggleable per user).
  • Dates rendered everywhere in your configured format.
  • Page tours — each main page offers a short tour the first time you open it, and the ? in its header replays it. Settings → General can turn the offers off or reset them.

Secure & on every device

  • Two-factor authentication (TOTP) — optional per-user 2FA with authenticator apps (QR enrolment + one-time recovery codes) and a two-step login.
  • Personal API tokens — scoped, revocable bearer tokens for programmatic access.
  • Installable PWA — a web-app manifest, icons and an offline app shell, so CloudBank installs to your phone's home screen or your desktop.
  • Web push notifications — opt-in browser push for schedule / bill due reminders.
  • Encrypted secrets at rest — set CB_SECRET_KEY to encrypt bank credentials, AI keys and other secrets in the database (see Configuration).

Optional AI (bring-your-own-key)

  • Category suggestions — provider-agnostic; suggests a category for a transaction from its description.
  • Natural-language entry — type "coffee 3.50 yesterday" and get a pre-filled transaction to review. Your API key is stored server-side, is write-only, and is never returned to the browser.

Quick start

You need Docker with the Compose plugin. Create a docker-compose.yml (or copy the one in this repo):

services:
  cloudbank:
    image: ghcr.io/easly1989/cloudbank:main # latest stable release (see tags below)
    container_name: cloudbank
    restart: unless-stopped
    ports:
      - "8080:8080"
    environment:
      # Set to "false" only for a plain-HTTP LAN install without TLS in front.
      CB_SECURE_COOKIES: "false"
    volumes:
      - cloudbank-data:/data

volumes:
  cloudbank-data:

Then start it and open the app:

docker compose up -d
# open http://localhost:8080 and complete the first-run admin setup

That is the whole install — one container, no external database. Your data lives in the cloudbank-data volume (a SQLite database under /data). Back it up by copying that volume, or use the in-app wallet backup (Settings → Import & export) and the admin full-database backup.

Running behind HTTPS (recommended for anything beyond a trusted LAN)? See docs/reverse-proxy.md. Coming from the HomeBank desktop app? See docs/migrate-from-homebank.md.

Install as an app (PWA)

CloudBank is an installable Progressive Web App — there is nothing extra to build, generate or host. The web-app manifest, the service worker (offline app shell) and the icons are produced automatically when the frontend is built and are baked into the same container image; the running app just serves them.

To install, open your CloudBank URL in a browser and:

  • Chrome / Edge (desktop) — click the install icon in the address bar (or menu → Install CloudBank…).
  • Android (Chrome) — menu → Add to Home screen / Install app.
  • iOS/iPadOS (Safari) — Share → Add to Home Screen.

It then launches in its own window like a native app, and updates itself to the latest version on the next launch after you deploy a new image.

Requires HTTPS. Browsers only register a service worker and offer installation over a secure context — i.e. HTTPS (plain http://localhost is the only exception, for local testing). Put CloudBank behind TLS (docs/reverse-proxy.md) and keep CB_SECURE_COOKIES at its default; over plain HTTP the browser won't offer "Install" and offline support / push notifications won't work.

Documentation

Configuration

Env varDefaultDescription
CB_ADDR:8080Address the HTTP server listens on.
CB_DATA_DIR/dataDirectory holding the SQLite database and backups.
CB_LOG_LEVELinfodebug, info, warn, or error.
CB_SECURE_COOKIEStrueSet false for plain-HTTP LAN installs (no TLS).
CB_RATE_URL(frankfurter.app)Override the online exchange-rate API root (e.g. a mirror).
CB_VAPID_SUBJECTmailto:cloudbank@localhostContact sent to browser push services with each web-push message. Set it to a mailto: or https: address of yours.
CB_SECRET_KEY(none)If set, encrypts secrets at rest (bank credentials, AI keys, 2FA & push keys). Use a strong, high-entropy value — generate one with openssl rand -base64 48 rather than a hand-picked passphrase. Keep it stable — losing it makes encrypted secrets unrecoverable.
CB_BANK_SYNC_INTERVAL1hHow often the background job checks for connections due to sync. Each connection has its own interval (default daily, configurable per connection), so this only bounds how promptly a due one is picked up. Set 0/off to disable background sync (manual "Sync now" still works).
CB_ENABLEBANKING_BASE_URL(Enable Banking's API)Diagnostics and testing only: points Enable Banking calls at another API root.
CB_BANK_SYNC_DEBUG_PENDING(off)Diagnostics only. When set, each auto-sync makes one extra transaction_status=PDNG call per account and logs the provider's exact response, to investigate why an ASPSP returns no pending transactions. Leave off in normal use — the extra call spends the PSD2 daily budget.
CB_OIDC_ISSUER(none)OIDC/SSO issuer URL (e.g. https://auth.example.com/realms/main). Setting issuer + client id + client secret + redirect URL enables a "Sign in with …" button alongside local login.
CB_OIDC_CLIENT_ID(none)OIDC client id registered with the provider.
CB_OIDC_CLIENT_SECRET(none)OIDC client secret.
CB_OIDC_REDIRECT_URL(none)Absolute callback URL registered with the provider: https://<your-host>/api/v1/auth/oidc/callback.
CB_OIDC_SCOPESopenid profile emailSpace-separated scopes requested (must include openid).
CB_OIDC_NAMESSOLabel shown on the sign-in button ("Sign in with <name>").
CB_OIDC_AUTO_PROVISIONfalseWhen true, first SSO login for an unknown identity creates a local (non-admin) account; otherwise the account must already exist (matched by verified email) or login is refused.

The :demo build reads a few more, all prefixed CB_DEMO_ (idle timeout, user and transaction limits, the per-address rate, proxy hops); they are listed with their defaults in server/internal/config and do nothing in an ordinary build.

Container images and tag convention

Images are published to GHCR: ghcr.io/easly1989/cloudbank.

⚠️ Read this — the tag scheme is intentional and unconventional:

TagMeaning
:mainLatest stable release — use this for a stable self-hosted install.
:latestNightly build from the main branch — bleeding edge, may break.
:vX.Y.ZA specific released version (e.g. :v3.1.5). Also :vX.Y.
:demoThe public demo — throwaway accounts, never for real money.

In other words, :latest is the development nightly, and :main is the stable release. This is the opposite of the usual Docker convention, so pin deliberately.

Availability: :latest is published on every push to main (nightly workflow). :main and the version tags are published by the Release workflow — either by publishing a GitHub Release, or by running that workflow manually from the Actions tab (it has a workflow_dispatch trigger, with an optional version input). If a pull fails with unauthorized, the GHCR package is private: make it public (package → Settings → Change visibility) or docker login ghcr.io with a token that has read:packages.

:demo is a different program, built with --build-arg DEMO=1 and published by the Docker demo workflow: with every published release (not prereleases), from the release's tag, and when the workflow is run by hand. There is no setup and no login: one button makes an account with a year of made-up data. Accounts are deleted after two hours without use and every night at 03:00 UTC. Admin, restore, attachments, AI, push, API tokens, two-factor and OIDC are switched off, and bank sync talks to a pretend bank. Run it without a volume, so a redeploy starts empty; it refuses to start on a data directory that holds real accounts. It is tuned with CB_DEMO_* variables (see server/internal/config); behind a proxy, set CB_DEMO_PROXY_HOPS so the per-address limit sees the visitor and not the proxy. What a visitor sees is described in docs/demo.md.

License

CloudBank is licensed under the GNU Affero General Public License v3.0 — see LICENSE. If you run a modified version as a network service, the AGPL requires you to offer your modified source to its users.

Support the project

CloudBank is an open-source labour of love. If it's useful to you, consider a donation — it genuinely helps and is much appreciated. ♥ The easiest way is Buy Me a Coffee. If you prefer another, the donation page lists them all: PayPal, Stripe, Liberapay or GitHub Sponsors.

Credits

Inspired by and aiming for parity with HomeBank by Maxime Doyen. CloudBank is built and maintained by Carlo Ruggiero (@easly1989) and is not affiliated with or endorsed by the HomeBank project.

Languages

Go

48.6%

TypeScript

46.9%

JavaScript

2.7%

CSS

1.6%