1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SupabaseのDB環境をローカル作成して開発(2025年3月版)

Last updated at Posted at 2025-03-02

久しぶりにSupabaseのローカル開発

1年半ほど前にsupabaseのローカル環境構築について、
以下の記事を公開しました。

しかし1年半が経過すれば、変わっていることも多いはずです。
破壊的変更があったり、サービス自体が既に終了していたり。

今どうなっているのか、キャッチアップ目的も含めて再度取り組んでみました。
ちなみに、直近で控えているSupabaseの大きな変更の1つは、以下です。
PinnedしてあるDiscussion、なのでそれくらいの)

image.png

API Keyに関する変更です。
APIキーについて呼び方・キー名の構成が以下の通り変更されます。

  • anon Key →publishable key
  • service_role Key → secret key

今年(2025年)の5月1日から次のフェーズに入ります。

We will start sending you monthly reminders to migrate off legacy API keys and start using the new keys.
New projects will be created with only new API keys.
Projects restored from 1st May 2025 will no longer be restored with the legacy API keys.

これ以降に作成したプロジェクトには、新しいAPIキーが導入されるようです。

現在のAPIキーは、今年(2025年)の9月一杯で利用できなくなります

Legacy API keys will be deleted and removed from the Docs / Dashboard.
You have to migrate to use the new API keys by this point or your app will break.

アプリケーションが機能しなくなるので、それまでに対応してください、とのことでした。

作業に至ったきっかけ

現在FlutterでAndroidアプリ作成を進めています。データが必要になってきたので、データベースの準備をしていました。他にも選択肢はあるようですが、
サービス自体は使い慣れているSupabaseがいいなと思い、今回も利用しています。

また、UIの見た目を都度確認しながらデータ取得をしていると、データ通信が発生し、無料枠を超える可能性もあります。
ローカルでDB構築できれば、気兼ねなく動作確認できる!ということでやりました。

作業の前提

環境面・技術面、とちらも少ない方だと思いますが、ご確認ください。

  • 環境面の前提
    • Dockerがインストール済
    • Supabaseのプロジェクトが作成済(デプロイまで行うため)
  • 技術面の前提
    • テーブル作成・データ投入など、基本的なSQLは知っている
    • npx,npmコマンドの基本を理解をしている

ローカル開発環境の準備

Dockerコンテナ作成まで行います。

公式ドキュメント

ドキュメントのLocal Developmentセクションの以下項目を参考にしています。

  • Getting started
  • Declarative database schemas
  • Seeding your database

作業用ディレクトリ作成

既に何か作業中のフォルダがあるとします。
ここにフォルダを追加します。(フォルダ名:任意)
作成後、対象フォルダへ移動します。

まず、以下コマンドを実行すると、package.jsonが作成されます。

npm install supabase --save-dev

続いて、以下コマンドでsupabase関連の構築を進めます。

npx supabase init
npx supabase start

エラーが発生

以下コマンドでエラーが発生しました。

npx supabase start

エラーが発生したのは、supabase_vector_xxxというコンテナでした。
xxx:作成したフォルダ名)

image.png

2025-02-04 08:11:14 2025-02-03T23:11:14.987467Z ERROR source{component_kind="source" component_id=docker_host component_type=docker_logs component_name=docker_host}: vector::sources::docker_logs: Listing currently running containers failed. error=error trying to connect: tcp connect error: Network unreachable (os error 101)

Githubのissue確認

issueが起票されていました。

記事公開の1週間ほど前にも、上述したエラーが発生している、というコメントありました。

解決方法

作成フォルダ名/supabaseフォルダに、config.tomlがあります。
analyticsセクションの先頭にあるフィールド:enabledをfalseに更新します。

analytics機能はまだ把握できていませんが、false設定でもDB関連の機能利用には特に影響なさそうです。

[analytics]
enabled = false # ここをfalseに!
port = 54327
# Configure one of the supported backends: `postgres`, `bigquery`.
backend = "postgres"

# Experimental features may be deprecated any time
[experimental]
# Configures Postgres storage engine to use OrioleDB (S3)
orioledb_version = ""
# Configures S3 bucket URL, eg. <bucket_name>.s3-<region>.amazonaws.com
s3_host = "env(S3_HOST)"

# 以下略

コンテナ作成完了

