Open source Β· AGPLv3

Self-hosted accounting software

Own your books, not just rent them. LineLedger is open source double-entry accounting that runs on your own server and nowhere else β€” free under the AGPLv3, installed with Docker in about five minutes.

Quick start

Up and running in five minutes

One prebuilt multi-arch image runs the app, the queue worker, and the scheduler alongside MySQL. Docker and Docker Compose are the only requirements β€” there is nothing to clone and nothing to build.

mkdir lineledger && cd lineledger
base=https://raw.githubusercontent.com/lineledger/lineledger/v1.2.0/docker
curl -fsSLO "$base/docker-compose.yml"
curl -fsSL  "$base/.env.example" -o .env
curl -fsSLO "$base/backup.sh"
curl -fsSLO "$base/restore.sh"
chmod +x backup.sh restore.sh

# Edit .env: set DB_PASSWORD, DB_ROOT_PASSWORD, APP_URL, and your mail settings,
# and add DB_QUEUE_RETRY_AFTER=3700 (the queue worker runs --timeout=120).
# Then generate the encryption key and paste it into .env as APP_KEY=...
docker compose run --rm --no-deps app php artisan key:generate --show

docker compose up -d

Then open http://localhost:8080 and register. The first user you create becomes the site admin and sets up the first organization. On boot the app container runs php artisan app:upgrade (migrations plus the release’s own upgrade steps), links storage, and generates the OAuth keys.

Mail has to work before anyone can get in

Email verification is enforced: a new account can’t create its organization until it clicks the verification link, so a blank MAIL_HOST leaves a fresh install stuck at the verify-email screen. Point the MAIL_* settings at a real mailer. For a trial run, start the bundled Mailpit with docker compose --profile mail up -d and set MAIL_HOST=mailpit and MAIL_PORT=1025; its inbox is at 127.0.0.1:8025.

Back up your .env

APP_KEY encrypts sessions and secrets, and PASSKEYS_USER_HANDLE_SECRET anchors every registered passkey. Losing either one is unrecoverable β€” no one, including us, can restore them for you. backup.sh copies .env alongside every backup for exactly this reason.

Upgrading

# 1. Back up the database, storage volume and .env into ./backups
./backup.sh

# 2. In .env, pin the release:  LINELEDGER_VERSION=1.2.0

# 3. Pull the new image; app:upgrade runs on boot
docker compose pull && docker compose up -d

# 4. Confirm, and prove the books still reconcile
docker compose exec app php artisan app:upgrade --verify

The app container runs app:upgrade on every boot, and the workers wait for it to become healthy. Step 4 is safe to repeat: with nothing left to migrate it just runs the integrity check. Pin LINELEDGER_VERSION to 1.2.0 for this exact release, or to 1.2 to follow its patch releases. Images are built for amd64 and arm64.

Coming from 1.1.0?

The compose file and the backup scripts are unchanged since 1.1.0, so there is nothing new to download β€” pin the version, pull, and run the verify step. Take a backup first: one of this release’s migrations rewrites data and cannot be rolled back. Installing without Docker? 1.2.0 needs the intl PHP extension, and a time-zone database new enough to know that British Columbia stays on UTC−7 this winter. 1.2.0 also fixes a sign-in flaw where a customer-portal session could authenticate on another organization’s portal, so don’t sit on it. The upgrade guide has every step.

Backups

./backup.sh
# or write them elsewhere:  BACKUP_DIR=/mnt/backups ./backup.sh

# Restore from a backup pair:
./restore.sh backups/lineledger-db-<ts>.sql.gz backups/lineledger-storage-<ts>.tar.gz

# Unattended nightly database dumps (kept 14 days by default):
docker compose --profile backup up -d

backup.sh captures the database (with the audit-log triggers), the storage volume, and .env in one run. restore.sh puts them back and re-verifies the books. Two Docker volumes hold all your data, and docker compose down -v deletes both, so keep ./backups somewhere other than the machine it describes.

Make it yours

A handful of settings in .env decide how the install presents itself, and none of them need a fork:

  • APP_NAME, BRAND_LOGO and BRAND_FOOTER_OWNER put your own name and mark on the sign-in, registration and onboarding screens. The AGPLv3 still asks you to keep the source offer visible β€” the app ships a note about section 13 next to the setting.
  • APP_LOCALE sets the default language, English or French. Each person, organization and customer can override it.
  • APP_REGION (CA, US or GB) decides which legal documents the footer points at. It does not limit the books: one install holds Canadian, US and UK organizations side by side.
  • SUPPORT_ENABLED=false hides the in-app support desk when your support lives somewhere else. Tickets already raised stay readable.

Why it works this way

Running it yourself isn’t a compromise we ask you to accept β€” it’s the point.

πŸ”

Read every line

LineLedger is open source under the GNU AGPLv3. You β€” or your accountant β€” can audit exactly how every balance, tax figure, and report is calculated. No black box.

πŸ”

Your data, your server

The books run on infrastructure you control. Your ledger never reaches us, because there is nowhere on our side for it to go β€” and the application ships no third-party analytics.

πŸ’Έ

No bill, no ratchet

You owe us nothing β€” ever. No per-seat fees, no annual price increases, no tier to climb to unlock a feature, and no paid edition held back from the one you downloaded.

πŸ“¦

Never locked in

Export any company to a portable ZIP and move it between your own machines whenever you like. The audit chain stays verifiable across the move.

Bring your history with you

Once it’s running, import your QuickBooks chart of accounts and replay your full general-ledger history β€” accounts mapped, contacts linked, no fresh start required.

Common questions

Is LineLedger really free?
Yes. LineLedger is open source under the GNU AGPLv3 and you run it yourself, so there is nothing to pay us β€” no plans, no seats, no paid edition. Self-hosting is not a cheaper option alongside a subscription; it is the only way LineLedger runs.
What do I need to run it?
Docker and Docker Compose, and a machine to put them on. The prebuilt multi-arch image (amd64 and arm64) runs the web app, the queue worker, and the scheduler as three containers alongside MySQL. A small VPS is plenty for a single business; a spare box on your own network works just as well.
What does the server cost?
That is the only bill involved, and it comes from your hosting provider rather than from us. A small VPS runs about Β£8–15 a month, and hardware you already own costs nothing extra.
How do upgrades work?
Back up with ./backup.sh, set LINELEDGER_VERSION in your .env to the new release, then run docker compose pull && docker compose up -d. On boot the app container runs php artisan app:upgrade (pending migrations plus any data steps the release ships), and the worker and scheduler wait until it is healthy. Finish with docker compose exec app php artisan app:upgrade --verify, which checks that the books still reconcile. Go one release at a time, and read that release's section in UPGRADING.md first.
How do I back it up?
Run ./backup.sh. It writes a database dump (with the audit-log triggers), an archive of the storage volume, and a copy of your .env into ./backups, and prints the matching ./restore.sh command. For unattended nightly database dumps, start the backup profile with docker compose --profile backup up -d. Copy ./backups off the machine either way.
What happens if you stop working on it?
Your install keeps running. It does not phone home, there is no licence to expire, and nothing about your books depends on us still being here. The AGPLv3 gives you the source, the right to modify it, and the right to hand it to someone else to maintain.