何度もやる作業を、道具にする
データエンジニアリングの仕事では、小さな作業が何度も出てくる。
SQLの改行とインデントを揃える。調査用の値一覧をIN句にする。受け取ったCSVの列数や空文字を確認する。
一つずつは短い作業でも、そのたびに手で直していると時間がかかる。自分が実務で欲しい道具を、すぐに開ける場所へ集めておきたかった。
そこで、Midnight Bench配下の独立サイトとしてUTILIZABLEを構築し、公開した。HTML / CSS / JavaScriptを基本にした静的サイトだ。
Enterprise Data Engineering & Integration Tools
名前の通り、データを使える状態にする。最初の方針は、Browser-firstとPractical tools for working data engineers。入力データをできるだけ外部へ送らず、ブラウザで処理できるものはそこで完結させる。
今回は、その道具を作るところから、既存の公開基盤につないで更新できる状態にするまでの記録を残す。
最初は3つだけ
最初に公開したのは、普段の作業で使う場面を想像しやすい3つのツールだ。
SQL Formatter
SQLを読みやすく整形する。インデントとキーワードの大文字・小文字を揃え、結果をコピーできるようにした。Oracle / PostgreSQLを主対象とする基本整形で、SQLの構文検証や全方言への完全対応は行わない。
SQL IN Generator
値の一覧からSQLのIN句を生成する。1行1値とCSV形式を受け付け、文字列・数値の切り替え、重複値の削除、空行やNULLの除外を選べる。
AAA
BBB
CCC
↓
IN ('AAA', 'BBB', 'CCC')
調査対象のIDやコードを条件に並べたい時、引用符とカンマを手で付ける作業を減らせる。
CSV Inspector
CSVをブラウザ内で確認する。行数、列数、ヘッダ、各列の最大文字数、空文字やNULL相当の件数、数値・日付らしさを調べる。
ファイルを受け取った時に、まず構造とデータの傾向を確認したい。初期版はUTF-8を主対象にし、ファイル内容をサーバへ送らずに解析する。
独立サイトを、既存の公開基盤につなぐ
公開先はdata.midnightbench.com。アクセスの経路は次のようになる。
data.midnightbench.com
↓
Cloudflare
↓
OCI
↓
Caddy
↓
Docker network
↓
utilizable (nginx:alpine)
UTILIZABLEはMidnight Bench本体とは別のコンテナで動作する。入口は既存のCaddyを使い、ホスト名に応じてutilizable:80へreverse proxyする。
サイトのファイルと更新単位を分けておけば、UTILIZABLEのツールを追加する時も、Midnight Bench本体のアプリケーションに組み込む必要がない。
静的ファイルをnginxで配信する
HTML / CSS / JavaScriptを配信するため、コンテナにはnginx:alpineを使った。サイトファイルは読み取り専用でマウントする。
services:
utilizable:
image: nginx:alpine
container_name: utilizable
restart: unless-stopped
volumes:
- ./:/usr/share/nginx/html:ro
networks:
- midnightbench_default
networks:
midnightbench_default:
external: true
ホスト側へのポート公開は設定しない。既存のmidnightbench_defaultをexternal networkとして指定し、Caddyと同じDocker networkに参加させる。
外部からのWebアクセスはCaddyを入口にする構成だ。同じDocker network上のコンテナからは到達できるため、「Caddy経由」は公開経路の話であり、コンテナ間通信をCaddyだけに制限する設定ではない。
Caddyに入口を一つ追加する
Caddyには、UTILIZABLE用のホスト設定を追加した。
data.midnightbench.com {
reverse_proxy utilizable:80
}
CaddyでHTTPS化し、Cloudflare側はProxied + Full (strict)で運用する。CloudflareからOCI側へ接続する区間もHTTPSを使う。
Caddyからnginxへの転送先は、Docker network内のutilizable:80。外側のHTTPS接続と、コンテナ間の転送先を分けて設定した。
更新をmainへのpushにつなぐ
ローカルの作業場所、ソース管理、OCI上の配置先を決めた。
D:\work\utilizable/opt/utilizableGitHub Actionsはmainブランチへのpushをトリガーにする。OCIへSSH接続し、配置済みのリポジトリで次のコマンドを実行する。
cd /opt/utilizable
git pull origin main
docker compose up -d
接続に必要な情報はGitHub Secretsで管理する。この記事には認証情報やPrivateリポジトリのURLは載せない。
開発
↓
commit
↓
push
↓
GitHub Actions
↓
OCI
↓
本番
ローカルで修正して確認し、commitしてpushする。そこから先の取得とコンテナ起動を自動化した。静的ファイルはマウントしているため、更新した内容をnginxから配信できる。
使われ方と表示性能を観測する
data.midnightbench.com専用にCloudflare Web Analyticsを導入した。ページビューとCore Web Vitalsを確認できるようにし、公開後の利用状況と表示性能を観測する。
どのツールが開かれるか。表示や操作に待ち時間がないか。公開した後も確認できる状態を作っておく。
一方、SQLやCSVの中身はアクセス解析に必要ない。ツールに入力したSQL、文字列、CSVファイルなどをAnalyticsへ送信しない設計にしている。
閲覧情報と入力データを分けて考える
業務で扱うデータを貼り付ける道具なら、入力がどこで処理されるかを説明しておきたい。UTILIZABLEにはPrivacyページを用意した。
現在の3ツールは、入力したSQL・文字列・CSVをブラウザ内で処理する。入力データをサーバ、外部API、AIサービスへ送信せず、Cookie、localStorage、IndexedDBにも保存しない。
ページを開く時には通常のWeb通信が発生し、アクセス情報が記録される場合がある。Cloudflare Web Analyticsも利用する。この閲覧に伴う情報と、ツールの入力欄やファイルから受け取るデータは分けて扱う。
Copyで結果をクリップボードに書き込むこと、Clearでは既にコピーした内容まで消えないことも記載した。将来サーバ処理が必要な機能を追加する場合には、送信する内容と目的をその機能で明示する。
次も、自分が使う道具から
今後ツールを拡張していく対象領域は、次のように考えている。すべての領域を現在提供しているわけではない。
- SQL
- Database
- CSV / Files
- ETL / Integration
- Data Warehouse
- Data Quality
- Documentation
実務で繰り返し使うものから、一つずつ追加していく。既存の3ツールも、実際に使って気づいたところを直していくつもりだ。
まずは、ブラウザで使える3つの道具と、それを公開・更新する経路ができた。