Nova is a web-based financial management application for small groups, clubs, or flatshares. It provides features to track income, expenses, donations, and individual members' contributions. The app consists of a frontend written in HTML/JS, a Node.js backend for handling file uploads, email notifications, and configuration, and an embedded PocketBase instance for authentication and data storage.
- Admin/User Views: Distinct interfaces tailored for administrators and standard users.
- Request Management (with approvals): Users can submit requests (payments, status changes, expenses) which admins can review and approve or reject.
- Person Management: Track and manage members' statuses (e.g., Vollverdiener, Geringverdiener, etc.).
- Payments & Standing Orders: Record recurring and one-time payments efficiently.
- Donations: Separate tracking for general donations.
- Expenses: Log expenses with optional receipt uploads.
Nova is distributed as an all-in-one Docker image. It includes the frontend, the backend server, and a bundled PocketBase process.
To run Nova, pull the latest image and start a container. Nova now keeps general app data and the PocketBase database in separate paths by default:
/app/datafor configuration, uploads, and the custom logo/app/dbfor the PocketBase database files
That makes it easy to place /app/db on faster cache/SSD storage while keeping the rest on larger HDD-backed storage.
docker pull ghcr.io/ricouhd/nova:latest
docker run -d \
-p 3000:3000 \
-v /path/to/your/storage:/app/data \
-v /path/to/your/cache:/app/db \
--name nova-app \
--restart unless-stopped \
ghcr.io/ricouhd/nova:latestReplace /path/to/your/storage and /path/to/your/cache with directories on your host machine to ensure your data survives container restarts.
Unraid / Permission Note: Nova starts as root only long enough to prepare bind-mounted
/app/data,/app/db, and/app/htmldirectories for the bundlednodeuser (UID 1000), then drops back tonodebefore starting the app. If your storage backend blocks ownership changes, make sure every mapped host directory is writable by UID 1000, e.g.chown -R 1000:1000 /path/to/your/storage /path/to/your/cache /path/to/your/frontend.
The frontend files are bundled directly in /app/html inside the container. If you want to customize the frontend (e.g. replace index.html or static assets), you can optionally map this path as well:
docker run -d \
-p 3000:3000 \
-v /path/to/your/storage:/app/data \
-v /path/to/your/cache:/app/db \
-v /path/to/your/frontend:/app/html \
--name nova-app \
--restart unless-stopped \
ghcr.io/ricouhd/nova:latestWhen mapping /app/html, Nova automatically syncs the bundled frontend files from the image into that directory on every start so that image upgrades take effect without removing the volume. Files that were removed in a newer image version are cleaned up automatically.
Custom logo storage: The admin SVG upload is persisted in
/app/data/church-logo.svg, not in/app/html/assets/church-logo.svg. The app serves/assets/church-logo.svgdynamically so the uploaded logo keeps working even when/app/htmlis mapped.
Reverse proxy note: Nova trusts local/private reverse proxies by default so the bundled rate limiting works cleanly behind Docker reverse proxies. If your proxy setup is different, you can override Express' proxy handling with the
TRUST_PROXYenvironment variable.
Nova is designed to be fully updateable through Docker image upgrades. When you pull a new image and recreate the container, all changes — backend code, frontend files, and the embedded PocketBase binary — are applied automatically. Your data in /app/data and /app/db is preserved across updates.
docker pull ghcr.io/ricouhd/nova:latest
docker stop nova-app
docker rm nova-app
docker run -d \
-p 3000:3000 \
-v /path/to/your/storage:/app/data \
-v /path/to/your/cache:/app/db \
--name nova-app \
--restart unless-stopped \
ghcr.io/ricouhd/nova:latestWhat happens during an update:
- The new backend code and PocketBase binary are part of the image and take effect immediately.
- The entrypoint script syncs the bundled frontend files into the
/app/htmlvolume, overwriting outdated files and removing stale ones that no longer exist in the new image. - The service worker in the browser uses a network-first strategy, so users see the updated frontend as soon as the new container is running.
- All user data (configuration, uploads, database) is stored on the mounted volumes and remains untouched.
Setup Wizard
When you first access the application at http://localhost:3000 (or your mapped port), you will be greeted by the built-in Setup Wizard. You only need to provide:
- App Name: The name of your instance (e.g., Nova).
- Optional SVG Logo: You can upload a custom logo directly during the wizard.
- SMTP Details (Optional): Credentials for a mail server to send automated status and request notifications.
PocketBase is provisioned automatically inside the container. Nova stores its runtime configuration in /app/data/config.json, the uploaded logo in /app/data/church-logo.svg, and the PocketBase database in /app/db by default. If needed, you can override the database path with DB_DIR (or the more explicit POCKETBASE_DIR).
The first user who logs in after setup is automatically promoted to:
admin: true(regular admin/supervisor rights)superAdmin: true(advanced admin/admin rights)
The super-admin can then:
- promote/demote other users to regular admins (supervisors),
- edit recorded payments afterwards,
- update
assets/church-logo.svg(church icon), - update the app name and SMTP configuration directly from the advanced settings UI.
PocketBase access model
Nova now provisions PocketBase automatically and configures the collections, indexes, and default records on startup. The effective permission model mirrors the previous Firebase rules:
- Admins can read and write all people, requests, donations, expenses, settings, and user records.
- Regular users can authenticate with PocketBase, read/update their own profile, read shared settings, read the public invite code, view only their linked person/request records, and submit their own requests.
- The first logged-in user is promoted to
superAdminand can manage admin roles plus the advanced system settings.
This project is licensed under the newest GNU General Public License (GPLv3). See the LICENSE file for more details.