Supabase CLI 使い方完全ガイド (2026年)

Ashley Innocent

Ashley Innocent

24 3月 2026

Supabase CLI 使い方完全ガイド (2026年)

Apidog エンタープライズ

オンプレミスデプロイ

SSO & RBAC

SOC 2 準拠

Apidog Enterpriseを見る

要約 (TL;DR)

Supabase CLIは、Dockerを使用してPostgreSQL、Auth、Storage、Edge FunctionsといったSupabaseのフルスタックをあなたのマシン上で実行します。brew install supabase/tap/supabaseでインストールし、supabase initsupabase startを実行してローカル環境を立ち上げ、supabase db pushsupabase functions deployを使用して本番環境にデプロイします。これは、クラウドに触れることなくSupabaseのバックエンドを構築・テストする最速の方法です。

はじめに

開発者がローカルテストをスキップするため、バックエンドのバグの73%が本番環境で発見されます。Supabase CLIを使えば、もはやそれは言い訳になりません。5分以内に本番環境と同等の環境をマシン上で完全に実行できます。

ここに本当の問題があります。ほとんどの開発者は、直接本番環境でテストするか(危険)、クラウドと完全に一致しないローカル環境の設定に何時間も費やす(イライラする)かのどちらかです。Supabase CLIはこれら両方を解決します。本番環境を正確にミラーリングするDockerベースのローカルスタックを提供するため、ローカルで動作するものは本番環境でも動作します。

💡
Supabase上にAPIを構築する場合、APIエンドポイントを設計、テスト、ドキュメント化するためのツールが必要になります。ApidogはSupabaseのRESTおよびGraphQL APIに直接接続し、ローカルでバックエンドを構築しながらテストを行うことができます。
ボタン

ApidogでSupabase APIをテスト - 無料

このガイドを読み終えるまでに、次のことができるようになります。

CLIなしではローカルSupabase開発が破綻する理由

SupabaseアプリをCLIなしで構築しようとしたことがあるなら、その苦痛を知っているでしょう。ここでは、常に発生する3つのシナリオを紹介します。

「本番環境でテスト」という罠。 Supabaseダッシュボードで直接スキーマ変更を行います。それは動作します。フロントエンドをプッシュします。3日後、チームメイトがリポジトリをプルすると、データベースに新しいカラムがないため、彼らのアプリは壊れます。

環境の不一致。 ローカルのPostgreSQLインスタンスをセットアップし、手動でSupabaseスキーマを再作成し、Row Level Securityポリシーがローカルで異なる動作をする理由をデバッグするのに2時間費やします。実際には異なりません。ポリシーを1つ見落としていただけです。

「私のマシンでは動く」という問題。 Edge FunctionはSupabaseダッシュボードエディタでは動作しますが、実際の環境変数ではなくハードコードされた値でテストしたため、本番環境では失敗します。

これらは特殊なケースではありません。スキーマのずれ(ローカルデータベースとリモートデータベースの同期のずれ)は、Supabaseを使用するチームにとって最も報告される問題です。CLIはこれら3つの問題をすべて解決します。

Supabase CLIの仕組み

ローカルスタック

supabase startを実行すると、CLIは以下のサービスを含むDocker Composeスタックを起動します。

サービス ポート 目的
PostgreSQL 54322 データベース
PostgREST 54321 自動生成されたREST API
GoTrue 54321/auth 認証サービス
Realtime 54321/realtime WebSocketサブスクリプション
Storage 54321/storage ファイルストレージ
Studio 54323 ビジュアルダッシュボード
Inbucket 54324 Eメールテスト (ローカルで全てのEメールをキャッチ)
Edge Runtime 54321/functions Denoベースの関数ランナー

これはSupabase Cloudで実行されているのと同じスタックです。あなたのマシン上で。

インストール

macOS:

brew install supabase/tap/supabase

Windows (Scoop):

scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
scoop install supabase

Linux / npm:

npm install -g supabase

動作確認:

supabase --version
# supabase 1.x.x
supabase start

プロジェクトのセットアップ

mkdir my-project && cd my-project
supabase init

これにより、以下が作成されます。

supabase/
├── config.toml       # ポート、認証設定、ストレージ設定
├── seed.sql          # データベースリセットのたびにロードされる開発データ
└── migrations/       # スキーマのバージョン履歴

