Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MTDify

MTD Bookkeeping Software

Django Tailwind CSS SQLite First PostgreSQL Docker Ready Self Hosted Ready VPS Hosting

Manage Transactions Daily
A lightweight, self-hosted bookkeeping tool for UK sole traders and the self-employed.

FeaturesQuick StartDesktop AppLocal DevelopmentSelf-Hosted DeploymentDocumentation


Overview

MTDify is a Django-based bookkeeping application designed specifically for UK sole traders and self-employed individuals. It provides a simple, privacy-focused way to track income, expenses, and VAT—all while keeping your data under your complete control.

Key Principles:

  • You own your data — Everything is stored locally in SQLite
  • Privacy first — No cloud dependencies, no data sharing
  • Simple and focused — Built for sole traders, not enterprise accounting
  • UK tax year aware — Automatically handles April-to-April tax years and UK dates.

Features

  • Transaction Management — Track income and expenses with categorisation
  • VAT Calculations — Automatic VAT rate application and tracking
  • Quarterly Summaries — View your finances by UK tax quarters (Q1-Q4)
  • Tax Year Reports — Year-to-date profit/loss statements
  • CSV Exports — Export all your data when needed
  • Receipt Storage — Attach receipt images to expenses
  • Recurring Entries — Set up automatic monthly transactions
  • Multi-Currency Display — Each user can choose their preferred symbol (£, €, or $) in Settings
  • Native Desktop App — Run as a standalone Windows app in its own window — no browser required (see Desktop App)
  • Daily Backups — Automatic database backups - backups appear at /app/data/db/backups/ inside the container
  • Multi-user Ready — Support for multiple user accounts

Admin Interface

MTDify uses Adminita, a clean and modern Django admin theme. Adminita provides a new look for the Django admin panel with improved typography, spacing, and visual hierarchy.

Quick Start

Choose your preferred deployment method:

Method Best For Difficulty
Desktop App (Windows) A standalone Windows app for non-technical users — no Python needed Easy
Local Development Testing, development, personal use on your machine Easy
Self-Hosted (Docker) Production server deployment Medium
Self-Hosted (Manual) VPS/dedicated server without Docker Medium

Local Development

Run MTDify locally on your machine for development, testing, or personal use. This method runs the Django development server which is perfect for single-user scenarios.

Prerequisites

  • Python 3.11 or higher
  • pip (Python package manager)
  • Git

Installation

  1. Clone the repository

    git clone https://github.com/djangify/mtdify.git
    cd mtdify
  2. Create a virtual environment

    python -m venv .venv
    
    # On Windows:
    .venv\Scripts\activate
    
    # On macOS/Linux:
    source .venv/bin/activate
  3. Install dependencies

    pip install -r requirements.txt
  4. Create environment file

    cp .env.example .env

    Edit .env and set your configuration (see Configuration below).

  5. Initialize the database

    python manage.py migrate
  6. Create a superuser account

    python manage.py createsuperuser

    Or create a default demo user:

    python manage.py create_default_user

    This creates a user with email demo@example.com and password demo123.

  7. Collect static files

    python manage.py collectstatic --noinput
  8. Run the development server

    python manage.py runserver
  9. Access the application

    Open your browser and navigate to:

Running on a Different Port

python manage.py runserver 0.0.0.0:8080

Accessing from Other Devices on Your Network

To access MTDify from other devices (phone, tablet, other computers):

  1. Add your local IP to ALLOWED_HOSTS in .env:

    ALLOWED_HOSTS=localhost,127.0.0.1,192.168.1.100
    
  2. Run the server binding to all interfaces:

    python manage.py runserver 0.0.0.0:8000
  3. Access from other devices at http://192.168.1.100:8000 (use your actual local IP).


Desktop App (Windows)

MTDify can run as a true local-first desktop application — it opens in its own native window (no browser, no address bar) and can be packaged into a single standalone .exe that needs no Python installation on the end user's machine.

Under the hood this uses PyWebView for the window, waitress as the local server, and PyInstaller to bundle everything (Python, Django, your code) into one folder.

Run it in its own window (for yourself)

Double-click start_desktop.bat, or from a terminal:

python desktop.py

This sets up the virtual environment, applies migrations, starts the local server, and opens MTDify in a desktop window. The first launch also creates the default login (see below).

Build a standalone .exe (to share with others)

Double-click build_exe.bat, or run it from a terminal:

build_exe.bat

This installs dependencies and PyInstaller, collects static files, and runs PyInstaller using mtdify.spec. When it finishes you'll have:

dist/MTDify/MTDify.exe

To distribute: zip the entire dist/MTDify folder and share the zip. The .exe needs the _internal folder beside it, so don't send the .exe on its own. End users just unzip and double-click MTDify.exe — no Python, no setup. A simple, non-technical guide for them is in HOW-TO-OPEN-MTDIFY.md.

Default login

The desktop app creates a default account on first launch:

  • Email: demo@example.com
  • Password: demo123

