Skip to content

Quick start

From git clone to a running SAE Books instance in 10 minutes.

Just want to run SAE Books?

This page builds everything from source — it's for developers. If you just want working books, the Install page has two faster paths: the one-click server (a single downloaded binary — v0.6, no Docker) and the Docker Community bundle (one docker compose command against published v0.6.1 images).

Prerequisites

  • Docker Engine 24+ with docker compose v2
  • Git
  • Python 3 (for secret generation — already on most Linux installs)

No Postgres installation needed — the compose stack ships one.

Two repos, side by side

The SAP bundle builds the API and web frontend from source. The build contexts expect both repos checked out as siblings. A single-repo clone will not work.

1. Clone both repos

git clone https://github.com/saebooks/saebooks.git
git clone https://github.com/saebooks/saebooks-web.git

Both repos must sit in the same parent directory. The compose build contexts use relative paths — ../.. for the API and ../../../saebooks-web for the web frontend.

2. Set up your environment

cd saebooks/deploy/sap
cp .env.example .env

Edit .env. At minimum, set the three secrets before starting:

# Required — generate before first up
POSTGRES_PASSWORD=   # see generation command below
SAEBOOKS_WEB_SECRET_KEY=   # see generation command below

# Strongly recommended — without this the API signs JWTs with an empty key,
# which causes auth failures on verification
SAEBOOKS_SECRET_KEY=   # see generation command below

Generate each secret:

# POSTGRES_PASSWORD
python3 -c "import secrets; print(secrets.token_urlsafe(32))"

# SAEBOOKS_WEB_SECRET_KEY
python3 -c "import secrets; print(secrets.token_hex(32))"

# SAEBOOKS_SECRET_KEY
openssl rand -hex 32

3. Build images and start

The compose stack builds the API and web images from your local source. The first build takes a few minutes; subsequent builds are fast.

docker compose up -d

4. Wait for the API healthcheck

Alembic migrations run automatically in the API entrypoint — no manual alembic upgrade head step needed for a fresh install. The api container reports healthy once migrations complete (~45 s on first start).

docker compose ps          # wait for api to show "healthy"
docker compose logs -f api  # follow startup output

5. Log in

Open http://localhost:8080 in your browser.

SAE Books will walk you through creating your first company. The Australian chart of accounts and tax codes are available in the first-run setup wizard. To pre-fill company details automatically, set SEED_COMPANY_NAME, SEED_COMPANY_LEGAL_NAME, and SEED_COMPANY_ABN in .env before the first start.

6. Verify the API

# Obtain a token
TOKEN=$(curl -s -X POST http://localhost:8042/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"[email protected]","password":"yourpassword"}' \
  | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")

# List accounts
curl -s http://localhost:8042/api/v1/accounts \
  -H "Authorization: Bearer $TOKEN" | python3 -m json.tool | head -30

The interactive Swagger UI is at http://localhost:8042/api/v1/docs.

What's running

api  :8080  — browser UI (Jinja2 + HTMX)
api  :8042  — JSON REST API (/api/v1/)
api  :50051 — gRPC (desktop client)
db   :5432  — Postgres 16 (internal only, not published to host)

The web UI is on port 8080. The REST API is on port 8042. The database port is not published to the host by default.

Troubleshooting

API container exits or restarts — check docker compose logs api. The most common cause is POSTGRES_PASSWORD not set, or a mismatch between the api and db containers. Delete the volume (docker compose down -v, only safe on a fresh install with no data) if Postgres was initialised with a different password.

Auth failures / tokens rejected — SAEBOOKS_SECRET_KEY is probably missing or empty. The API silently defaults to an empty signing key, which means tokens verify only until the container restarts (or across any instance that has a different value). Set SAEBOOKS_SECRET_KEY in .env and docker compose up -d to recreate the api container.

Migrations seem to hang — the api waits for Postgres to be ready. Watch docker compose logs db alongside docker compose logs api. If Postgres shows "database system is ready to accept connections," the migration is running; give it 60 s on a slow host.

Build fails with "path not found" — confirm both repos are siblings in the same parent directory. The api build context is ../.. (the saebooks repo root) and the web build context is ../../../saebooks-web. If the parent directory doesn't contain saebooks-web/, the build will fail.

Next steps