👀

Supabaseのローカル開発環境構築

2022/01/13に公開約8,400字1件のコメント

Supabaseのローカル開発環境を構築するメモ。プロジェクト開始時にやっておきたい。

前置き

Supabaseは彼らの本番環境と同じ環境をローカルにDockerで構築できる仕組みを提供している。これをローカルで立ち上げるとStudioと呼ばれるGUI(本番と同じもの)が利用できるようになる。しかしStudioから操作できるのはPostgreSQLに関するもの(DatabaseやTable/SQL Editorなど)だけである。本番では提供されているStorageやAuthやSettingsに関してローカルのStudioには表示されない。roadmapには載ってるらしいがまだ提供されていない。

Supabaseプロジェクト作成

Introduction | Supabaseを参考にSupabaseにプロジェクトを作成する。GitHubログインしてとりあえず適当なプロジェクトを作るだけで良い。あとからいくらでも変更できる。

ローカル環境構築

以下すでにNext.jsやNuxt.jsなどでinitしてプロジェクト作成は終わっているものとし、cd your-app-projectしている前提で進める。基本はLocal Development | Supabaseに則って進めるとよい。

CLIのインストール

まずはSupabaseのCLIをインストールする。自分はMac環境なのでbrew instal supabase/tap/supabaseで入れた。

Supabaseを使う準備

アプリのルートディレクトリでsupabase initをする。

 $ supabase init

するとsupabase/ディレクトリが生成される。中身はsupabase/migrationssupabase/config.toml。名前の通りmigrationファイルとSupabaseの設定記すファイル。

[必要なら]リモートDBとローカルDBをリンクする

リモートDB(最初に作ったSupabase内のプロジェクトのやつ)とローカルDBをリンクするとリモート環境のDBのスキーマをローカルにシンクできる。またローカルからリモート側にmigrationをpushすることもできるようになる。cli/examples/tour at main · supabase/cliを参考に進めると良い。

まずはremoteのDB情報をローカルに設定する。するとsupabase/配下に.envができるはず。.gitignoreに入れておくこと。

 $ supabase db remote set 'postgresql://postgres:<YOUR_DB_PASSWORD>@db.<YOUR_PROJECT_REF>.supabase.co:5432/postgres'

そして下記コマンドを叩く。するとremote DBからローカルにスキーマ情報を持って来ることができる。supabase/migration配下にsqlファイルが生成されるはず。

 $ supabase db remote commit

Supabaseの立ち上げ

Supabaseのローカル環境を立ち上げてみる。

 $ supabase start
 Started local development setup.

          API URL: http://localhost:54321
           DB URL: postgresql://postgres:postgres@localhost:54322/postgres
       Studio URL: http://localhost:54323
         anon key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiJ9.ZopqoUt20nEV9cklpv9e3yw3PVyZLmKs5qLD6nGL1SI
 service_role key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoic2VydmljZV9yb2xlIn0.M2d2z4SFn5C7HlJlaSLfrzuYim9nbY_XI40uWFN3hEE

このコマンドでSupabase環境に必要な諸々がDockerでインストールされて立ち上がる。初回のセットアップに5分くらいかかる。終わるとローカル用のURLやAPI Keyなどが生成される。keyの値は固定値っぽいので.env.localなどに一度登録しておけば良さそう。

http://localhost:54323/にアクセスするとSupabaseの見慣れたDashboardページが表示される。

※supabase startでエラーが出る場合

おそらくsupabase db remote commitでremote DBのスキーマを持ってきた場合、そのSQL文の実行順序がおかしい可能性がある。このコマンドで生成されるSQL文はDBの現在の状態のスキーマに過ぎないので、例えばtagsというテーブルを作成し、その後にarticlesというテーブルを作成し、tagsからarticlesへ外部キーを設定するみたいな操作をリモート側のGUIでしていた場合。生成されるSQL文は上から順にtagsとtagsの外部キー制約のSQL、次にarticles のSQLみたいな感じになる。ただこの場合articlesがまだ作成されていないのにも関わらず、tagsの外部キーの生成のSQL文内でarticlesへの参照が発生してしまう。よってエラーになる。SQL文で表すとこんな感じになってしまっている。これは手動で直すしかない....