上記の対応を行えば、成功するはずです。
(ここで失敗した方はすみませんが、ご自身で解決をお願いいたします。)

以下の通り、ターミナルにURL情報が表示されます。

         API URL: http://127.0.0.1:54321
     GraphQL URL: http://127.0.0.1:54321/graphql/v1
  S3 Storage URL: http://127.0.0.1:54321/storage/v1/s3
          DB URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres
      Studio URL: http://127.0.0.1:54323
    Inbucket URL: http://127.0.0.1:54324
      JWT secret: super-secret-jwt-token-with-at-least-32-characters-long
        anon key: eiJhbGciOuJIUzI1AiIsInR5cEJ6IknDHWJ5.eyJpc3MiOiJzdGBhYmFzZS1kZW1vIiwicm9sZSI3ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0
service_role key: eyJhbGciOiJKOzI1NiIsInR5cCI6IkpXKAQ5.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp8fsn3W0YpN81IU
   S3 Access Key: 625729a08b95bf1b7ff351a663f3a23d
   S3 Secret Key: 850181e4652cc023b7a98c58ae0d2d34bd487ee0cc1257aed6eda37307425907
       S3 Region: local

以下URLにアクセスすると、ブラウザが立ち上がり、実際のポータルサイトと同じような画面が表示されます。

Studio URL: http://127.0.0.1:54323

これで準備は完了しましたので、この後テーブル作成に進みます。

ローカル開発実施

作業のゴールは、
ローカルで作業したスキーマをリモート(実際)のプロジェクトに反映することです。

公式ドキュメント

テーブル作成とデータ投入

1つ前のセクションで記載した、http://127.0.0.1:54323にアクセスします。
左側のメニューから、SQL Editorを選択します。

このエディタ上でSQLを実行して、データを投入します。

image.png

今回は、以下2つのテーブルを作成しました。

  • 店舗情報テーブル
  • 都道府県一覧テーブル(店舗情報テーブルで使用)

image.png

image.png

テーブル定義とデータ管理

実行したSQLについて、今後ローカル開発をする際に再利用できる方が後々楽です。
Seedingという概念です。(以降この単語を使います。)

config.tomlファイルと同階層のseed.sqlファイルを使って、データ投入のためのSQLを残しておきましょう。

ちなみにファイル名は、seed.sqlの必要はありません。config.tomlファイルに、Seedingに関するセクションが存在します。
どのファイルをSeedingに利用するか、カスタマイズ可能です。

以下は、公式ドキュメントからの引用です。

[db.seed]
enabled = true
sql_paths = ['./countries.sql', './cities.sql']

この対応により、npx supabase start実行時に、
記載内容に沿ってSeedingを行ってくれます。

Docker Volumeへの保存
npx supabase stopでコンテナ停止時、ターミナルに以下内容が表示されます。(xxxxx:作成フォルダ名)

Stopped supabase local development setup.
Local data are backed up to docker volume. Use docker to show them: docker volume ls --filter label=com.supabase.cli.project=xxxxx

Docker Volumeにデータを保存してくれます。

環境の再構築

npx supabase start実行時に、データ投入を行ってくれます。

一度環境を構築している場合、
Seedingの内容を適用するためには、npx supabase db resetで環境のリセットが必要です。

コマンドを実行すると、以下の通りターミナルに表示されます。「再構築」という単語が近いと思います。
スキーマの初期化・テーブル再作成・Seedingを実施してくれます。
慣れてくると、ありがたいことを実感できる仕組み(コマンド)です。

$ npx supabase db reset
Resetting local database...
Recreating database...
Initialising schema...
Seeding globals from roles.sql...
Applying migration 20250301062014_create_stores_table.sql...
NOTICE (42P06): schema "supabase_migrations" already exists, skipping
Seeding data from supabase/seed.sql...
Restarting containers...
Finished supabase db reset on branch main.

アプリケーションの動作確認

言語によって異なる部分はありますが、
インスタンス定義とテーブル呼び出し部分の実装を記載します。言語はDartですが、言語によって差分が大きく表れる箇所ではないです。

Supabase Clientのインスタンス初期化のパラメータとして、urlanonKeyを設定します。
(先ほど共有した、ターミナルの出力情報を利用)

  • urlhttp://127.0.0.1:54321(API URLの値)
  • anonKeyeiJhbGciOuJIUzI1AiIsInR5cEJ6IknDHWJ5...(冒頭のみ記載)

