Kimai¶
Time tracking.
| Runtime | Container (Docker Swarm), 2 containers: app, db |
| Tier | Apps (Important) |
| Node | swarm-core |
| Image | kimai/kimai2:2.62.0; mariadb:11.4 |
| URL | https://kimai.lab.riversfamily.uk |
| Auth | Native SAML |
| Source | ansible/stacks/apps/kimai/ |
Bumped to 2.62.0 (issue #105/PR #106): the apache- image prefix was retired
after 2.57.0; the bare 2.62.0 tag is now the Apache variant and still
serves on port 8001, so this was a straight tag bump.
Configuration¶
SAML config is rendered into a mounted Symfony local.yaml
(/opt/kimai/config/packages/local.yaml), not env vars. It embeds the
shared SAML signing certificate directly
({{ authentik_saml_signing_cert | indent(10) }}) — the certificate is
public, so this is not a secret.
TRUSTED_HOSTS/TRUSTED_PROXIES are pre-set for the Traefik-fronted
deployment.
Volumes¶
| Volume | Path | Backing | Contents |
|---|---|---|---|
data |
/opt/kimai/var/data |
Local | Application data |
database |
/var/lib/mysql |
Local | MariaDB data — never NFS |
| (rendered) | /opt/kimai/config/packages/local.yaml |
Read-only | SAML config |
Networking¶
app joins both the shared traefik network (for its Traefik route) and
this stack's private internal network. db joins internal only — it is
unreachable from every other stack.
Secrets¶
| Vault variable | Delivered as | Purpose |
|---|---|---|
vault_kimai_db_password |
Swarm secret on db (MARIADB_PASSWORD_FILE); app reads the same value inline in DATABASE_URL |
MariaDB password |
vault_kimai_app_secret |
Plain env var (APP_SECRET) |
Symfony app secret |
vault_kimai_admin_password |
Plain env var (ADMINPASS) |
Initial admin password |
db also sets MARIADB_RANDOM_ROOT_PASSWORD: "yes" — a random root password
needs no secret at all.
Gotchas¶
- Kimai has no native OIDC support, so it is the only Apps-tier service using SAML instead of OIDC or forward-auth.
- Shares the SAML signing certificate with Snipe-IT and Fleet (both experimental tier) — rotating that certificate means redeploying all three.