Supabase を自前のサーバーで動かす手順そのものは短い。docker ディレクトリを持ってきて環境変数を書き換え、コンテナを起動する。噛み合わなくなるのはその先です。2026年8月時点の公式リポジトリでは API ゲートウェイが Kong から Envoy に入れ替わり、サービス名も kong から api-gw へ改名されています。構成要素・更新・バックアップ・自前で持つべきかの線引きを、実測した値で並べます。
まとめ:自前運用に踏み切る前に決める3つの判断
第一に、バックアップと復旧を自分で組む前提を受け入れられるかどうか。公式ドキュメントはマネージドバックアップと PITR をセルフホストでは提供しないと明記し、更新スクリプトも設定ファイルしか退避しません。
第二に、追随の担い手を置けるかどうかです。イメージのバージョンはひと月おきに動き、過去3リリースは全て破壊的変更を含んでいました。Postgres のメジャー移行、認証エンドポイントのパス変更、ゲートウェイの入れ替えと続いています。
第三に、金額ではなく要件で選べているか。月25ドルのマネージドとの差額は数千円です。「安いから」だけが理由なら、SupabaseとFirebaseの違いを比較した記事で扱った無料枠の範囲を先に確認してください。
現行スタックの構成要素:Envoyが既定になった11サービスの役割
公式の構成に定義されるサービスは11本です。以下は master ブランチを2026年8月28日に取得した時点のイメージタグです。
| サービス名 | イメージ | 役割 |
|---|---|---|
| db | postgres:17.6.1.136 | 本体のPostgres |
| api-gw | envoy:v1.39.0 | 8000番の入口 |
| auth | gotrue:v2.189.0 | 認証とJWT発行 |
| rest | postgrest:v14.12 | 自動生成REST API |
| realtime | realtime:v2.102.3 | 変更の配信 |
| storage | storage-api:v1.60.4 | ファイルAPI |
| imgproxy | imgproxy:v3.30.1 | 画像の変換 |
| meta | postgres-meta:v0.96.6 | スキーマ操作API |
| functions | edge-runtime:v1.74.0 | Deno実行環境 |
| studio | studio:2026.08.03 | 管理画面 |
| supavisor | supavisor:2.9.5 | 接続プーラー |
データ層とAPI層:dbとrestとauthが担う3つの責務の切れ目
中心は db で、他は全てこの Postgres に依存します。rest はテーブル定義から REST API を生成し、auth は JWT を発行する。認可の判断はアプリ側ではなく行レベルセキュリティが持つ設計です。
この分担はマネージド版と同じで、アプリのコードは書き換えずに済みます。逆にポリシーを書かずに置くと、入口を開けた瞬間に全テーブルが読める。書き方はSupabase RLSの設定手順の記事、公開範囲は自動生成APIとRPCの記事を参照してください。
Studioとmetaは管理面:本番で外から触らせない置き方
studio は管理画面、meta はその裏でスキーマを読み書きする API です。この2本はアプリの動作には不要で、止めてもデータ API は動きます。meta にはヘルスチェックが定義されていないため、状態表示が健全でも応答していない場合があります。
既定の守りは Studio への HTTP ベーシック認証だけです。DASHBOARD_PASSWORD の初期値は公開リポジトリに書かれた文字列のままなので、変更前にポートを外へ出すと管理画面ごと明け渡すことになります。
realtimeとstorageとfunctionsを止めても動く構成の作り方
使わない機能は最初から起動しない選択もできます。ファイルを扱わないなら storage と imgproxy、購読が不要なら realtime を落とせる。メモリ4GBの最小構成では、この判断で余裕が変わります。
ただし後から足す場合は環境変数の追加とゲートウェイのルート定義が要ります。実装側の話はRealtimeの実装と同時接続の上限を扱った記事とEdge FunctionsのDeno実行環境の記事にまとめました。
supavisorを内包する意味:接続数の上限を自分で決める
接続プーラーの supavisor は既定で同梱され、5432 と 6543 の両方を公開します。POOLER_DEFAULT_POOL_SIZE は 20、POOLER_MAX_CLIENT_CONN は 100 が初期値です。
マネージド版はプランで上限が決まっていましたが、自前ではこの2つと max_connections を釣り合わせます。経路の選び方はPrismaとDrizzleの接続文字列を扱った記事で整理しました。
KongからEnvoyへ切り替わった経緯とapi-gw改名の影響
ここが既存の日本語記事と最も食い違う点です。手元の構成と解説が合わないときは、たいていこの変更が挟まっています。
0.8.0で既定が入れ替わった:kongという名前だけが残る
セルフホスト版のリリース 0.8.0 で、既定が Kong から Envoy に変わりました。サービス名は kong から api-gw へ、コンテナ名は supabase-envoy へ改名されています。公式のマニフェストによれば kong のエイリアスは引き続き解決するため、内部の参照は動きます。
壊れるのは2箇所です。サービス名を直接指定していた運用コマンドは止まり、設定ファイルを編集してルートを足していた構成は更新のマージで置き換わります。セルフホストでMCPサーバーを有効化する作業も、このゲートウェイの設定ファイルを編集して再起動する手順になります。詳細はSupabase MCPサーバーの接続手順とスコープ設計にまとめました。
Kongを続けるならoverride:config add kongで固定する
Kong を使い続ける道は残っています。sh run.sh config add kong でオーバーライドを有効にすると docker-compose.kong.yml が合成対象に入る。versions.md では Kong 側のイメージも 3.9.3 まで更新されています。
目安は、独自のルートやプラグインを入れているかどうかの一点です。素のまま使っていたなら Envoy へ寄せる。プラグインで認証やレート制限を足していたなら、移植を見積もるまで Kong で固定してください。
初期構築の手順:setup.shとrun.shで立ち上げるまでの流れ
入口は2つあります。スクリプトに任せる方法と、リポジトリを直接持ってくる方法です。
setup.shで雛形を作る:手動cloneとの違いはどこにあるか
Linux では次の1行で雛形が作られます。ディレクトリ構造と初期値、鍵の生成まで済んだ状態から始められます。
curl -fsSL https://supabase.link/setup.sh | sh
cd supabase-project && sh run.sh start
手動で置く場合はリリースタグを指定して取得し、初期値の雛形も鍵も自分で用意します。何が生成されたのか把握したいときは手動のほうが分かりやすい。
git clone --depth 1 --branch self-hosted/v0.8.0 https://github.com/supabase/supabase
mkdir supabase-project
cp -rf supabase/docker/. supabase-project
cd supabase-project && cp .env.example .env
docker compose pull
必要なマシンは最小で 4GB メモリ・2コア・40GB の SSD、推奨は 8GB 以上・4コア以上・80GB 以上です。最小は検証用と考えてください。
既定値のままでは公開できない7つの鍵と生成コマンドの決まり方
初期の環境変数ファイルは秘密情報が全てプレースホルダーで、公式も既定の構成は本番向けではないと明示しています。最低限で書き換える対象は次の通りです。
| 変数 | 条件 | 生成方法 |
|---|---|---|
| POSTGRES_PASSWORD | 英数字のみ推奨 | 任意の長い文字列 |
| JWT_SECRET | 32文字以上 | generate-keys.sh |
| ANON_KEY | JWT_SECRETと対応 | add-new-auth-keys.sh |
| SERVICE_ROLE_KEY | 同上 | add-new-auth-keys.sh |
| DASHBOARD_PASSWORD | 初期値は公開済み | 任意の長い文字列 |
| SECRET_KEY_BASE | 64文字以上 | openssl rand -base64 48 |
| VAULT_ENC_KEY | ちょうど32文字 | openssl rand -hex 16 |
桁数の条件は外しても起動しないだけです。危ないのは管理画面と Postgres のパスワードを放置したまま外向きのポートを開ける流れです。
publishable/secretキーが自前側にも来た:旧鍵との併存
実測した雛形には、従来の2鍵のほかに SUPABASE_PUBLISHABLE_KEY と SUPABASE_SECRET_KEY、JWK 配列を渡す JWT_KEYS、検証用の JWT_JWKS、ES256 署名の非対称版が並んでいました。
新旧が併存するため、どちらをアプリに配るかは自分で決めます。線引きと漏洩時の回し方はSupabaseのAPIキー管理を扱った記事に切り出しました。自前では再発行が手作業になるので、先に整理してください。
起動確認はrun.sh status:落ちるのはauthとstorageが多い
付属の run.sh は Docker Compose の薄い包みで、start・restart・recreate・status・logs・pull・secrets などを持ちます。start は全サービスの健全化を待ってから戻ります。
失敗する箇所は偏っていて、auth は SMTP の指定ミス、storage は保存先の設定漏れで止まります。logs にサービス名を渡して当たりを付け、設定値そのものは printenv と secrets で確認してください。
差し替えるオーバーライド:pg15・s3・logs・TLSの選び分け
docker ディレクトリには用途別の合成ファイルが置かれ、run.sh config add で足し config remove で外します。
| オーバーライド | 足すと変わる点 |
|---|---|
| pg15 / pg17 | Postgresの版を固定 |
| kong / envoy | ゲートウェイの選択 |
| logs | LogflareとVectorを追加 |
| s3 / rustfs | 保存先を外部へ |
| caddy / nginx | TLS終端を前段に置く |
| pgbouncer | プーラーを差し替え |
pg17が既定になった:pg15へ留めるときの固定のしかたと注意
Postgres のイメージは2026年6月17日の更新で 17.6.1.136 が既定になりました。それ以前は 15 系です。既存のデータディレクトリに 17 のコンテナをそのまま向けてはいけない、と公式のマニフェストが警告しています。
移行するなら同梱のスクリプトを root 権限で走らせ、コンテナを作り直す。見送るなら docker-compose.pg15.yml で 15 に固定してください。実行前にダンプを取ることが前提です。
ストレージ実体の選択:MinIOと外部S3とrustfsの三択
既定の保存先はローカルのファイルシステムで、雛形には MinIO 用の資格情報が並んでいます。外部の S3 互換ストレージへ寄せるなら s3、軽量な実装を使うなら rustfs のオーバーライドがあります。
分かれ目はバックアップをどこで取るかです。ローカル保存だと退避の手順を自分で書くことになる。外部の S3 に寄せておけば、その層のバージョニングに任せられます。
ログとメトリクスは追加構成:logsを足すかどうかの判断基準
Logflare と Vector によるログ基盤は既定では起動せず、sh run.sh config add logs で追加する扱いです。README の同梱一覧に両者が載るため、最初から動くと誤解されがちです。
足すとメモリの消費が増えます。マネージド版のログ画面はこれを入れないと使えないので、切り分けをログ直読みで済ませる運用なら無しで始めて構わないでしょう。
TLSはCaddyかNginx:8000をそのまま外に出さない前提
本体が公開するのは平文の 8000 番だけです。公式は前段にリバースプロキシを置く構成を推奨し、caddy と nginx のオーバーライドを用意しています。ここを省いて直接インターネットへ出すと、認証のトークンが平文で流れます。
クラウド版との機能差:セルフホストでは持てない6つの機能と代替手段
同じソフトウェアでも、マネージド版と揃わない部分があります。公式が名指しで挙げているものを押さえると見積もりの精度が上がります。
持てない機能の一覧:ブランチングとPITRと管理APIの扱い
公式は、ブランチング、高度なメトリクス、マネージドバックアップと PITR、アナリティクス系とベクトル系のバケット、ETL、プラットフォーム管理 API を提供しないと明記しています。セキュリティと災害復旧の責任は運用者が持つとも書かれています。
| 失う機能 | 自前での代替 |
|---|---|
| ブランチング | 環境ごとに別スタック |
| マネージドバックアップ | ダンプの定期実行 |
| PITR | WALアーカイブを自作 |
| 高度なメトリクス | logs追加と外部監視 |
| 管理API | SQLとCLIで代替 |
| サポート窓口 | コミュニティのみ |
プレビュー環境ごとに DB を分けていた場合、ブランチングの不在が一番効きます。マネージド版での分け方はVercel連携とプレビュー環境のDB分離の記事で扱っていますが、自前ではスタックの複製で組む形になります。
認証メールは自前のSMTPを用意する:既定は開発用の受け皿だけ
初期値の送信設定はコンテナ内のダミーで、ユーザーもパスワードも架空の文字列です。外部の送信サービスを入れるまで、メール確認を伴うサインアップは完了しません。自動確認の変数で検証は進みますが、本番で残すと他人のアドレスで登録できます。
バックアップは自分で組む:ダンプ3本とストレージ実体の扱い方
ここが自前運用で最も差が出る工程です。マネージド版の日次バックアップに当たるものは無く、手順を自分で書きます。
ダンプはroles・schema・dataの3本に分ける理由と復元順
公式のマネージド版からセルフホストへ移す手引きでは、ロール・スキーマ・データの順に3つへ分けて取ります。生の pg_dump ではなく CLI 経由にすると、内部スキーマの除外と予約ロールの除去が入ります。
supabase db dump --db-url "$DB_URL" -f roles.sql --role-only
supabase db dump --db-url "$DB_URL" -f schema.sql
supabase db dump --db-url "$DB_URL" -f data.sql --use-copy --data-only
復元は1トランザクションで行い、データ投入の直前にトリガーを止めます。この指定を省くと、二重に暗号化されたカラムができるなどの副作用が出ます。
psql --single-transaction --variable ON_ERROR_STOP=1 \
--file roles.sql --file schema.sql \
--command 'SET session_replication_role = replica' \
--file data.sql --dbname "$TARGET_URL"
この3本は日次の退避にも使えます。置き場所はSupabase CLIとローカル開発環境の記事の運用に寄せてください。
ストレージの実体はDBに含まれない:オブジェクト側の二重管理
ダンプに入るのはスキーマ・データ・ロール・ポリシー・関数・トリガー・利用者テーブルまでで、アップロードされたファイルの実体は含まれません。公式の移行手引きも、ストレージのオブジェクトは対象外だと断っています。
退避は2系統になります。ダンプだけ戻すと、行はあるのにファイルが無い状態になる。外部の S3 に寄せておくと、2系統目を書かずに済みます。
復旧目標を先に数字で決める:日次のダンプで足りるかの分かれ目
マネージド版の保持期間は Pro が7日、Team が14日で、PITR は7日あたり月100ドルの追加オプションです。自前でこの水準に近づけるには、WAL のアーカイブと復旧試験まで組むことになります。
決めるのは、どれだけのデータ損失を許せるかという数字です。日次ダンプなら最大24時間分が消えます。当社のインフラ構築支援では、この復旧設計を含めた自前運用の立ち上げも受けています。
更新の運用負荷:update.shの3方向マージと破壊的変更のゲート
構築より重いのは更新です。イメージの版はひと月おきに動き、設定ファイル側の変更も混ざります。
update.shは設定だけを守る:データは別途で退避しておく
付属の update.sh は公式リポジトリの最新設定を取得し、手元の編集内容と3方向マージします。秘密情報・オーバーライド・ローカルの改変が残るよう作られていて、実行にはホスト側に git と jq が必要です。
sh update.sh --dry-run
sh update.sh
sh run.sh pull && sh run.sh recreate
退避の範囲には注意が要ります。公式は設定ファイルだけを写し、Postgres と Storage のデータは退避しないと明記しています。衝突すると標準のマージマーカーが書き込まれ、終了コード2で止まる。版の記録は .supabase-version です。
破壊的変更のゲート:0.6.0と0.7.0と0.8.0で何を求められたか
リポジトリの upgrades.json には、差分では表せない手作業がリリース単位で書かれています。実測した3件はいずれも破壊的変更の扱いで、更新スクリプトは該当区間に入ると内容を表示して確認を求めます。
| 版 | 求められる手当て |
|---|---|
| 0.6.0 | Postgres 17への移行実行 |
| 0.7.0 | 認証URLとSAMLの変更 |
| 0.8.0 | ゲートウェイの入れ替え |
見落としやすいのは 0.7.0 です。API_EXTERNAL_URL にパスの接頭辞が付き、SAML の SSO エンドポイントも移動しました。OAuth プロバイダ側のコールバック URL を直さないと、ログインだけが通らなくなります。
個別サービスだけを上げると壊れる:組み合わせに保証はない前提
1つだけ新しくしたい場面はあります。イメージ行を書き換えて取得と作り直しを回す手順はありますが、公式は個別の版変更について互換性を保証しないと明記しています。
versions.md では、2026年6月3日の更新で8サービスが同時に上がっています。Realtime は v2.76.5 から v2.102.3 まで一気に動いた。1本だけ先へ進めると前提が合わなくなります。
自前運用が割に合う条件:月25ドルと運用工数の損益分岐を引く
ここまでの実測を踏まえ、採用と見送りを条件で言い切ります。
月25ドルと運用工数の比較:どこから自前が高くつき始めるのか
マネージド版は無料枠、月25ドルから始まる Pro、月599ドルから始まる Team という構成です。Pro と Team は月10ドル分のコンピュートクレジットを含み、転送量は250GBまで、超過分は1GBあたり0.09ドルと案内されています。
自前運用に必要なサーバーは推奨構成で 8GB メモリ・4コア・80GB の SSD 以上。クラウドの汎用インスタンスなら月に数千円から1万円程度で、ソフトウェア自体は Apache 2.0 で無償です。金額だけなら数千円の差にしかなりません。
反転するのは工数を載せたときです。更新の追随がひと月1〜2時間、復旧試験の整備が初期で数日、障害対応は自分たちの持ち時間になる。人件費に換算すれば差額はすぐ埋まります。
自前運用に踏み切る4つの条件:所在・閉域・改造・台数で見極める
採用してよいのは次のどれか1つ以上が要件として立つ場合です。データの所在を自社の管理下に置く必要があるとき。閉域網の内側からしか到達させられないとき。製品側へ手を入れる必要があるとき。検証環境を多数並べてプロジェクト単価が積み上がるとき。
いずれも金額に置き換えにくい制約です。1つも無いのに自前を選ぶと、数千円のために運用責任だけを引き受ける形になる。迷うならまずマネージドで動かし、前述のダンプ3本で移す順序が安全でしょう。
見送るべき3つの場面:担い手を置けないなら手を出さない判断軸
1つ目は、更新を追う担い手を置けないとき。過去3リリースが全て破壊的変更を含む製品を片手間で維持するのは無理があります。2つ目は、復旧目標を数字で決められないとき。事故が起きてから初めてダンプの中身を確認する流れになります。
3つ目は、サポート窓口を必要とするとき。セルフホストはコミュニティ支援のみで、応答の保証はありません。Next.js側の構成を扱った記事で触れたアプリ層と違い、ここは移植性ではなく責任分界の話です。
よくある質問
セルフホストとマネージド版でアプリのコードは変わりますか?
接続先の URL と鍵を差し替えるだけで動きます。クライアントライブラリも API の形も同じで、行レベルセキュリティの前提も変わりません。差が出るのはブランチングや PITR といった運用面の機能です。
いま構築した構成にKongは入っていないのですか?
既定では入っていません。0.8.0 で Envoy が既定になり、サービス名は api-gw です。kong のネットワークエイリアスは残るため内部参照は解決します。使い続けるなら sh run.sh config add kong を実行してください。
バックアップはボリュームのコピーで済みませんか?
稼働中のデータディレクトリをコピーすると、整合しない状態を持ち出す危険があります。論理ダンプを取るか、コンテナを止めてから複製してください。オブジェクトの退避も別に組みます。
Postgres 15のまま運用を続けても問題ないですか?
docker-compose.pg15.yml のオーバーライドで固定できるため当面は動きます。ただし既定は 17 に移り、新しい組み合わせは 17 前提で検証されていく見込みです。同梱のスクリプトで移行できるので、早めに済ませるほうが安全でしょう。
無料で使えるという説明は正しいのですか?
ライセンス費用は Apache 2.0 で発生しません。ただしサーバー代・転送量・運用工数はかかります。月25ドルとの差は数千円で、更新追随とバックアップ整備の工数がそれを上回る場合が多い。無償なのはライセンスだけです。
関連記事
- SupabaseとFirebaseの違いを徹底比較:製品の全体像と料金です。
- Supabase CLIとローカル開発環境:マイグレーションの運用です。
- Supabase APIキーの管理:鍵の権限差と回し方です。
- Supabase RLSの設定手順とポリシー設計:認可の実装です。
- Supabase 自動生成API(PostgREST)とRPC:公開範囲の制御です。
- Supabase Realtimeの実装:同時接続の前提です。
- Supabase Edge Functionsとは:Deno実行環境の話です。
- SupabaseにPrismaとDrizzleをつなぐ:接続経路の選び分けです。
- Supabase Next.js連携の実装:アプリ側の構成です。
- Supabase Vercelデプロイ連携:環境ごとのDB分離です。