(Override these by setting DEFAULT_USER_EMAIL / DEFAULT_USER_PASSWORD in .env before building. You can change the password later in the app's Settings.)

Where your data lives

Run mode Database & receipts location
start_desktop.bat / python desktop.py (dev) data/ inside the project folder
Packaged MTDify.exe %LOCALAPPDATA%\MTDify (persists across app updates)

The packaged app keeps user data outside the program folder so it survives reinstalls and isn't lost when you replace the app with a new build.

Requirements & notes

  • Windows 10 or 11. The build is Windows-only — it must be built on Windows, and the resulting .exe runs only on Windows. A Mac build would need to be produced on a Mac.
  • PyWebView uses the WebView2 runtime, which ships with Windows 11 and most updated Windows 10 machines. On a rare PC without it, Windows offers it as a free one-time download.
  • New apps trigger a "Windows protected your PC" SmartScreen warning. This is normal for unsigned indie software — click More info → Run anyway. This is covered in the end-user guide.
  • The app icon is read from static/images/mtdify.ico (referenced by mtdify.spec). Replace that file to change the icon.
  • If the build fails mentioning magic / libmagic, run pip install python-magic-bin and rebuild. To see detailed errors, set console=True in mtdify.spec.

Self-Hosted Deployment

Deploy MTDify on your own server for production use with multiple users or remote access.

Docker Deployment

The recommended way to deploy MTDify in production.

Prerequisites

  • Docker and Docker Compose installed
  • A domain name (optional, for HTTPS)

Quick Docker Setup

  1. Clone the repository

    git clone https://github.com/djangify/mtdify.git
    cd mtdify
  2. Create environment file

    cp .env.example .env

    Edit .env with production settings:

    DEBUG=False
    SECRET_KEY=your-very-long-random-secret-key-here
    ALLOWED_HOSTS=your-domain.com,www.your-domain.com

    Generate a secure secret key:

    python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
  3. Build and start the container

    docker-compose up -d --build
  4. Run initial setup

    # Run migrations
    docker-compose exec web python manage.py migrate
    
    # Create superuser
    docker-compose exec web python manage.py createsuperuser
    
    # Collect static files
    docker-compose exec web python manage.py collectstatic --noinput
  5. Access the application

Docker Commands Reference

# Start services
docker-compose up -d

# Stop services
docker-compose down

# View logs
docker-compose logs -f web

# Run Django management commands
docker-compose exec web python manage.py <command>

# Restart services
docker-compose restart

# Rebuild after code changes
docker-compose up -d --build

Docker Data Persistence

Data is persisted in Docker volumes:

Volume Purpose
mtdify_data SQLite database and media files
mtdify_static Collected static files

To backup your data:

# Backup database
docker-compose exec web cp /app/data/db/db.sqlite3 /app/data/db/backup-$(date +%Y%m%d).sqlite3

# Copy backup to host
docker cp mtdify_web_1:/app/data/db/backup-*.sqlite3 ./backups/

Manual Deployment

Deploy without Docker on a VPS or dedicated server.

Prerequisites

  • Python 3.11+
  • A web server (Nginx recommended)
  • Supervisor or systemd for process management

Setup Steps

  1. Clone and configure

    git clone https://github.com/djangify/mtdify.git
    cd mtdify
    python -m venv .venv
    source .venv/bin/activate
    pip install -r requirements.txt
  2. Configure environment

    cp .env.example .env
    # Edit .env with production settings
  3. Initialize application

    python manage.py migrate
    python manage.py createsuperuser
    python manage.py collectstatic --noinput
  4. Create systemd service

    Create /etc/systemd/system/mtdify.service:

    [Unit]
    Description=MTDify Gunicorn Daemon
    After=network.target
    
    [Service]
    User=www-data
    Group=www-data
    WorkingDirectory=/path/to/mtdify
    Environment="PATH=/path/to/mtdify/.venv/bin"
    ExecStart=/path/to/mtdify/.venv/bin/gunicorn \
        --workers 3 \
        --bind unix:/path/to/mtdify/mtdify.sock \
        mtdify.wsgi:application
    
    [Install]
    WantedBy=multi-user.target

    Enable and start:

    sudo systemctl enable mtdify
    sudo systemctl start mtdify
  5. Configure Nginx

    Create /etc/nginx/sites-available/mtdify:

    server {
        listen 80;
        server_name your-domain.com;
    
        location /static/ {
            alias /path/to/mtdify/staticfiles/;
        }
    
        location /media/ {
            alias /path/to/mtdify/data/media/;
        }
    
        location / {
            proxy_pass http://unix:/path/to/mtdify/mtdify.sock;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }

    Enable the site:

    sudo ln -s /etc/nginx/sites-available/mtdify /etc/nginx/sites-enabled/
    sudo nginx -t
    sudo systemctl reload nginx
  6. Set up HTTPS (recommended)

    sudo apt install certbot python3-certbot-nginx
    sudo certbot --nginx -d your-domain.com

Configuration

Environment Variables

Create a .env file in the project root with the following variables:

Variable Description Default Required
DEBUG Enable debug mode True No
SECRET_KEY Django secret key change-me-in-production Yes (production)
ALLOWED_HOSTS Comma-separated list of allowed hosts localhost,127.0.0.1 Yes (production)

Example .env for Development

DEBUG=True
SECRET_KEY=dev-secret-key-not-for-production
ALLOWED_HOSTS=localhost,127.0.0.1

Example .env for Production

DEBUG=False
SECRET_KEY=your-super-long-random-secret-key-minimum-50-characters
ALLOWED_HOSTS=mtdify.yourdomain.com,www.mtdify.yourdomain.com

Security Considerations

When DEBUG=False, the following security features are automatically enabled:

  • HTTPS redirect (SECURE_SSL_REDIRECT)
  • Secure session cookies (SESSION_COOKIE_SECURE)
  • Secure CSRF cookies (CSRF_COOKIE_SECURE)
  • CSRF trusted origins based on ALLOWED_HOSTS

Important: Always use HTTPS in production and ensure your reverse proxy sets the X-Forwarded-Proto header.


Project Structure

mtdify/
├── accounts/           # User authentication and management
├── bookkeeping/        # Core transaction tracking
│   ├── models.py       # Income, Expense, Category, RecurringEntry
│   ├── views/          # Transaction and report views
│   └── utils.py        # Tax year utilities
├── business/           # Business profile management
├── mtdify/             # Django project settings
│   ├── settings.py     # Application configuration
│   ├── urls.py         # URL routing
│   └── views.py        # Dashboard and home views
├── templates/          # HTML templates
├── static/             # CSS, JS, images (incl. app icon mtdify.ico)
├── data/               # SQLite database and media (gitignored)
│   ├── db/             # Database files
│   └── media/          # Uploaded receipts
├── desktop.py          # Desktop app launcher (PyWebView + waitress)
├── mtdify.spec         # PyInstaller build config for the .exe
├── start_desktop.bat   # Run the app in its own window (dev)
├── build_exe.bat       # Build the standalone Windows .exe
├── HOW-TO-OPEN-MTDIFY.md  # Plain-language guide for end users
├── start.bat           # Run via the browser (Django dev server)
├── requirements.txt    # Python dependencies
├── manage.py           # Django management script
├── Dockerfile          # Docker image definition
└── docker-compose.yml  # Docker Compose configuration

Usage Guide

First-Time Setup

  1. Log in with your created account
  2. Create a Business — Navigate to Business → Add Business
  3. Set your tax year — The system defaults to the current UK tax year
  4. Start tracking — Add income and expenses from the dashboard

Personalising Reports

When you generate printable reports, MTDify displays your email address by default. To include your full name and business name on reports:

  1. Go to Admin Panel (/admin)
  2. Navigate to Users and select your account
  3. Add your First Name and Last Name
  4. Ensure you've created a Business with your business name

Reports will then display your name, email, and business name in the header — useful for professional record-keeping.

Adding Transactions

Income:

  • Navigate to Bookkeeping → Add Income
  • Enter date, description, amount, and category
  • Optionally add client name and invoice number

Expenses:

  • Navigate to Bookkeeping → Add Expense
  • Enter date, description, amount, and category
  • Set VAT rate (0%, 5%, or 20%)
  • Upload receipt image (optional)

Reports

Access reports from the Dashboard:

  • Quarterly Summary — View income, expenses, and profit by quarter
  • Category Breakdown — See spending by category
  • CSV Export — Download data for your accountant

Tax Years

MTDify follows the UK tax year (6 April – 5 April):

  • Q1: April – June
  • Q2: July – September
  • Q3: October – December
  • Q4: January – March

Switch between tax years using the dropdown in the navigation bar.


API Reference

MTDify does not currently expose a public API. All interactions are through the web interface.


Troubleshooting

Common Issues

"CSRF verification failed"

  • Ensure ALLOWED_HOSTS includes your domain
  • Check that your reverse proxy passes the X-Forwarded-Proto header

Static files not loading

  • Run python manage.py collectstatic --noinput
  • Check that WhiteNoise is properly configured (it is by default)

Database locked errors

  • SQLite can have issues with concurrent writes
  • For heavy multi-user scenarios, consider PostgreSQL

Permission denied on data directory

  • Ensure the application user has write access to data/ directory
  • In Docker, check volume permissions

Getting Help


Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

Development Setup

  1. Fork the repository
  2. Clone your fork
  3. Create a virtual environment and install dependencies
  4. Create a branch for your feature
  5. Make your changes
  6. Run tests (when available)
  7. Submit a pull request

License

This project is licensed under the MIT License. See the LICENSE file for details.

Acknowledgements

Built with:


DISCLAIMER

MTDify is provided "as is" without warranty of any kind. If you choose to self-host this software, you do so at your own risk. The developer accepts no responsibility for data loss, inaccuracies, or any issues arising from its use. Always maintain your own backups and verify calculations independently.

Made for UK self employed and sole traders
Introducing Manage Transactions Daily

Maintained by Diane Corriette

About

Manage Transactions Daily Self-Hosted Bookkeeping Software

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages