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 composev2 - 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¶
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.
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¶
- Architecture — what these containers are actually doing
- Self-host in production — reverse proxy, TLS, backups, hardening
- API reference — every endpoint documented