ローカルスタックの起動

supabase start

初回実行時には約1GBのDockerイメージがダウンロードされます。それ以降は、起動に約10秒かかります。

API URL: http://localhost:54321
DB URL:  postgresql://postgres:postgres@localhost:54322/postgres
Studio:  http://localhost:54323
anon key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

anon key.env.localファイルにコピーしてください。これはフロントエンドに必要です。

マイグレーションによるデータベース管理

マイグレーションはCLIワークフローの核です。すべてのスキーマ変更は、Gitで追跡されるバージョン管理されたSQLファイルになります。「誰がいつデータベースを変更したのか」という問題はもうありません。

最初のマイグレーションの作成

supabase migration new create_posts_table
# 作成されるファイル: supabase/migrations/20260324120000_create_posts_table.sql

ファイルを編集:

-- RLS付きのpostsテーブルを作成
CREATE TABLE posts (
  id          UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id     UUID REFERENCES auth.users(id) ON DELETE CASCADE NOT NULL,
  title       TEXT NOT NULL,
  content     TEXT,
  published   BOOLEAN DEFAULT false,
  created_at  TIMESTAMPTZ DEFAULT NOW(),
  updated_at  TIMESTAMPTZ DEFAULT NOW()
);

-- 行レベルセキュリティを有効にする
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;

-- 誰でも公開された投稿を読める
CREATE POLICY "Anyone can read published posts"
  ON posts FOR SELECT
  USING (published = true);

-- ユーザーは自分の投稿を管理する
CREATE POLICY "Users manage own posts"
  ON posts FOR ALL
  USING (auth.uid() = user_id);

-- 変更ごとにupdated_atを自動更新
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER posts_updated_at
  BEFORE UPDATE ON posts
  FOR EACH ROW EXECUTE FUNCTION update_updated_at();

適用:

supabase migration up

TypeScript型の生成

スキーマ変更ごとに、型を再生成します。

supabase gen types typescript --local > src/types/database.ts

フロントエンドは完全な型安全性を得られます。

import { Database } from '@/types/database'

type Post = Database['public']['Tables']['posts']['Row']
type NewPost = Database['public']['Tables']['posts']['Insert']

// これで、ランタイム前にエディターが型エラーをキャッチします
const createPost = async (post: NewPost) => {
  const { data, error } = await supabase
    .from('posts')
    .insert(post)
    .select()
    .single()
  return data
}

開発データのシーディング

supabase/seed.sqlを編集:

-- テストユーザー (ローカル開発のために認証をバイパス)
INSERT INTO auth.users (id, email) VALUES
  ('00000000-0000-0000-0000-000000000001', 'alice@example.com'),
  ('00000000-0000-0000-0000-000000000002', 'bob@example.com');

-- テスト投稿
INSERT INTO posts (user_id, title, content, published) VALUES
  ('00000000-0000-0000-0000-000000000001', 'Supabase入門', '学んだことを紹介...', true),
  ('00000000-0000-0000-0000-000000000002', '下書き: API設計パターン', '作業中...', false);

いつでもリセットして再シーディング:

supabase db reset

これにより、すべてが削除され、すべてのマイグレーションが再実行され、シードデータがロードされます。毎日実行して、クリーンな状態から開始しましょう。

ApidogでSupabase APIをテストする

ローカルのSupabaseが起動すると、http://localhost:54321で完全に機能するREST APIが利用可能になります。Supabaseは、PostgRESTを介してすべてのテーブルのエンドポイントを自動生成します。これらをcurlで手動でテストするのは、特に異なるユーザートークンでRLSポリシーをテストする必要がある場合、すぐに面倒になります。

ApidogはローカルのSupabaseインスタンスに直接接続します。次のことができます。

ApidogをローカルSupabaseで設定する:

  1. Apidogで新しいプロジェクトを作成
  2. ベースURLを設定: http://localhost:54321
  3. 環境変数を追加: anon_key = your-local-anon-key
  4. 認証ヘッダーを追加: Bearer {{anon_key}}

投稿エンドポイントのテスト:

GET http://localhost:54321/rest/v1/posts?published=eq.true
Authorization: Bearer {{anon_key}}
apikey: {{anon_key}}

