A small, self-hosted time-tracking web app. Log hours per client, task type and period, track daily-hours targets and overtime, and produce printable per-client and per-period reports.
It ships as a single Go binary with server-side rendered
templ views, a Bulma UI, and an
embedded SQLite database. Static assets and templates are compiled into the
binary, so a deployment is one file. That same binary runs the web server
(time-tracker serve) and the admin commands (register, export-users).
- Tasks: log time entries with a title, client, task type, period, date and hours. Entries are grouped by day with per-day totals.
- Clients, task types and periods: manage each from its own page, with dedicated edit pages to rename them. A client can restrict which task types it allows, and one period can be marked as the default.
- Daily targets and overtime: set target hours per weekday under My account. The Time page shows each day's hours against its target, grouped by month with monthly subtotals.
- Date-range filter: sum hours, target and overtime between two dates. An open-ended range runs up to today.
- Printable reports: standalone, print-friendly pages that open the browser
print dialog for save-as-PDF.
/time/reportproduces a day-by-day time report over the selected range./clients/{id}/reportproduces a per-client report: a summary table of hours per task type, followed by one detail table per task type, honoring the active filters.
- Bilingual: English and French (
/lang/en,/lang/fr). - Authentication: email and password login backed by opaque, server-side session tokens stored in a cookie. Sessions live in memory, so they are lost on restart and can be revoked instantly.
Choose one of the options below, then follow First run to create a user and log in.
A multi-arch image is published to GHCR on every push to master and on
version tags, for linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v6,
linux/386, linux/ppc64le, linux/s390x and linux/riscv64.
docker run -d -p 8080:8080 \
-e JWT_SECRET=change-me \
-v time-tracker-data:/data \
ghcr.io/bloomyindev/time-tracker:latestThe container runs time-tracker serve by default. The database is stored in
the /data volume (DB_PATH=/data/time-tracker.db). Run admin commands inside
the container with docker exec <container> /app/time-tracker <command> (see
CLI).
An example compose.yml is included:
docker compose up -d
docker compose exec time-tracker /app/time-tracker register \
--email you@example.com --password secretDownload a tarball for your OS and architecture from the
Releases page. Each
archive contains the single time-tracker binary. Prebuilt targets:
| OS | Architectures |
|---|---|
| Linux | amd64, 386, arm64, armv7, ppc64le, riscv64, s390x, loong64 |
| macOS | amd64, arm64 |
| Windows | amd64, 386, arm64 |
| FreeBSD | amd64, arm64 |
| OpenBSD | amd64, arm64 |
| NetBSD | amd64 |
tar -xzf time-tracker_*_linux_amd64.tar.gz
cd time-tracker_*_linux_amd64
JWT_SECRET=change-me ./time-tracker serveBuilding from source requires Go 1.26 or later. See DEVELOPMENT.md for the full setup.
- Start the server. It listens on http://localhost:8080. In production,
always set
JWT_SECRET(see Configuration). - Create a user. There is no public sign-up:
./time-tracker register --email you@example.com --password secret # from source: ./bin/time-tracker register ... # docker: docker exec <container> /app/time-tracker register ...
- Log in at http://localhost:8080/login with those credentials.
The app is configured through environment variables:
| Variable | Default | Description |
|---|---|---|
DB_PATH |
time-tracker.db |
Path to the SQLite database file. |
JWT_SECRET |
dev-secret-change-me |
Secret for signing JWTs used by the (currently unused) bearer-token API flow. Set this in production. |
The server always listens on port 8080. The database path can also be passed
with --db-path. The schema is created and migrated automatically on startup.
The admin commands live in the same binary as the server:
time-tracker serve # run the web server
time-tracker register --email <email> --password <password> # create a user
time-tracker export-users # dump users as JSON (no password hashes)Every command accepts --db-path (or the DB_PATH environment variable).
Development setup, build instructions and the project layout are documented in DEVELOPMENT.md.
GNU AGPL v3. See LICENSE.