Tracearr¶
Media-server session and library analytics in the media namespace
(connorgallopo/Tracearr).
Database¶
Tracearr builds its statistics on TimescaleDB: sessions and library_snapshots are hypertables
and five continuous aggregates (daily engagement, plays, bandwidth, library stats, content quality)
are refreshed by policy. Continuous aggregates are in Timescale's TSL-licensed code, so it needs
the full TimescaleDB build, not the Apache-only timescaledb-oss image CloudNativePG publishes.
- Dedicated cluster.
tracearr-postgres(two instances,medianamespace, Flux Kustomizationtracearr-database) runstimescale/timescaledb-ha. TimescaleDB needsshared_preload_libraries, which on the sharedpostgres18would restart every tenant, so this is the dedicated-cluster case of the Postgres policy in storage. - ImageCatalog. The image is selected through an
ImageCatalogwithmajor: 18, because CloudNativePG rejectsimageNamewhen it cannot parse a major version from the tag (pg18.6-ts2.30.2).postgresUID/GID: 1000match the image's postgres user. - Operator access. A CiliumNetworkPolicy lets the CNPG operator in
databasereach the instances; the namespacedallow-same-namespacepolicy blocks it otherwise. Any dedicated cluster outsidedatabaseneeds the same. - Backups. WAL archiving and daily base backups go to the
cnpg-tracearrGarage bucket through the barman-cloud plugin (30-day retention), with its own key so the shared CNPG key never sits inmedia. The NAS mirror and R2 copy jobs pick the bucket up, andCNPGBackupStalealerts after 36 hours without a base backup. To restore, bootstrap a new Cluster withrecoveryfrom thetracearr-postgres-garageObjectStore (resolved H-22).
Migration from the shared cluster¶
The data moved from postgres18 on 2026-10-09 with tracearr scaled to 0: pg_dump -Fc on the old
primary piped into pg_restore --no-owner --no-acl --role=tracearr --single-transaction on the new
one, run as the operator's superuser. Tracearr's own UI restore was not used: it drops and recreates
the timescaledb extension and calls timescaledb_pre_restore(), which need a superuser that the
app role is not. On first start Tracearr converted sessions and library_snapshots to hypertables
and built the continuous aggregates itself. The old database and role on postgres18 were dropped the same day, once the new
cluster had a completed base backup.
Upgrading TimescaleDB¶
Renovate tracks the image with regex versioning that keeps PostgreSQL 18 fixed and never
auto-merges. A new ts version changes the binaries but not the installed extension; the
extension belongs to the superuser, so neither CNPG nor Tracearr updates it. After the new image
has rolled out, run as the first command of a fresh session:
kubectl cnpg psql tracearr-postgres -n media -- -X -d tracearr -c 'ALTER EXTENSION timescaledb UPDATE'
A PostgreSQL major upgrade needs a dump and restore; use Tracearr's own backup and restore.
Node rolls¶
The cluster has its own primary PodDisruptionBudget. Draining the node that hosts the primary
relies on CNPG switching over to the replica once the node is cordoned; if the replica is still
catching up from the previous node's reboot the drain can time out. Check
kubectl -n media get cluster tracearr-postgres shows both instances ready before rolling the next
node.