要約
- MySQLコンテナとGrafanaコンテナを連携させて、MySQL内にあるサンプルデータをGrafana Dashboard上に表示する
-
https://github.com/rakiraki-lucky/docker-grafana
- アプリ実行方法はリポジトリのreadmeを参照
アプリ構成
ざっくり構成。
grafana-mysqlは内部コンテナからしか参照されないのでlocalhostへのポートマッピングは無し。
環境
- Docker version: 20.10.22
きっかけ
grafanaで遊びたかった。datasourceにMySQLを選んだのは使い慣れていたから。
(本来ならPrometheusやInfluxDBなんかの時系列データ向けのDBと合わせるのがいいらしい)
実装内容
DBログイン時のユーザ情報などはコンテナの環境変数として管理する。
各変数はアプリ起動時に引数として.env.dev
を渡すことで実体化させる。
version: "1.1"
services:
grafana-mysql:
image: grafana-mysql
build:
context: ./grafana-mysql
dockerfile: Dockerfile
container_name: grafana-mysql
hostname: ${DB_HOSTNAME}
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
TZ: Asia/Tokyo
host_cache_size: 0
init: true
volumes:
- grafana-mysql:/var/lib/mysql
grafana-app:
image: grafana-app
build:
context: ./grafana-app
dockerfile: Dockerfile
container_name: grafana-app
user: grafana
environment:
GF_SECURITY_ADMIN_USER: ${GF_USER}
GF_SECURITY_ADMIN_PASSWORD: ${GF_PASSWORD}
GF_DATASOURCE_DB: ${GF_DATASOURCE_DB}
DB_HOSTNAME: ${DB_HOSTNAME}
DB_PORT: 3306
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
DB_NAME: ${DB_NAME}
init: true
ports:
- ${GF_PORT}:3000
volumes:
- grafana-app:/var/lib/grafana
depends_on:
- grafana-mysql
volumes:
grafana-app:
name: grafana-app
grafana-mysql:
name: grafana-mysql
以下環境ファイルをアプリ起動時に引数として渡す。
DB_ROOT_PASSWORD=root
DB_HOSTNAME=grafana-mysql
DB_NAME=grafana-db
DB_USER=db-user
DB_PASSWORD=password
GF_DATASOURCE_DB=mysql
GF_USER=grafana-user
GF_PASSWORD=password
GF_PORT=8085
grafana-mysql
grafana-appで表示するデータを格納したMySQLコンテナ。
docker-entrypoint-initdb.d
直下にsqlファイルを配置することで、コンテナ起動時に記述クエリを自動実行してくれる。
テストデータの自動作成ができて便利。
FROM mysql:8.0
COPY ./my.cnf /etc/mysql/conf.d/
COPY ./testdata.sql /docker-entrypoint-initdb.d/testdata.sql
テストデータにはtime_table
とtime_table2
の2つのテーブルを用意した。
それぞれアプリ起動時の時刻を元に時系列データを自動生成する。
USE grafana-db
CREATE TABLE time_table (
id int(10) AUTO_INCREMENT PRIMARY KEY,
data_time DATETIME,
value int
);
INSERT INTO time_table(data_time, value) VALUES (DATE_SUB(NOW(), INTERVAL 1 HOUR), 10);
INSERT INTO time_table(data_time, value) VALUES (DATE_SUB(NOW(), INTERVAL 2 HOUR), 20);
INSERT INTO time_table(data_time, value) VALUES (DATE_SUB(NOW(), INTERVAL 3 HOUR), 30);
INSERT INTO time_table(data_time, value) VALUES (DATE_SUB(NOW(), INTERVAL 4 HOUR), 40);
INSERT INTO time_table(data_time, value) VALUES (DATE_SUB(NOW(), INTERVAL 5 HOUR), 30);
INSERT INTO time_table(data_time, value) VALUES (DATE_SUB(NOW(), INTERVAL 6 HOUR), 20);
CREATE TABLE time_table2 (
id int(10) AUTO_INCREMENT PRIMARY KEY,
data_time DATETIME,
value int
);
INSERT INTO time_table2(data_time, value) VALUES (DATE_SUB(NOW(), INTERVAL 10 MINUTE), 11);
INSERT INTO time_table2(data_time, value) VALUES (DATE_SUB(NOW(), INTERVAL 20 MINUTE), 12);
INSERT INTO time_table2(data_time, value) VALUES (DATE_SUB(NOW(), INTERVAL 30 MINUTE), 13);
INSERT INTO time_table2(data_time, value) VALUES (DATE_SUB(NOW(), INTERVAL 40 MINUTE), 14);
INSERT INTO time_table2(data_time, value) VALUES (DATE_SUB(NOW(), INTERVAL 50 MINUTE), 15);
INSERT INTO time_table2(data_time, value) VALUES (DATE_SUB(NOW(), INTERVAL 60 MINUTE), 16);
grafana-app
データ表示用のダッシュボードコンテナ。
grafanaコンテナの/etc/grafana/provisioning/
配下のdashboards
およびdatasources
ディレクトリにそれぞれの定義ファイルを配置することで、コンテナ起動時に読み取って実行してくれる。
FROM grafana/grafana:7.1.1
# sample dashboard settings
COPY ./sample-dashboard-models.json /etc/grafana/provisioning/dashboards/
COPY ./dashboards.yaml /etc/grafana/provisioning/dashboards/
# sample datasource settings
COPY ./datasources.yaml /etc/grafana/provisioning/datasources/datasources.yml
ダッシュボードについてはパネル構成などを定義したjsonファイルを別途用意し、options.pathプロパティでその保管場所を渡すことで、コンテナ起動に合わせて構築済みダッシュボードが自動作成される。
apiVersion: 1
providers:
- name: sample-dashboard
orgId: 1
folder: ""
folderUid: ""
type: file
disableDeletion: false
updateIntervalSeconds: 10
allowUiUpdates: false
options:
path: /etc/grafana/provisioning/dashboards/
foldersFromFilesStructure: true
DBへの接続情報はコンテナの環境変数として保持する構成なので、datasources.yamlもそれを読み取る形で記述した。
apiVersion: 1
datasources:
- name: sample-datasource
type: ${GF_DATASOURCE_DB}
access: proxy
orgId: 1
url: ${DB_HOSTNAME}:${DB_PORT}
user: ${DB_USER}
secureJsonData:
password: ${DB_PASSWORD}
database: ${DB_NAME}
isDefault: true
editable: false
version: "1"
実行結果
アプリを起動してgrafana dashboardを表示すると、以下のようなグラフが表示される。
今回はダッシュボードでのデータ表示が目的だったのでグラフは適当。
最後に
コンテナ間通信を行うDockerアプリを初めて組んだ。
疎通もそうだが環境変数などでの制御をどうするかに結構試行錯誤した。。。
無料公開されているAPIからデータをとってきて可視化してみると面白そう。
時系列データ向けDBは今回触らなかったので、次作るときはinfluxDBなどで作ってみたいな。
参考記事
- GrafanaでMySQLのデータを可視化する in Docker (in WSL2)
- 【Docker】【MySQL】コンテナ初回起動時にスクリプトを実行させる
- https://doc.sitecore.com/xp/ja/developers/101/managed-cloud/import-and-export-your-grafana-dashboards.html
- https://grafana.com/docs/grafana/latest/dashboards/build-dashboards/view-dashboard-json-model/
- https://dev.mysql.com/doc/refman/5.6/ja/date-and-time-functions.html#function_date-add