A no-BS, zero-effort budgeting software as a self-hostable service with tons of insights.
See the codeBudgeting that actually fits into your life.
Check it out now!
| URL | comaney.app/login |
demo@comaney.app | |
| Password | 91448 |
The demo account is a public sandbox. Do not enter personal, sensitive, or illegal data. It is reset automatically once a week.

Custom themes, configurable in your account settings. Download exemplary backdrop files.
Full documentation is available at https://comaney.app/docs.

Comaney is a personal budgeting app available as a hosted service at comaney.app or self-hosted on your own server.
Log expenses with a title, amount, date, and category. Tag them however you like and search or filter across your whole history in seconds. Export everything to CSV at any time.
Set up scheduled expenses (subscriptions, rent, insurance) once and Comaney generates them automatically. Get notified when a payment is coming up or overdue.
The modular dashboard lets you build your own overview from scratch: spend-by-category charts, running totals, custom lists, and more. Each card is fully configurable and can link through to the matching filtered expense list.
AI express entry lets you jot down a quick note like "strawberries for date night with Ann, 4 EUR" and Comaney turns it into a properly categorised and tagged expense. Snap a photo of a receipt and it splits it into individual line items automatically.

How much did the bathroom renovation cost in the end? Put every expense that belongs to it (tiles, plumber, paint, the rented tile cutter) into a project and Comaney adds it all up for you, no matter how many months it took. Projects don't need anyone else: they're a place to collect everything that belongs to one undertaking, alongside your normal monthly budget. See Projects below.

Comaney runs an MCP (Model Context Protocol) server, so AI assistants can read and write your account directly. Each assistant gets its own agent key. See User manual: AI Assistants (MCP).
A REST API lets scripts and other apps read and write your data, for example to import bank transactions. See User manual: REST API Access.
A project is an expense container tied to a specific goal, event, or ongoing situation. Projects work fine on their own as a way to keep expenses organized, and they scale up to full multi-person shared budgets when you need them.
Examples:
A solo project is just you. It is a clean way to bucket all expenses related to a specific goal without mixing them into your main expense list. The debt diagram and settlement tools are hidden because there is no one else to settle with.
Add other people to a project and it becomes a shared budget. A project can include any mix of:
When creating an expense, set the assignment to Project and pick the project. For multi-member projects you then set:
If a connected user is set as the one who paid, the expense is created in their account and they must approve it before it counts toward the balance.
The project page shows two debt views based on all approved shared expenses:
The Your balance section gives you a plain-language summary of who you owe and who owes you.
Use the Pay someone back form on the project page to record a payment. The amount is pre-filled with what you owe, but you can enter any value.
The project admin can also settle the entire project at once: Comaney calculates the simplified debt breakdown and creates one settlement per debtor-creditor pair in a single action, then notifies everyone by email.
Every project has one admin. Only the admin can invite and remove members, trigger a group-wide settlement, archive or delete the project, and transfer admin rights.
Archiving freezes the project. No new expenses or settlements can be created, but in-flight settlements can still be confirmed. Archived projects remain accessible for review but no longer appear in expense form dropdowns.
Removing a real user keeps their name as a read-only offline entry so past expenses still reference them correctly.
Removing an offline member moves their shared expense history to Achim Archive rather than deleting it, keeping all balances intact.

If you want to split costs with a single person, you do not need a project. The Contacts feature gives you the same split-pay mechanics directly between two people.
Click Contacts in the navigation.
You can link an offline contact to their real Comaney account later so the full history carries over.
Create a new expense and set the assignment to Contact. Choose the contact, set who paid and the split, then save.
From the Contact Expenses page, use the Pay someone back form. For a connected user, they must confirm receipt before the balance clears. For an offline contact, it is confirmed automatically.
If a connected contact logs an expense with you as the one who paid upfront, it appears in the "Did you pay for this?" section on Contact Expenses. Approve it to move it into your regular expense list; reject it to delete it entirely.

When you remove an offline member from a project or your contacts, Comaney does not delete their shared expense history. It moves that history to a placeholder called Achim Archive so all balances stay correct.
Multiple removed offline members all fold into the same archive. You can permanently delete the archived expenses at any time; Comaney shows you exactly what will change before asking you to confirm. This cannot be undone.
Comaney runs as a Docker container backed by MariaDB.
services:
web:
image: leonetienne/comaney:latest
restart: unless-stopped
ports:
- "80:8000"
depends_on:
- mariadb
environment:
# Generate: python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
DJANGO_SECRET_KEY: "change-me"
DB_HOST: mariadb
DB_PORT: 3306
DB_NAME: comaney
DB_USER: comaney
DB_PASSWORD: "change-me"
SITE_URL: "http://localhost:80"
ALLOWED_HOSTS: "localhost"
CSRF_TRUSTED_ORIGINS: "http://localhost"
ENABLE_REGISTRATION: "TRUE" # disable after creating your account
DISABLE_EMAILING: "TRUE" # set up SMTP for full functionality
GUNICORN_WORKERS: 1
# Optional: AI features. AI_PROVIDER picks the service, its settings start with
# AI_PROVIDER_<NAME>_ (see Admin Manual: AI Providers). Example, a self-hosted model:
# AI_PROVIDER: local
# AI_PROVIDER_LOCAL_BASE_URL: "http://host.docker.internal:11434/v1"
# AI_PROVIDER_LOCAL_MODEL: "qwen3.8:27b"
# AI_TRIAL_USAGE_LIMIT: 10 # per user and month, in US cents; 0 = no limit
volumes:
# Required: all uploaded images (avatars, backgrounds, project pictures) live in /app/data
- ./comaney/data:/app/data
mariadb:
image: mariadb:lts
restart: unless-stopped
environment:
MARIADB_DATABASE: comaney
MARIADB_USER: comaney
MARIADB_PASSWORD: "change-me"
MARIADB_ROOT_PASSWORD: "change-root-too"
volumes:
- ./comaney/mariadb:/var/lib/mysql
All options and production setup: Admin Manual: Deployment.
Important: the
/app/datamount is required. Comaney stores every uploaded image (avatars, backgrounds, project pictures) under/app/datainside the container; without a persistent mount there, they are lost whenever the container is recreated, and the app shows a configuration error page instead of starting normally. Point the left side at any host directory you back up.
docker compose up -dhttp://localhost/register/, or create one from the command line:
docker exec -it comaney-web-1 python manage.py create_user you@example.com
ENABLE_REGISTRATION: "FALSE" and restart.To change a user's password at any time:
docker exec -it comaney-web-1 python manage.py set_user_password you@example.com
# Every 5 minutes: notifications, recurring expense generation, auto-settle, end-of-month allowance handling
*/5 * * * * user docker compose -f /path/to/docker-compose.yml exec -T web python manage.py run_cron
# Monthly: reset AI trial budgets
0 0 1 * * user docker compose -f /path/to/docker-compose.yml exec -T web python manage.py reset_trial_budgets
| Variable | Default | Description |
|---|---|---|
DJANGO_SECRET_KEY | (dev placeholder) | Required in production. Signs sessions and CSRF tokens. |
DB_HOST / DB_PORT / DB_NAME / DB_USER / DB_PASSWORD | 127.0.0.1 / 3306 / comaney / comaney / comaney | MariaDB connection. |
SITE_URL | http://localhost:8080 | Public base URL, embedded in outgoing email links. |
ALLOWED_HOSTS | * | Comma-separated list of accepted hostnames. |
CSRF_TRUSTED_ORIGINS | (empty) | Required when behind an HTTPS reverse proxy. |
ENABLE_REGISTRATION | FALSE | TRUE to allow new signups. |
DISABLE_EMAILING | (unset) | TRUE to suppress all emails (also disables email verification). |
EMAIL_HOST / EMAIL_PORT | (none) | SMTP server. Required unless DISABLE_EMAILING=TRUE. |
EMAIL_USE_TLS | (unset) | TRUE for STARTTLS (port 587). |
EMAIL_HOST_USER / EMAIL_HOST_PASSWORD | (empty) | SMTP credentials. |
DEFAULT_FROM_EMAIL | noreply@comaney.local | Sender address for outgoing emails. |
ADMIN_NOTIFICATION_EMAIL | (unset) | Receives system alerts. Also enables the contact form. |
AI_PROVIDER | (unset) | AI service for the AI features: claude, deepseek, local (any OpenAI-compatible server) or none. Unset = no AI. |
AI_PROVIDER_<NAME>_* | Settings of the chosen AI service (key, model, ...). See Admin Manual: AI Providers. | |
AI_TRIAL_USAGE_LIMIT | 0 | Per-user monthly cap in US cents for the shared AI access; 0 = no limit. |
AI_TRIAL_API_KEY | (unset) | Deprecated old name of the shared key setting; see the AI Providers page. |
PUBLIC_PAGE_IMPRINT_MD | (unset) | Path to a Markdown file served at /impressum/. |
PUBLIC_PAGE_EUDATENSCHUTZ_MD | (unset) | Path to a Markdown file served at /datenschutzerklaerung/. |
GUNICORN_WORKERS | 1 | Number of Gunicorn worker processes. |
Full reference: Admin Manual: Environment Variables
./build/build-assets.sh
Runs npm install && npm run build inside a node:25.9.0-slim linux/amd64 container. Never run npm directly on the host; see Dev Manual: Building Assets.
./docs/build/build-docs.sh
Builds the mkdocs site to docs/build/site/, then served by Django at /docs/.
# Stack must be running: docker compose up
# Mailpit at :8030, app at :8080
pip install -r requirements-test.txt
pytest ./tests/ -vsx
See Dev Manual: Testing for full details.
The dev stack can run against a self-hosted model on your machine (AI_PROVIDER=local), with or without authentication. On a Mac the model server runs natively for GPU access; plain docker compose up -d is unchanged. See Dev Manual: Local AI in the Dev Stack.
docker buildx build \
--platform linux/amd64 \
-f Deployment/Dockerfile \
-t leonetienne/comaney:<version> \
--build-arg APP_VERSION=<version> \
--push \
.
A no-BS, zero-effort budgeting software as a self-hostable service with tons of insights.
See the codeBudgeting that actually fits into your life.
Check it out now!
| URL | comaney.app/login |
demo@comaney.app | |
| Password | 91448 |
The demo account is a public sandbox. Do not enter personal, sensitive, or illegal data. It is reset automatically once a week.

