こんにちは、Doorkelでエンジニアをやっております、ヒガシと申します。
本記事の概要
rails consoleなど、CLI経由で大量のデータを使う方法
背景
サービスを運用している際、できれば管理画面などで行いたいが機能実装しきれておらず、渋々rails consoleなどのCLI経由で大量のデータを扱う業務が発生することがあるかと思います。
データ量が少量であれば単にシェルにコピペすれば済みますが、CSVデータを元に大量にデータを追加する場合などではコピペミスのリスクやシェル側で何かしらの問題が起きて正しくデータを追加できずに困るケースがあります。
考えられる対策と課題
いくつか方法が考えられます。
- サービス内にファイルアップロード機能(ActiveStorage等)があればそれでアップロード、そのファイルをCLI内で参照する
- 頑張ってバッチを書いてシェルのリダイレクト等を使う
- どこかpublicな場所に置く
1は該当機能の導線やファイルの特定などの楽さ、削除の容易さなどによって選ばれるかと思います。今回私が直面したケースだと、アップロードのUXが煩雑で、削除も面倒なので選びませんでした。
2は、実行するバッチが完成していればOKですがCLIで実行しつつ挙動を確認して進めたい、、などがあると選びづらい選択肢になります。
結果、3を選んだのですがホスティング先が重要です。gistは削除忘れ時にリスクになりうるし、s3やgcsなども事前に設定してないとなかなか面倒です。
対応方法: http-server + ngrokが楽だった
nodeのhttp-serverを使うと、特定のフォルダの静的ファイルをPC内にホスティングできます。
ngrokは、ローカル環境をPublicにアクセスできるようにするサービスで、http-serverでホスティングしている静的ファイルをPublicアクセスできるようになります。
下記のように、CLI上で使いたいファイルが入ったディレクトリでそれぞれのアプリケーションを実行することでホスティングできます。
publicになるため、URLを知られると当然漏洩のリスクがありますがCLI上でファイルをダウンロードする一瞬だけ公開であれば比較的低リスクでしょう。
$ http-server
Starting up http-server, serving ./
http-server version: 14.1.1
http-server settings:
CORS: disabled
Cache: 3600 seconds
Connection Timeout: 120 seconds
Directory Listings: visible
AutoIndex: visible
Serve GZIP Files: false
Serve Brotli Files: false
Default File Extension: none
Available on:
http://127.0.0.1:8081
http://192.168.1.15:8081
Hit CTRL-C to stop the server
$ ngrok http 8081
Account xxx
Update update available (version 2.3.41, Ctrl-U to update)
Version 2.3.35
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://ngrok-url.app -> http://localhost:8081
Forwarding https://ngrok-url.app -> http://localhost:8081
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
使い方
上記http-serverとngrokを実行しておきつつ、下記の様にCLI(rails console)上でファイルを取得して実行します。
sample_json_str = URI.open('http://ngrok-url.app/sample.json').read
sample = JSON.parse(sample_json_str)
まとめ
そもそも、console上で大量のデータを扱うようなリスクの高い作業は避けるべきですが、とはいえやらないといけないタイミングもあります。
多用しないよう気をつけつつ、比較的セキュアに作業しましょう。