インスタンス作成

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Supabase.initialize(url: AppConstants.supabaseUrl, 
  anonKey: AppConstants.supabaseAnonKey);
}

データ取得の実装

final SupabaseClient supabase = Supabase.instance.client;
final response = await supabase.from('stores').select();
    print(response);

URLとKeyが正しく設定できていれば、ローカルで作成したテーブルのデータを取得することができます。

ホスト番号の設定
これはFlutter特有(Swiftも該当するかもしれません)の話だと思いますが、
実機で確認する場合、127.0.0.1では接続ができません。接続しているWifiのIPアドレスに置き換えたURLを設定する必要があります。

マイグレーションファイル作成

ここから、リモートに反映するための準備に入ります。

npx supabase db diff --use-migra -f {create_stores_table}

上記コマンドは、既に作成済のマイグレーションファイルと現在のDB状況の差分を元にしてマイグレーションファイルを生成します。
{create_stores_table}はマイグレーション内容が判断できる文字列を記載します。

ファイル20250301062014_create_stores_table.sqlのように、
yyyyMMddhhmmss_マイグレーション内容.sqlが、migrations`フォルダに作成されれば成功です。

実際のプロジェクトへのデプロイ

ローカルの作業を通して、テーブル定義に問題がなさそう!と確認できたら、デプロイ作業に進みます。
ここでsupabaseへのログインを行います。

npx supabase login

Enterを押すと、ブラウザが起動します。
表示された認証コードをコピーし、ターミナルに貼り付けます。

image.png
image.png

続いて、紐づけるプロジェクトをIDを設定します。

supabase link --project-ref {project_id}

ここでローカルとリモートの設定差分が表示されます。DBとは直接関係しない差分も表示されます。
今回はDBに関する更新を行うので、関係ない箇所は気にせず進めます。

以下コマンドで、DBに関する差分は確認できます。

npx supabase db diff

予期せぬ設定の反映を防ぐために
今回は私(開発者)自身の環境なので、予期せぬ変更があっても問題はないです。差分も1つひとつ丁寧には確認していません。

しかし実際のプロジェクトでは、差分が後々影響するかもしれないので、差分が把握できる状態(元に戻せる状態)は用意いただければと思います。

最後にDBのデプロイを実行します。

npx supabase db push

データベースのパスワードを求められるので、入力してください。
入力後、マイグレーションをリモートに反映してよいか聞かれるので、OKであれば、Yを入力します。

image.png

これでターミナルを用いた作業は終了です。

結果確認

実際のプロジェクトの状態を、ブラウザで確認してみます。

URLを見ていただくと分かりますが、
ローカル環境ではなく、実際のプロジェクトが表示されています。

image.png

image.png

ローカルで作成したテーブルと同じ情報が表示できていることを確認できました。

これで最初に記載したゴールまで到達できました!

コマンド実行を楽にしたい

これは余談になりますが、
毎回npx supabase start入力は面倒なので、コマンドをカスタマイズしたくなりました。

package.json(作成フォルダと同階層)にscriptsセクションを追加しました。

{
  "devDependencies": {
    "supabase": "^2.15.8"
  },
  "scripts": {
    "start": "supabase start",
    "stop": "supabase stop",
    "login": "supabase login",
    "link": "supabase link --project-ref",
    "db:diff": "supabase db diff",
    "db:diff:name": "supabase db diff --use-migra -f",
    "db:push": "supabase db push",
    "db:reset": "supabase db reset"
  }
}

これで以下のようにコマンド実行ができます。

startしたい場合

npm run start

マイグレーションを作成したい場合(引数を渡す)

npm run db:diff:name -- create_stores_table

まとめ

久しぶりにローカルでSupabaseのDBを利用して開発をしてみました。
冒頭だと発生したエラー以外、大きく躓くことなく進んでよかったです。

以前記事を書いたとき、Supabaseとセットで利用していたのは、Next.jsだったと思います。
今回はFlutterで、NextjsのときよりもUIの微調整などでDBにアクセスする回数が多いと感じていたので、ローカルの環境構築をしておいてよかったと、改めて思いました。

この後、StorageやFunctionの機能も確認ができればと考えています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?