Custom themes, configurable in your account settings. Download exemplary backdrop files.
Full documentation is available at https://comaney.app/docs.

Comaney is a personal budgeting app available as a hosted service at comaney.app or self-hosted on your own server.
Log expenses with a title, amount, date, and category. Tag them however you like and search or filter across your whole history in seconds. Export everything to CSV at any time.
Set up scheduled expenses (subscriptions, rent, insurance) once and Comaney generates them automatically. Get notified when a payment is coming up or overdue.
The modular dashboard lets you build your own overview from scratch: spend-by-category charts, running totals, custom lists, and more. Each card is fully configurable and can link through to the matching filtered expense list.
AI express entry lets you jot down a quick note like "strawberries for date night with Ann, 4 EUR" and Comaney turns it into a properly categorised and tagged expense. Snap a photo of a receipt and it splits it into individual line items automatically.

How much did the bathroom renovation cost in the end? Put every expense that belongs to it (tiles, plumber, paint, the rented tile cutter) into a project and Comaney adds it all up for you, no matter how many months it took. Projects don't need anyone else: they're a place to collect everything that belongs to one undertaking, alongside your normal monthly budget. See Projects below.

Comaney runs an MCP (Model Context Protocol) server, so AI assistants can read and write your account directly. Each assistant gets its own agent key. See User manual: AI Assistants (MCP).
A REST API lets scripts and other apps read and write your data, for example to import bank transactions. See User manual: REST API Access.
A project is an expense container tied to a specific goal, event, or ongoing situation. Projects work fine on their own as a way to keep expenses organized, and they scale up to full multi-person shared budgets when you need them.
Examples:
A solo project is just you. It is a clean way to bucket all expenses related to a specific goal without mixing them into your main expense list. The debt diagram and settlement tools are hidden because there is no one else to settle with.
Add other people to a project and it becomes a shared budget. A project can include any mix of:
When creating an expense, set the assignment to Project and pick the project. For multi-member projects you then set:
If a connected user is set as the one who paid, the expense is created in their account and they must approve it before it counts toward the balance.
The project page shows two debt views based on all approved shared expenses:
The Your balance section gives you a plain-language summary of who you owe and who owes you.
Use the Pay someone back form on the project page to record a payment. The amount is pre-filled with what you owe, but you can enter any value.
The project admin can also settle the entire project at once: Comaney calculates the simplified debt breakdown and creates one settlement per debtor-creditor pair in a single action, then notifies everyone by email.
Every project has one admin. Only the admin can invite and remove members, trigger a group-wide settlement, archive or delete the project, and transfer admin rights.
Archiving freezes the project. No new expenses or settlements can be created, but in-flight settlements can still be confirmed. Archived projects remain accessible for review but no longer appear in expense form dropdowns.
Removing a real user keeps their name as a read-only offline entry so past expenses still reference them correctly.
Removing an offline member moves their shared expense history to Achim Archive rather than deleting it, keeping all balances intact.

