概要
先日公開した記事の中で、supabaseを利用していました。
issueやpull requestの数を見ていても、
まだまだ機能の追加・改善がされるサービスと思っています!
何か作成中、動作確認の度にクラウドからデータ取得をしていると、データ受取量が増え、コストとなる場合もあります。
ローカルに構築したsupabase環境からデータ取得することで、
コストセーブに加えて、開発しやすさも向上すると思いました。
ということで今回はローカル環境を構築してみました。
チュートリアルを見ていると大きく2種類の流れがあります。
- ローカル環境に1から構築
- 既にクラウド上に作成済のデータベースの情報をローカルに反映
今回私の場合は、後者の状況です。
操作がシンプルで、公式ドキュメントだけで完了するのは助かります。
セットアップ
supabaseのローカル環境構築に必要なコンテナのダウンロードまでは、以下のページに記載されています。
既にローカルにあるReactのプロジェクトなどがある前提で話をします。
npx npm install supabase --save-dev
初期化を実施します。
npx supabase init
supabase
というフォルダが作成されます。
続けて以下を実行します。
npx supabase start
コンテナがいくつか作成された後に、いくつか情報が出力されます。
http://127.0.0.1:XXXX
といった情報がいくつかあるので、ローカル動作確認用と確認できますね。
セキュリティの都合上、載せていませんが、この画像の続きとして、JWT secret
・anon key
・service_role key
が記載されています。
今回の作業では、以下が必要になります。
- API URL
- DB URL
- anon key
リモートのテーブル定義をローカルにpull
ここからは以下のページを参考にして進めます。
以下を実行して、TOKENを取得します。ただし今回は認証までは実施していないので、使う場面はありません。
npx supabase login
続けて、特定のプロジェクトと結びつけるため、以下を実行します。
ダッシュボードのURLの、projects以降の文字列を使います。
https://supabase.com/dashboard/project/XXXXXXXXXXXXXXXXXXXX
npx supabase link --project-ref $PROJECT_ID
実行すると、パスワードを聞かれます。
このパスワードは、DB作成時に設定した値を入力します。入力して問題なければ、以下の通り出力されます。
Enter your database password (or leave blank to skip):
Finished supabase link.
これでリモートからローカルにDBの情報を反映する準備ができました。
続けて以下を実行し、リモートの状態をローカルで取得します。この段階では、まだローカルにテーブルは作成されません。
npx supabase db pull
history更新するかどうか聞かれます。
今回私の場合は、履歴を残す必要もなさそうだったので、no
にしました。
ターミナルに出力された通りですが、supabaseのディレクトリを見ると、sqlファイルが追加されていました。
作成されたファイルについて、一部ですが、以下のようにDDLなどが記載されています。
(私はmoviesテーブルを作成していたので、以下の情報がありました。)
CREATE TABLE IF NOT EXISTS "public"."movies" (
"id" bigint NOT NULL,
"name" "text",
"description" "text"
);
テーブル作成とデータ投入
ローカルにテーブル定義やデータを反映する作業は、以下ページのAdd sample data
セクションの情報を確認します。
既にテーブル定義はpullしたので、初期データ投入して準備完了です。
supabase/seed.sql
というファイルに、データを投入するためのSQLを記述します。
seed.sqlの例
INSERT INTO "public"."movies" ("id", "name", "description")
VALUES
(1, 'The Empire Strikes Back', 'After the Rebels are brutally overpowered by the Empire on the ice planet Hoth, Luke Skywalker begins Jedi training with Yoda.'),
(2, 'Return of the Jedi', 'After a daring mission to rescue Han Solo from Jabba the Hutt, the Rebels dispatch to Endor to destroy the second Death Star.'),
(12, 'name', 'description'),
(14, 'name', 'description_2023/11/26 9:45:10'),
(16, 'name', 'description_2023/11/26 9:45:30'),
(17, 'name', 'description_2023/11/26 9:45:33'),
(18, 'name', 'description_2023/11/26 9:46:27'),
(22, 'name', 'description_2023/11/26 9:47:6'),
(24, 'name', 'description_2023/11/26 9:47:39'),
(27, 'name', 'description_2023/11/26 9:47:52');
私は、supabaseのdashboardからcsvファイルをデータをexportしていたので、そのデータをSQLに変更して、記述しました!
こういう作業でも、chatGPTは役立ちますね。
Reset your database (apply current migrations), and populate with seed data
マイグレーションを適用し、データ投入まで実施します。
npx supabase db reset
コンテナが再起動し、
resetが完了、というメッセージが表示されました。
5c712df4ab14: Pull complete
Digest: sha256:ad820ed920ba8dbf7759982b67958902943e3c887979c5ea04fd3b4b8bb20225
Status: Downloaded newer image for public.ecr.aws/supabase/gotrue:v2.109.0
Applying migration 20231203070610_remote_schema.sql...
Seeding data supabase\seed.sql...
Restarting containers...
Finished supabase db reset on branch main.
ローカルのデータを確認してみる
npx supabase start
実行後、URLなどが一覧表示された出力がありました。その中の以下のURLをブラウザで開くと、クラウド上で確認していたdashboardと同じUIで投入したデータを確認できます。
- Studio URL: http://127.0.0.1:54323
特に話をしていませんでしたが、ローカルにFastAPIのアプリケーションを用意してあります。
(冒頭に記載した別記事にアプリケーション)
特定のエンドポイントにアクセスすると、supabase上(クラウド)からデータ取得します。
取得元がクラウドからローカルに切り替わったか、確認してみます。
supabaseからデータを取得するためには、URLとKEYが必要です。
npx supabase start
で出力された情報からURLとKEYを設定します。
SUPABASE_URL=http://127.0.0.1:54321
SUPABASE_KEY=eyJhXXXXXXXXXXXXXXXXXXXXXXH6IkpXVCJ9.eyXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_I0
ローカルに対してリクエストを送信していることが確認できました。
(クラウド上のテーブルから取得した場合、
赤線部分がhttps://XXXXXXXXXXXXXXXXXXXX.supabase.co/
)
リクエスト数(データ転送量)は本当に増えていない?
ローカル開発でデータ取得を行った際に、クラウドへのリクエストがないのか、
一応確かめてみました。
ダッシュボードのメニューReports
からAPI
を選択すると、以下のグラフがあります。
- AM9時ごろ:クラウド側のテーブルに、データ取得を6回実施(赤線・矢印)
- PM6時ごろ:ローカル側のテーブルに、データ取得を6回実施
- PM10時ごろ:状況確認のため、ダッシュボードにアクセス(紫矢印)
ローカルで操作を行った、PM6時ごろのリクエスト情報がグラフにありません。
ローカルで完結しており、クラウドへのリクエストは増えていないことが確認できました。
ローカル開発とは関係ないですが、先ほどの画像右上に四角と矢印がセットになったアイコンがあります。
クリックすると、Logs Explorer
が表示されます。
SQLを組むことで、取得する情報をカスタマイズできるようです。
表示されていたSQLは、以下の処理を行っています。
- edge_logs テーブルからログデータを読み込み
- timestamp を1時間単位で丸めている (timestamp_trunc)
- 1時間ごとに集計(GROUP BY)し、順に並べ替え(ORDER BY)
SQL全量
select
cast(timestamp_trunc(t.timestamp, hour) as datetime) as timestamp,
count(t.id) as count
FROM edge_logs t
cross join unnest(metadata) as m
cross join unnest(m.response) as response
cross join unnest(m.request) as request
cross join unnest(request.headers) as headers
GROUP BY
timestamp
ORDER BY
timestamp ASC
片付けと再開
以下を実行し、コンテナを削除します。
npx supabase stop
volumeに設定した情報が出力され、ローカル環境用のコンテナは削除されました。
Postgres database saved to volume: supabase_db_clerk-nextjs-app-quickstart
Postgres config saved to volume: supabase_config_clerk-nextjs-app-quickstart
・・・
Stopped supabase local development setup.
再開時のトラブルシュート
皆さんの環境でも発生するか分かりませんでしたが、私の環境では、ローカル環境再開時にエラーが発生したので、その内容と解決手段を記載しておきます!
再度コンテナを立てるためにコマンドを実行
npx supabase start
まとめ
Dockerのみあれば構築ができて、最初のセットアップもコマンド数本で完了するので、サクッと構築できる印象を受けました。
ローカル開発に限らず、今後のアップデート動向を眺めながら、定期的にキャッチアップをしたいと思います。