これをリクエストとして保存し、応答に少なくとも1つの投稿が含まれているというアサーションを追加し、RLSポリシーを変更するたびに実行してください。これにより、本番環境に到達する前に、壊れたポリシーを検出できます。

ApidogでSupabase APIのテストを開始 - 無料

Edge Functions: ローカルでの構築とテスト

Edge FunctionsはDeno上で、ユーザーに近いエッジで実行されます。Webhooks、バックグラウンドジョブ、サーバーサイドロジックが必要なAPIエンドポイントに最適です。

関数の作成

supabase functions new send-welcome-email

これにより、supabase/functions/send-welcome-email/index.tsが作成されます。

import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'

serve(async (req) => {
  const { user_id } = await req.json()

  // サービスロールはRLSをバイパスします - 慎重に使用してください
  const supabase = createClient(
    Deno.env.get('SUPABASE_URL')!,
    Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
  )

  const { data: profile } = await supabase
    .from('profiles')
    .select('email, full_name')
    .eq('id', user_id)
    .single()

  // ここにEメール送信ロジックを記述します
  console.log(`Sending welcome email to ${profile?.email}`)

  return new Response(
    JSON.stringify({ success: true }),
    { headers: { 'Content-Type': 'application/json' } }
  )
})

ホットリロードでローカルテスト

supabase functions serve

関数サーバーはファイルの変更を監視し、自動的にリロードします。テストするには:

curl -X POST http://localhost:54321/functions/v1/send-welcome-email \
  -H "Authorization: Bearer YOUR_ANON_KEY" \
  -H "Content-Type: application/json" \
  -d '{"user_id": "00000000-0000-0000-0000-000000000001"}'

本番環境へのデプロイ

# 一つの関数をデプロイ
supabase functions deploy send-welcome-email

# 全ての関数をデプロイ
supabase functions deploy

高度なテクニックと実績のあるアプローチ

シークレット管理

APIキーを関数にハードコードしないでください。シークレットを使用します。

# 本番環境のシークレットを設定
supabase secrets set RESEND_API_KEY=re_xxx STRIPE_KEY=sk_live_xxx

# 全てのシークレットを一覧表示
supabase secrets list

# シークレットを削除
supabase secrets unset STRIPE_KEY

関数内でそれらにアクセスします。

const resendKey = Deno.env.get('RESEND_API_KEY')
// 決してこのようにしてはいけません: const resendKey = 're_xxx'

データベースのブランチング

大規模なスキーマ変更に取り組んでいますか?分離されたブランチを作成してください。

supabase branches create feature-payments
supabase branches switch feature-payments

# 変更を加え、テストし、マージする
supabase branches merge feature-payments

これにより、実験中もメインの開発データベースをクリーンに保つことができます。

避けるべきよくある間違い

Studioでデータベースを直接編集する。 常にマイグレーションを使用してください。直接編集すると追跡されず、チームメイトはそれらの変更を把握できません。

.envファイルをコミットする。 本番環境にはsupabase secrets setを使用してください。.env*.gitignoreに追加してください。

プル後にsupabase db resetをスキップする。 チームメイトの変更をプルした場合、新しいマイグレーションをローカルで実行する必要があります。それらを適用するためにリセットしてください。

スキーマ変更後に型を再生成しない。 カラムを追加した瞬間にTypeScriptの型は古くなります。型生成をマイグレーションワークフローの一部にしてください。

ローカルテストなしで関数をデプロイする。 デプロイする前に、常にsupabase functions serveを実行し、実際のリクエストでテストしてください。

フロントエンドコードでサービスロールキーを使用する。 サービスロールキーはRLSをバイパスします。Edge Functionsとサーバーサイドコードのみに属し、ブラウザには決して使用しないでください。

パフォーマンスのヒント

# メモリを節約するために不要なサービスをスキップ
supabase start --exclude-studio --exclude-inbucket

# リソースを消費しているものを確認
docker stats

代替手段と比較

機能 Supabase CLI Firebase CLI PlanetScale CLI
ローカルデータベース 完全なPostgreSQL エミュレーターのみ クラウドのみ
マイグレーション Git内のSQLファイル ネイティブサポートなし ブランチング
Edge Functions Denoランタイム Cloud Functions 含まれていない
ローカル認証 完全なGoTrue エミュレーター 含まれていない
オープンソース 完全にオープン プロプライエタリ プロプライエタリ
型生成 組み込み 手動 手動

