Tóm tắt: Grafana đọc file YAML trong /etc/grafana/provisioning/datasources/ và /etc/grafana/provisioning/dashboards/ lúc khởi động. Provider dashboard trỏ tới một thư mục chứa file JSON; mỗi thư mục con có thể thành một folder. Cố định uid cho datasource và dashboard để link và tham chiếu không bị đổi.
Luồng hoạt động
flowchart LR G[Git repo] --> V["Docker volume / bind mount"] V --> DS["provisioning/datasources/*.yaml"] V --> DP["provisioning/dashboards/*.yaml"] V --> J["dashboards/*.json"] DS --> GF[Grafana khởi động] DP --> GF J -->|"quét lại mỗi updateIntervalSeconds"| GF GF --> UI[Folder và dashboard trên UI]
Cấu hình
Cấu trúc thư mục
grafana/
├── docker-compose.yml
├── provisioning/
│ ├── datasources/telemetry.yaml
│ └── dashboards/provider.yaml
└── dashboards/
├── Telemetry/interfaces.json
└── Flows/top-talkers.jsonDocker Compose
services:
grafana:
image: grafana/grafana:12.2.0
ports: ["3000:3000"]
environment:
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD}
GF_INSTALL_PLUGINS: grafana-clickhouse-datasource
INFLUX_TOKEN: ${INFLUX_TOKEN}
CH_PASSWORD: ${CH_PASSWORD}
volumes:
- ./provisioning:/etc/grafana/provisioning:ro
- ./dashboards:/var/lib/grafana/dashboards:ro
- grafana-data:/var/lib/grafana
volumes:
grafana-data:Đọc thêm về env, volume, override trong Docker Compose patterns.
Datasource
apiVersion: 1
datasources:
- name: InfluxDB-telemetry
uid: influx-telemetry
type: influxdb
access: proxy
url: http://influxdb:8086
jsonData:
version: Flux
organization: netops
defaultBucket: telemetry
secureJsonData:
token: $INFLUX_TOKEN
- name: Prometheus
uid: prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
- name: ClickHouse-flows
uid: clickhouse-flows
type: grafana-clickhouse-datasource
jsonData:
host: clickhouse
port: 9000
protocol: native
username: grafana
defaultDatabase: default
secureJsonData:
password: $CH_PASSWORDGrafana thay $VAR / ${VAR} bằng biến môi trường của container. Muốn xoá một datasource đã provision thì thêm khối deleteDatasources (name, orgId).
Dashboard provider
apiVersion: 1
providers:
- name: telemetry-dashboards
type: file
disableDeletion: true
allowUiUpdates: false
updateIntervalSeconds: 30
options:
path: /var/lib/grafana/dashboards
foldersFromFilesStructure: truefoldersFromFilesStructure: true biến thư mục con (Telemetry/, Flows/) thành folder. Khi bật nó thì không đặt folder / folderUid trong provider.
Dashboard JSON
Lấy JSON từ UI: Dashboard → Export → Export as JSON, để tắt tuỳ chọn "Export for sharing externally". Sửa vài field trước khi commit:
{
"id": null,
"uid": "telemetry-interfaces",
"title": "Interfaces",
"panels": [
{
"type": "timeseries",
"title": "Traffic in (bps)",
"datasource": { "type": "influxdb", "uid": "influx-telemetry" }
}
]
}Query cho panel xem InfluxDB Flux hoặc PromQL cheatsheet.
Áp dụng và kiểm tra
docker compose up -d
docker compose logs grafana | grep -i -E 'provision|error'
curl -s -u admin:"$GRAFANA_ADMIN_PASSWORD" localhost:3000/api/datasources | jq '.[].uid'
curl -s -u admin:"$GRAFANA_ADMIN_PASSWORD" 'localhost:3000/api/search?type=dash-db' | jq '.[] | {title, folderTitle, uid}'Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách xử lý |
|---|---|---|
Panel báo Datasource ${DS_INFLUXDB} was not found |
JSON export bằng "for sharing externally" | Export lại không bật tuỳ chọn đó, hoặc thay bằng uid cố định |
| Panel "datasource not found" sau khi dựng lại | uid datasource sinh ngẫu nhiên |
Đặt uid trong file provisioning |
| Dashboard không cập nhật khi sửa file | Sai path, hoặc file JSON lỗi cú pháp |
Xem log provisioning.dashboard, chạy jq . file.json |
| Sửa trên UI rồi mất | Provisioned dashboard bị ghi đè từ file | Sửa file trong Git; allowUiUpdates: true chỉ để thử |
| Không lưu được, báo "Cannot save provisioned dashboard" | Dashboard do provisioning quản lý | Export JSON, cập nhật file |
Hai dashboard trùng uid / tên |
Copy file mà không đổi uid |
Mỗi file một uid riêng |
| Plugin ClickHouse không có | Chưa cài plugin | Biến GF_INSTALL_PLUGINS hoặc cài sẵn trong image |