# Supabase CLIの使い方
Supabase CLIを使ってローカル環境で開発する際のメモ。インターネット接続なしで開発でき、データベースの変更を安全にテストできる。
# インストール
# macOS/Linux
# Homebrewを使用(推奨)
brew install supabase/tap/supabase
# npmを使用
npm install -g supabase
# または、npxで直接実行
npx supabase --version
# Windows
# Scoopを使用
scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
scoop install supabase
# npmを使用
npm install -g supabase
# Dockerのインストール
Supabase CLIはDockerを使用するため、Docker Desktopが必要。
インストール後、Dockerが起動していることを確認:
docker --version
docker ps
# プロジェクトの初期化
supabase init
# 以下のディレクトリ構造が作成される:
# supabase/
# ├── config.toml # Supabase設定ファイル
# ├── migrations/ # データベースマイグレーションファイル
# ├── seed.sql # シードデータ(オプション)
# └── functions/ # エッジ関数(オプション)
# ローカル環境の起動と停止
# 起動
supabase start
# 起動後、以下の情報が表示される:
# API URL: http://localhost:54321
# GraphQL URL: http://localhost:54321/graphql/v1
# DB URL: postgresql://postgres:postgres@localhost:54322/postgres
# Studio URL: http://localhost:54323
# Inbucket URL: http://localhost:54324
# JWT secret: your-jwt-secret
# anon key: your-anon-key
# service_role key: your-service-role-key
初回起動
初回起動時は、Dockerイメージのダウンロードとコンテナの起動に数分かかる。2回目以降は数秒で起動する。
# ステータスの確認
supabase status
# 停止
supabase stop
# 再起動
supabase start
# データは保持されたまま再起動される
# 完全削除
# ローカル環境を完全に削除(データも含む)
supabase stop --no-backup
# または、Dockerコンテナを直接削除
docker stop supabase_db_local
docker rm supabase_db_local
# ローカル環境の設定
# 環境変数の設定
supabase startで表示されたURLとキーを環境変数に設定。
# .env.local
NEXT_PUBLIC_SUPABASE_URL=http://localhost:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-local-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-local-service-role-key
# Supabase Studio(ローカル)
ローカル環境のSupabase Studioにアクセス:
http://localhost:54323
ローカルのSupabase Studioでは、テーブルの作成・編集、SQLエディタでのクエリ実行、認証ユーザーの管理などが可能。
# データベースマイグレーション
# マイグレーションファイルの作成
supabase migration new create_posts_table
# supabase/migrations/YYYYMMDDHHMMSS_create_posts_table.sql が作成される
命名規則:
supabase migration new create_posts_table
supabase migration new add_user_email_index
supabase migration new update_posts_rls_policy
supabase migration new drop_old_columns
# マイグレーションファイルの編集
-- supabase/migrations/YYYYMMDDHHMMSS_create_posts_table.sql
CREATE TABLE posts (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
title TEXT NOT NULL,
content TEXT,
user_id UUID REFERENCES auth.users(id),
created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc'::text, NOW()) NOT NULL
);
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
CREATE POLICY "誰でも読み取り可能" ON posts
FOR SELECT USING (true);
CREATE POLICY "認証済みユーザーのみ書き込み可能" ON posts
FOR INSERT WITH CHECK (auth.role() = 'authenticated');
# マイグレーションの適用
# データベースをリセットしてマイグレーションを適用
supabase db reset
# または、新しいマイグレーションのみ適用
supabase migration up
データのリセット
supabase db resetは、データベースを完全にリセットし、すべてのマイグレーションを再適用する。ローカルのデータはすべて削除される。
# マイグレーションの状態確認
supabase migration list
# 出力例:
# 20240101000000_create_posts_table (applied)
# 20240102000000_add_user_email_index (applied)
# 20240103000000_update_posts_rls_policy (pending)
# マイグレーションのロールバック
# 最後に適用したマイグレーションをロールバック
supabase migration down
# 特定のマイグレーションまでロールバック
supabase migration down --target 20240101000000
# リモートプロジェクトとの連携
# リモートプロジェクトとのリンク
supabase link --project-ref your-project-ref
# プロジェクト参照IDは、SupabaseダッシュボードのURLから取得
# https://app.supabase.com/project/your-project-ref
リンク後、supabase/config.tomlにプロジェクトIDが保存される。
# リモートへのマイグレーションのプッシュ
supabase db push
本番環境への適用
supabase db pushは本番環境にも影響する可能性がある。本番環境に適用する前に、必ずステージング環境でテストする。
# リモートからのマイグレーションのプル
supabase db pull
# リモートからのスキーマの差分取得
# リモートとローカルのスキーマの差分を確認
supabase db diff
# 差分をマイグレーションファイルとして生成
supabase db diff -f migration_name
# 型定義の生成
# ローカル環境から型定義を生成
supabase gen types typescript --local > types/supabase.ts
# リモートプロジェクトから型定義を生成
supabase gen types typescript --project-id your-project-id > types/supabase.ts
# または、リンク済みのプロジェクトから生成
supabase gen types typescript --linked > types/supabase.ts
# 生成された型定義の使用例
import { Database } from './types/supabase'
import { createClient } from '@supabase/supabase-js'
const supabase = createClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
// 型安全なクエリ
const { data } = await supabase
.from('posts')
.select('*')
# シードデータの投入
# seed.sqlの作成
-- supabase/seed.sql
INSERT INTO posts (title, content, user_id)
VALUES
('最初の投稿', 'これはテスト投稿です', '00000000-0000-0000-0000-000000000000'),
('2番目の投稿', 'これもテスト投稿です', '00000000-0000-0000-0000-000000000000');
# シードデータの投入
# シードデータを投入
supabase db reset
# db resetは、マイグレーションの適用後に自動的にseed.sqlを実行する
# シードデータの手動実行
# シードデータのみ実行(マイグレーションは適用しない)
supabase db seed
# よく使うCLIコマンド一覧
# プロジェクト管理
supabase init
supabase status
supabase logs
# ローカル環境の管理
supabase start
supabase stop
# データベース操作
supabase db reset
supabase migration new migration_name
supabase migration up
supabase migration down
supabase migration list
supabase db seed
# リモートとの連携
supabase link --project-ref your-project-ref
supabase db push
supabase db pull
supabase db diff
# 型定義の生成
supabase gen types typescript --local > types/supabase.ts
supabase gen types typescript --project-id your-project-id > types/supabase.ts
supabase gen types typescript --linked > types/supabase.ts
# ローカル開発のワークフロー
プロジェクトの初期化
supabase initローカル環境の起動
supabase startマイグレーションファイルの作成
supabase migration new create_posts_tableマイグレーションファイルの編集
supabase/migrations/ディレクトリ内のSQLファイルを編集
マイグレーションの適用
supabase db reset型定義の生成
supabase gen types typescript --local > types/supabase.ts開発とテスト
- ローカル環境でアプリケーションを開発・テスト
リモートへの反映(準備ができたら)
supabase link --project-ref your-project-ref supabase db push
# 実装時の注意点
# マイグレーションファイルの命名規則
明確で説明的な名前を付ける。
# 良い例
supabase migration new create_posts_table
supabase migration new add_user_email_index
# 悪い例
supabase migration new migration1
supabase migration new update
# マイグレーションファイルの管理
マイグレーションファイルは必ずGitで管理する。
# .gitignoreに追加しない
# supabase/migrations/ は必ずコミットする
# マイグレーションの順序
マイグレーションは時系列順に適用されるため、依存関係を考慮する。
# 1. テーブル作成
supabase migration new create_posts_table
# 2. インデックス追加
supabase migration new add_posts_indexes
# 3. RLSポリシー追加
supabase migration new add_posts_rls_policies
# 型定義の自動生成
スキーマ変更後は、必ず型定義を再生成する。
supabase db reset
supabase gen types typescript --local > types/supabase.ts
# 環境変数の管理
開発環境と本番環境で異なる環境変数を使用する。
# 開発環境の設定
# .env.local
NEXT_PUBLIC_SUPABASE_URL=http://localhost:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-local-anon-key
# 本番環境の設定
# .env.production
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-production-anon-key
# よくあるエラーと対処法
# ローカル環境が起動しない
エラー: Error: failed to start: Docker is not running
原因: Docker Desktopが起動していない、またはDockerがインストールされていない
対処:
- Docker Desktopを起動
- Dockerがインストールされているか確認:
docker --version - Docker Desktopの設定で、リソースが十分に割り当てられているか確認
# ポートが既に使用されている
エラー: Error: port 54321 is already in use
原因: 既にSupabaseのローカル環境が起動している、または他のアプリケーションがポートを使用している
対処:
# 既存のSupabase環境を停止
supabase stop
# または、使用中のポートを確認
lsof -i :54321
# プロセスを終了
kill -9 <PID>
# マイグレーションが適用されない
原因: マイグレーションファイルに構文エラーがある、またはマイグレーションの順序が正しくない
対処:
# マイグレーションの状態を確認
supabase migration list
# データベースをリセットして再適用
supabase db reset
# マイグレーションファイルの構文を確認
# SQLエディタで実行してエラーを確認
# ローカル環境とリモート環境の不一致
原因: ローカルとリモートで異なるマイグレーションが適用されている
対処:
# リモートのマイグレーションをローカルに取得
supabase db pull
# または、ローカルのマイグレーションをリモートに適用
supabase link --project-ref your-project-ref
supabase db push
データの同期
supabase db pushはリモートのデータベースを変更する。本番環境に適用する前に、必ずバックアップを取得し、ステージング環境でテストする。
# 型定義が更新されない
原因: スキーマ変更後に型定義を再生成していない
対処:
# マイグレーションを適用後、型定義を再生成
supabase db reset
supabase gen types typescript --local > types/supabase.ts
# Dockerコンテナが起動しない
原因: Dockerのリソース不足、またはイメージの破損
対処:
# Dockerのリソースを確認
docker system df
# 不要なイメージやコンテナを削除
docker system prune -a
# Supabaseのイメージを再ダウンロード
supabase stop
supabase start