init.sql
 CREATE TABLE IF NOT EXISTS public.tags
 (
   id uuid NOT NULL,
   article_id bigint NOT NULL,
   CONSTRAINT tags_article_id_fkey FOREIGN KEY (article_id)
           REFERENCES public.articles (id) MATCH SIMPLE  <- まだarticlesは作成されてない!!
           ON UPDATE NO ACTION
           ON DELETE NO ACTION,
 )

 CREATE TABLE IF NOT EXISTS public.articles
 (
 ....

その後の流れ

ローカルでDBのスキーマ変更をした場合、下記コマンドを叩くことでmigraitonファイルが生成される。自前でSQL文を書かなくて良い。GUIからのテーブル変更をコマンド側でいい感じにやってくれる。

 $ supabase db commit <migration_file_prefix_name>

良きタイミングで下記コマンドを実行することで本番DBにも反映させられる。

 $ supabase db push

その他

初期データ

初期データに関しては下記のような感じでsupabase/seed.sqlを作っておくとsupabase start時に毎回実行してくれる。

supabase/seed.sql
 -- in supabase/seed.sql
 INSERT INTO boarders(id, name) VALUES (1, 'Arthur Dent'), (2, 'Ford Prefect');

リセット

下記でローカルDBのリセットができる。migrationを0からやり直したい場合とかに便利。

 $ supabase db reset

その他のコマンドに関しては下記リンクを参照すると良い。
supabase help | Supabase

JSのクライアント

どうせ使うと思うのでJavascript用のクライアントのインストールもやっておくと良い。

 $ npm install --save @supabase/supabase-js

テーブルの型情報の生成

openapi-typescriptを入れてschema情報から型を生成する。camelCase to sneakCaseとかも下記のリンクの通りでok

ローカルとリモートのマイグレーションがズレた場合

ローカルのマイグレーションファイルをいじったりしてると誤ってリモートのマイグレーションと合わなくなることがある。この場合はローカルのマイグレーションファイルを削除して、リモートのsupabase_migrations.schema_migrationsのレコードを全てdelete from supabase_migrations.schema_migrations;で削除し、supabase db remote commitでリモートDBとローカルDBをリンクし直すのが早い。一応supabase_migrations.schema_migrationsのレコードをちまちまと消してローカルと合わせるでも良いけど。

ローカルでもサードパーティのOAuthプロバイダーのAuthenticationを使いたい

追記: 2022/3/2

この問題に関して送っていたPRを見てくれた中の人が根本的な解決をしてくれた。具体的にはsupabase initをするとconfig.tomlを生成するようになり、その中でExternal auth providersを設定できるようになった。これを使うとローカルでもサードパーティのOAuthプロバイダーが使えるようになる。

https://github.com/supabase/cli/pull/172

このアップデートにより以下の記述はもう不要です。

古い内容

ちなみにこれが正解のやり方なのかはわからんけど、現状ローカル環境でもサードパーティのOAuthプロバイダーのAuthentication機能をCLIで使いたい場合は結構イレギュラーなやり方が必要でsupabase/cli: Supabase CLIinternal/start/start.goのGoTrueの設定に渡している環境変数に好きなものを追加してgo buildをすることでなんとかするという方法がある。

SupabaseのAuthenticationを担うGoTrueというコードのgotrue/example.env at master · supabase/gotrueを見ればどんなの環境変数が追加できるかわかるので適宜参考にするとよい。一例としては下記の流れ。コード内にコメントを書いた。

 // 適当な場所へ
 $ cd /Users/hoge/dev

 // supabase-cliのダウンロード
 $ git clone git@github.com:supabase/cli.git
 $ cd cli/

 // ソースコードの書き換え
 $ vim internal/start/start.go
 ...
 env := []string{
 	"API_EXTERNAL_URL=http://localhost:" + utils.ApiPort,

 	"GOTRUE_API_HOST=0.0.0.0",
 	"GOTRUE_API_PORT=9999",

 	"GOTRUE_DB_DRIVER=postgres",
 	"GOTRUE_DB_DATABASE_URL=postgresql://supabase_auth_admin:postgres@" + utils.DbId + ":5432/postgres",

 	"GOTRUE_SITE_URL=http://localhost:3000",
 	"GOTRUE_DISABLE_SIGNUP=false",

 	"GOTRUE_JWT_SECRET=super-secret-jwt-token-with-at-least-32-characters-long",
 	"GOTRUE_JWT_EXP=3600",
 	"GOTRUE_JWT_DEFAULT_GROUP_NAME=authenticated",

 	"GOTRUE_EXTERNAL_EMAIL_ENABLED=true",

 	"GOTRUE_EXTERNAL_PHONE_ENABLED=true",
 	"GOTRUE_SMS_AUTOCONFIRM=true",

 	// Custom settings for Google OAuth2. 
	// ここにFACEBOOKとかTWITTERとかサードパーティの情報を追加すればなんでもいける。
 	"GOTRUE_EXTERNAL_GOOGLE_ENABLED: 'true'",
	"GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID: XXXXXXXXXX.apps.googleusercontent.com",
	"GOTRUE_EXTERNAL_GOOGLE_SECRET: XXXXX-XXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
	"GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI=http://localhost:3000/auth/v1/callback",
	"GOTRUE_EXTERNAL_URI=https://accounts.google.com"
 }
....

// これはMacOSの場合のビルド。Windowsの場合などはGOOSとGOARCHの部分を変える。
// ビルドで生成されるコマンド名をsupabaseという名前にすると本家のcliと競合しそうなので適当にtupabaseという名前にしてる。
$ GOOS=darwin GOARCH=amd64 go build -o build/tupabase .

// supabaseを使いたいプロジェクトのルートへ移動
$ cd /Users/hoge/dev/my-project

// supabaseのコマンドが実行できるはず。もしエラーになる場合はsupabase/.branchesとかsuapabase/.tempを削除してからやりなおすと良い
$ /Users/hoge/dev/cli/build/tupabase init
$ /Users/hoge/dev/cli/build/tupabase start

あとは生成した/Users/hoge/dev/cli/build/tupabaseについてはPATHを通すなり自由にする。

https://scrapbox.io/files/61e00ad85a5677001f95c049.png
それとOAuthのPROVIDERのサイト側(GoogleならGCPのOAuthクライアントの設定画面など)でredirect or callback urlとして登録するURLにはhttp://localhost:54321/auth/v1/callbackを設定するのを忘れず。

CLIがローカルに展開するSupabaseではデフォルトでAPIがhttp://localhost:54321でDBがhttp://localhost:54322でStudioがhttp://localhost:54323である。そのほかに自分のフロントエンドがおそらく多くはhttp://localhost:3000。ちなみに認証して/auth/v1/callbackにredirectしたのち戻ってくるのはデフォルトではhttp://localhost:3000。これはGoTrueでGOTRUE_SITE_URL=http://localhost:3000が設定されているためである。

Link

Discussion

(このコメントは投稿主及びこの記事に辿った人への参考情報。)

supabase を始めてみようとこのページに辿りました。
そんな古くない投稿なのに、なぜか example/tour へのリンク切れが発生しています。

調べてみたら、ちょうど19日前に、supabase 側が色々と更新をかけていました。

https://github.com/supabase/cli/commit/273f2668bb518df607ef5bf180e4af0d1f120655

上記の情報によると、example/tour だったものは、以下の公式ガイドに移ったそうです。

https://supabase.com/docs/guides/local-development
ログインするとコメントできます