Firebaseのローカルエミュレーターは素早いプロトタイピングには良いですが、実際のPostgreSQLインスタンスは提供しません。PlanetScaleのブランチングモデルはスキーマ変更に優れていますが、常にクラウドに対して作業することになります。Supabase CLIは、完全にオープンソースでPostgreSQLネイティブのローカル開発体験を望むチームにとって優れています。

実際のユースケース

マルチテナントデータを持つSaaSアプリケーション。 あるフィンテックスタートアップは、3つの環境(開発、ステージング、本番)で47のマイグレーションを管理しています。RLSポリシーは、コードが本番環境に到達する前に、異なるユーザーロールでローカルでテストされます。結果:6ヶ月間でスキーマ関連の本番インシデントはゼロでした。

Eコマースの注文処理。 あるEコマースチームは、Stripeのウェブフック処理にEdge Functionsを使用しています。彼らはsupabase functions serveを使って、実際のStripeテストイベントでウェブフックのペイロードをローカルでテストしています。デプロイ時間は2時間から15分に短縮されました。

モバイルアプリのバックエンド。 あるReact Nativeチームは、マイグレーションごとにTypeScriptの型を生成し、それを社内のnpmパッケージとして共有しています。フロントエンドとバックエンドは自動的に同期されます。「このエンドポイントはどのようなフィールドを返すのか?」といったSlackでの質問はもうありません。

まとめ

これで次のことができるようになりました:

このワークフローはすぐに効果を発揮します。チームはより速く出荷し、バグを早期に発見し、二度とスキーマのずれに悩まされることはありません。

次のステップ:

  1. インストール: brew install supabase/tap/supabase
  2. プロジェクトでsupabase initを実行
  3. 最初のマイグレーションを作成
  4. Apidogを設定してローカルエンドポイントをテスト
  5. 自信を持って本番環境にデプロイ

ApidogでSupabase APIをテスト - 無料

ボタン

よくある質問

Supabase CLIを使用するにはDockerが必要ですか?はい。supabase startを実行する前にDocker Desktopが実行されている必要があります。CLIはDocker Composeを使用して、完全なスタックをローカルで実行します。Dockerが実行されていない場合、「Cannot connect to Docker daemon」エラーが発生します。

ローカルデータベースを本番環境と同期するにはどうすればよいですか?supabase db pullを使用してリモートスキーマからマイグレーションを生成し、supabase db pushを使用してローカルのマイグレーションを本番環境に適用します。プル後にローカルでsupabase db resetを実行して、環境が一致していることを確認してください。

Supabase CLIをSupabase Cloudアカウントなしで使用できますか?はい。CLIは、クラウドアカウントなしで開発のために完全にローカルで使用できます。本番環境にデプロイする準備ができたときにのみ、supabase loginsupabase linkが必要です。

チームでマイグレーションの競合を処理するにはどうすればよいですか?新しいマイグレーションを作成する前に、最新のGit変更をプルし、supabase db resetを実行してください。記述的なマイグレーション名を使用し、破壊的なスキーマ変更を行う際にはチームとコミュニケーションを取ってください。

supabase db pushsupabase migration upの違いは何ですか?supabase migration upは、保留中のマイグレーションをローカルデータベースに適用します。supabase db pushは、それらをリモート(本番)プロジェクトに適用します。常に最初にローカルでテストしてください。

既存のプロジェクトでSupabase CLIを使用できますか?はい。supabase link --project-ref YOUR_PROJECT_IDを実行して既存のプロジェクトにリンクし、supabase db pullを実行して現在のリモートスキーマからマイグレーションを生成できます。

RLSポリシーをローカルでテストするにはどうすればよいですか?http://localhost:54323のSupabase Studioを使用してユーザーロールを切り替えるか、異なるJWTトークンを使用してAPI経由でテストします。Apidogを使用すると、複数の環境を異なるユーザートークンで作成し、同じリクエストを異なるユーザーとして実行することで、これが簡単になります。

Supabase CLIは無料ですか?はい。CLIは無料でオープンソースです。ローカル開発には費用はかかりません。Supabase Cloudリソースは、本番環境にデプロイした場合にのみ料金が発生します。

ApidogでAPIデザイン中心のアプローチを取る

APIの開発と利用をよりシンプルなことにする方法を発見できる