A self-hosted TIG stack (Telegraf, InfluxDB 3 Core, Grafana) that stores and visualizes Home Assistant (HA) history and server metrics.
HA runs on its own host and writes directly to InfluxDB through the built-in influxdb: integration. This repository provides the storage and dashboard backend plus host-metrics collection for the monitored servers.
- Architecture · Features · Prerequisites
- Quick start · Configuration · Connect Home Assistant
- Server monitoring · Known limits
- Verify · Backup and restore · Troubleshooting · License
flowchart LR
HA["Home Assistant<br/>(separate host)"] -->|"influxdb: integration<br/>(v2 write API)"| DB
THA["Telegraf<br/>(on HA host)"] -->|host metrics| DB
subgraph TIG["TIG stack (this repo)"]
TL["Telegraf<br/>host metrics"] -->|v2 write| DB[("InfluxDB 3 Core<br/>:8181")]
DB --> GF["Grafana<br/>:3000"]
end
- InfluxDB 3 Core: Apache Arrow/Parquet engine with SQL, InfluxQL, and v1/v2 write compatibility.
- Telegraf: collects the host's CPU, memory, disk, and network metrics. Container metrics are opt-in.
- Grafana: auto-provisioned InfluxDB datasource; the admin password comes from a Docker secret, not
admin/admin. - Hardened defaults: healthchecks,
service_healthystartup ordering,restart: unless-stopped, memory limits, Docker secrets, and a private bridge network. - Reproducible: the full stack lives in
docker-compose.ymland.env.
- Docker Engine 24 or later and Docker Compose v2
- A running Home Assistant instance (any installation type) on the same network
- 2 GB of free memory (RAM)
git clone https://github.com/su-ekachai/tig-stack.git
cd tig-stack
# 1. Configuration
cp .env.example .env
# 2. Secrets (git-ignored)
mkdir -p secrets
openssl rand -base64 24 > secrets/grafana_admin_password
# Generate the InfluxDB 3 admin token (JSON) offline, using the image itself:
docker run --rm -v "$PWD/secrets:/secrets" influxdb:3-core \
influxdb3 create token --admin --name _admin --offline \
--output-file /secrets/influxdb3-admin-token.json
# Copy the raw token into .env for Telegraf and Grafana:
echo "INFLUX_TOKEN=$(grep -o 'apiv3_[A-Za-z0-9_-]*' secrets/influxdb3-admin-token.json)" >> .env
# 3. Launch
docker compose up -d
docker compose ps # every service reports "healthy"
# 4. Create the Home Assistant database with retention (run once)
docker compose exec influxdb3 sh -c \
'influxdb3 create database "$INFLUXDB_DB" --retention-period "$INFLUXDB_RETENTION" --token "$INFLUX_TOKEN"'Access after launch:
- Grafana: http://localhost:3000 (user
admin, password insecrets/grafana_admin_password) - InfluxDB: http://localhost:8181
All non-secret settings live in .env (copied from .env.example):
| Variable | Default | Description |
|---|---|---|
TZ |
UTC |
Container timezone |
INFLUXDB_PORT |
8181 |
InfluxDB HTTP port, published on the network so the HA host can write |
INFLUXDB_DB |
home_assistant |
Database that HA writes to |
INFLUXDB_RETENTION |
104w |
How long data is kept (bounds disk use) |
INFLUXDB_QUERY_FILE_LIMIT |
2000 |
Parquet files a single query may scan. Raise it for longer history (see Known limits) |
INFLUXDB_EXEC_MEM_POOL_BYTES |
1073741824 |
Query memory ceiling; raise it with the file limit if long queries run out of memory (OOM) |
GRAFANA_PORT |
3000 |
Grafana web port |
GRAFANA_ADMIN_USER |
admin |
Grafana admin username |
INFLUX_TOKEN |
(unset) | Raw apiv3_… admin token for Telegraf and Grafana |
Secrets stay in files and are never committed: secrets/influxdb3-admin-token.json, secrets/grafana_admin_password.
On the Home Assistant host, add the following to configuration.yaml and restart HA:
influxdb:
api_version: 2
ssl: false
host: <tig-stack-host-ip>
port: 8181
token: !secret influxdb_token # a scoped, non-admin InfluxDB 3 token is recommended
organization: home # any value; Core ignores it, HA requires the field
bucket: home_assistant
# add include/exclude filters as needed; see the HA integration docsHA writes through the v2-compatible API; sensors query back through InfluxQL.
Telegraf runs on each monitored machine, one agent per host, all writing to this InfluxDB.
- This stack's host: covered by the bundled Telegraf, which mounts the host filesystem (
/:/hostfs:ro) and reports the host, not the container. - The Home Assistant host (a separate machine):
- Normal Linux host: install a second Telegraf there with the same
outputs.influxdb_v2configuration. - Home Assistant OS appliance: enable the HA System Monitor integration, whose stats flow through the
influxdb:integration, or install the Glances or Telegraf add-on.
- Normal Linux host: install a second Telegraf there with the same
InfluxDB 3 Core is a recent-data engine. No data is deleted early: all writes persist for the full retention period. By default a single query reaches back about 72 hours, the product of query-file-limit (432 files) and gen1-duration (10m).
To query longer ranges in Grafana, raise INFLUXDB_QUERY_FILE_LIMIT in .env and run docker compose up -d. Larger limits cost memory and query speed. For dashboards spanning months, InfluxDB 3 Enterprise (free for at-home use, single node, two cores) adds a compactor for unbounded historical queries and is a drop-in replacement for this stack.
docker compose ps # every service "healthy"
docker compose exec influxdb3 sh -c 'influxdb3 show databases --token "$INFLUX_TOKEN"'
curl -s localhost:3000/api/health # Grafana respondsThe InfluxDB datasource is already provisioned in Grafana; open it and run Save & test to confirm connectivity.
Data lives in the named volumes influxdb3-data and grafana-storage:
docker run --rm -v tig-stack_influxdb3-data:/data -v "$PWD":/backup \
busybox tar czf /backup/influxdb3-$(date +%F).tar.gz -C /data .Restore by extracting the archive back into the volume while the stack is stopped.
| Symptom | Resolution |
|---|---|
| Grafana panels empty for ranges beyond ~3 days | Raise INFLUXDB_QUERY_FILE_LIMIT, then run docker compose up -d |
| HA data not arriving | Confirm api_version: 2, a valid token, and that port 8181 is reachable from the HA host; check the HA logs |
| Telegraf reports container instead of host metrics | Confirm the /hostfs mount and the HOST_PROC, HOST_SYS, and HOST_MOUNT_PREFIX variables are set |
docker input errors after enabling it |
The telegraf user lacks docker-group access to the socket; add group_add with the host docker group ID (see Server monitoring) |
admin/admin rejected at Grafana login |
The password is the content of secrets/grafana_admin_password |
Released to the public domain under the Unlicense.