Install with Docker Compose
Docker Compose is the simplest way to run a self-hosted instance. It serves the React web UI and FastAPI backend from one container and stores app data in a persistent Docker volume.
Requirements
Install:
- Git
- Docker Desktop or Docker Engine with Docker Compose
Clone the repository
Run:
git clone git@github.com:edgar-costa/finances-app.git
cd finances-appCreate local configuration files:
cp .env.example .env
cp examples/invoicer.example.toml invoicer.tomlinvoicer.toml is only needed for Notion import/export. You can leave it as an example file if you are not using Notion yet.
Choose the first-owner setup path
When the database is empty, the app needs one owner and one first workspace. Choose one setup path before the first run.
Option 1: Create the first owner in the browser
Edit .env and set a setup token:
INVOICER_SETUP_TOKEN=replace-with-a-long-random-tokenStart the app:
docker compose up -d --buildOpen http://127.0.0.1:8000. The setup page asks for:
- Workspace name
- Owner name
- Owner email
- Owner password
- Setup token, when setup is not coming from localhost
Use this option when you want the owner to choose their own password in the browser.
Option 2: Bootstrap the first owner from .env
Edit .env and set all four bootstrap values:
INVOICER_BOOTSTRAP_WORKSPACE_NAME=Freelancer Hub
INVOICER_BOOTSTRAP_OWNER_NAME=Owner Name
INVOICER_BOOTSTRAP_OWNER_EMAIL=owner@example.com
INVOICER_BOOTSTRAP_OWNER_PASSWORD=replace-with-a-long-passwordStart the app:
docker compose up -d --buildIf the database has no users, the server creates the first workspace, owner user, and owner membership on startup. If users already exist, these variables are ignored and won't reset the owner.
Use this option for unattended VPS provisioning.
Log in
Open:
http://127.0.0.1:8000Log in with the owner email and password you created. After login, use Settings → Workspaces and users to create more users, add isolated workspaces, or switch workspaces.
Check that the server is healthy
Run:
curl -fsS http://127.0.0.1:8000/api/healthExpected response:
{"status":"ok"}Check whether first-run setup is still required:
curl -fsS http://127.0.0.1:8000/api/setup/statusAfter the first owner exists, required should be false.