Operate a self-hosted instance
This page covers the routine tasks for a running Docker instance.
Know where data lives
With the default Compose file:
- SQLite database:
/data/invoicer.sqlite3 - Generated files:
/data/files - Managed backups:
/data/backups - Docker volume:
invoicer-data
Do not delete the Docker volume unless you intentionally want to remove the app data.
Generated PDFs use workspace-scoped relative storage keys under /data/files. At startup, legacy generated-file records are migrated only when their old file already resolves inside the configured storage root. An absolute or escaped legacy path is never copied or served; its metadata remains visible as a missing file so an operator can reconcile it deliberately.
Start, stop, and update
Start or rebuild:
docker compose up -d --buildStop:
docker compose downCheck logs:
docker compose logs -f invoicerCheck health:
curl -fsS http://127.0.0.1:8000/api/healthBack up before risky changes
Use the Settings backup page to create and review managed backups.
Managed backup ZIP files contain:
manifest.jsonwith metadata and row counts.database.jsonwith a portable finance backup envelope.files/...for generated files that still exist in storage.
Store copies of backup ZIP files outside the Docker volume before upgrades, server moves, or destructive testing.
Secure public deployments
Before exposing the app outside localhost:
- Set
INVOICER_SETUP_TOKENuntil setup is complete. - Keep the Compose port bound to
127.0.0.1and proxy it through HTTPS. - Set
INVOICER_COOKIE_SECURE=1. - Set
INVOICER_ALLOWED_HOSTSto the exact public hostname. - Set
INVOICER_ALLOWED_ORIGINSto the exact public HTTPS origin if the reverse proxy does not preserve that origin for backend requests. - Leave
INVOICER_ALLOW_UNAUTHENTICATED_LOCAL=0. - Keep
.envandinvoicer.tomlout of Git. - Use long unique passwords.
- Put the app behind a reverse proxy that you control.
- Create a backup before upgrades.
The app is designed for self-hosted trusted operators, not open public signup.
Add users and workspaces
After login, open Settings → Workspaces and users.
Owners and admins can create users in the active workspace. Owners can manage all roles in that workspace. Admins can manage admins and members, but not owners.
For a new email, copy the one-time activation link and deliver it to the user through a trusted channel. The user chooses their own global password. Existing users keep their password when they are added to another workspace. Workspace administrators cannot reset a global password.
For operator recovery from the host, stop concurrent administrative work and run:
uv run invoicer app reset-user-password user@example.com --db /data/invoicer.sqlite3Use the host-visible SQLite path for non-container runs. In Docker, execute the command inside a disposable invocation of the same image with the data volume mounted; never copy the database into an untrusted environment.
Create a new workspace when you need isolated finances for a different business or project. A workspace has its own clients, work items, invoices, expenses, payments, settings, backups, and Notion connector settings.