If you want to split costs with a single person, you do not need a project. The Contacts feature gives you the same split-pay mechanics directly between two people.
Click Contacts in the navigation.
You can link an offline contact to their real Comaney account later so the full history carries over.
Create a new expense and set the assignment to Contact. Choose the contact, set who paid and the split, then save.
From the Contact Expenses page, use the Pay someone back form. For a connected user, they must confirm receipt before the balance clears. For an offline contact, it is confirmed automatically.
If a connected contact logs an expense with you as the one who paid upfront, it appears in the "Did you pay for this?" section on Contact Expenses. Approve it to move it into your regular expense list; reject it to delete it entirely.

When you remove an offline member from a project or your contacts, Comaney does not delete their shared expense history. It moves that history to a placeholder called Achim Archive so all balances stay correct.
Multiple removed offline members all fold into the same archive. You can permanently delete the archived expenses at any time; Comaney shows you exactly what will change before asking you to confirm. This cannot be undone.
Comaney runs as a Docker container backed by MariaDB.
services:
web:
image: leonetienne/comaney:latest
restart: unless-stopped
ports:
- "80:8000"
depends_on:
- mariadb
environment:
# Generate: python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
DJANGO_SECRET_KEY: "change-me"
DB_HOST: mariadb
DB_PORT: 3306
DB_NAME: comaney
DB_USER: comaney
DB_PASSWORD: "change-me"
SITE_URL: "http://localhost:80"
ALLOWED_HOSTS: "localhost"
CSRF_TRUSTED_ORIGINS: "http://localhost"
ENABLE_REGISTRATION: "TRUE" # disable after creating your account
DISABLE_EMAILING: "TRUE" # set up SMTP for full functionality
GUNICORN_WORKERS: 1
# Optional: AI features. AI_PROVIDER picks the service, its settings start with
# AI_PROVIDER_<NAME>_ (see Admin Manual: AI Providers). Example, a self-hosted model:
# AI_PROVIDER: local
# AI_PROVIDER_LOCAL_BASE_URL: "http://host.docker.internal:11434/v1"
# AI_PROVIDER_LOCAL_MODEL: "qwen3.8:27b"
# AI_TRIAL_USAGE_LIMIT: 10 # per user and month, in US cents; 0 = no limit
volumes:
# Required: all uploaded images (avatars, backgrounds, project pictures) live in /app/data
- ./comaney/data:/app/data
mariadb:
image: mariadb:lts
restart: unless-stopped
environment:
MARIADB_DATABASE: comaney
MARIADB_USER: comaney
MARIADB_PASSWORD: "change-me"
MARIADB_ROOT_PASSWORD: "change-root-too"
volumes:
- ./comaney/mariadb:/var/lib/mysql
All options and production setup: Admin Manual: Deployment.
Important: the
/app/datamount is required. Comaney stores every uploaded image (avatars, backgrounds, project pictures) under/app/datainside the container; without a persistent mount there, they are lost whenever the container is recreated, and the app shows a configuration error page instead of starting normally. Point the left side at any host directory you back up.
docker compose up -dhttp://localhost/register/, or create one from the command line:
docker exec -it comaney-web-1 python manage.py create_user you@example.com
ENABLE_REGISTRATION: "FALSE" and restart.To change a user's password at any time:
docker exec -it comaney-web-1 python manage.py set_user_password you@example.com
# Every 5 minutes: notifications, recurring expense generation, auto-settle, end-of-month allowance handling
*/5 * * * * user docker compose -f /path/to/docker-compose.yml exec -T web python manage.py run_cron
# Monthly: reset AI trial budgets
0 0 1 * * user docker compose -f /path/to/docker-compose.yml exec -T web python manage.py reset_trial_budgets
| Variable | Default | Description |
|---|---|---|
DJANGO_SECRET_KEY | (dev placeholder) | Required in production. Signs sessions and CSRF tokens. |
DB_HOST / DB_PORT / DB_NAME / DB_USER / DB_PASSWORD | 127.0.0.1 / 3306 / comaney / comaney / comaney | MariaDB connection. |
SITE_URL | http://localhost:8080 | Public base URL, embedded in outgoing email links. |
ALLOWED_HOSTS | * | Comma-separated list of accepted hostnames. |
CSRF_TRUSTED_ORIGINS | (empty) | Required when behind an HTTPS reverse proxy. |
ENABLE_REGISTRATION | FALSE | TRUE to allow new signups. |
DISABLE_EMAILING | (unset) | TRUE to suppress all emails (also disables email verification). |
EMAIL_HOST / EMAIL_PORT | (none) | SMTP server. Required unless DISABLE_EMAILING=TRUE. |
EMAIL_USE_TLS | (unset) | TRUE for STARTTLS (port 587). |
EMAIL_HOST_USER / EMAIL_HOST_PASSWORD | (empty) | SMTP credentials. |
DEFAULT_FROM_EMAIL | noreply@comaney.local | Sender address for outgoing emails. |
ADMIN_NOTIFICATION_EMAIL | (unset) | Receives system alerts. Also enables the contact form. |
AI_PROVIDER | (unset) | AI service for the AI features: claude, deepseek, local (any OpenAI-compatible server) or none. Unset = no AI. |
AI_PROVIDER_<NAME>_* | Settings of the chosen AI service (key, model, ...). See Admin Manual: AI Providers. | |
AI_TRIAL_USAGE_LIMIT | 0 | Per-user monthly cap in US cents for the shared AI access; 0 = no limit. |
AI_TRIAL_API_KEY | (unset) | Deprecated old name of the shared key setting; see the AI Providers page. |
PUBLIC_PAGE_IMPRINT_MD | (unset) | Path to a Markdown file served at /impressum/. |
PUBLIC_PAGE_EUDATENSCHUTZ_MD | (unset) | Path to a Markdown file served at /datenschutzerklaerung/. |
GUNICORN_WORKERS | 1 | Number of Gunicorn worker processes. |
Full reference: Admin Manual: Environment Variables
./build/build-assets.sh
Runs npm install && npm run build inside a node:25.9.0-slim linux/amd64 container. Never run npm directly on the host; see Dev Manual: Building Assets.
./docs/build/build-docs.sh
Builds the mkdocs site to docs/build/site/, then served by Django at /docs/.
# Stack must be running: docker compose up
# Mailpit at :8030, app at :8080
pip install -r requirements-test.txt
pytest ./tests/ -vsx
See Dev Manual: Testing for full details.
The dev stack can run against a self-hosted model on your machine (AI_PROVIDER=local), with or without authentication. On a Mac the model server runs natively for GPU access; plain docker compose up -d is unchanged. See Dev Manual: Local AI in the Dev Stack.
docker buildx build \
--platform linux/amd64 \
-f Deployment/Dockerfile \
-t leonetienne/comaney:<version> \
--build-arg APP_VERSION=<version> \
--push \
.