以前使っていたノートPCを掘り起こし、Supabase専用端末化してみたときの備忘録です。
※画像やコンソール出力をぺたぺた貼ってたらすごい縦に長くなってしまったので、見出し以下について<details></details>
で折りたたんでみました。
環境情報
PC1(Supabase用)
詳細
項目 | 内容 |
---|---|
PC | ThinkPad X1 Carbon (2018モデル) |
OS | Windows10 Home ⇒ Windows11 Home (23H2) |
CPU | i7-8550U |
メモリ | 16GB |
Docker Engine | 26.0.0 |
Docker Desktop | 4.29.0 |
docker compose | v2.26.1-desktop.1 |
scoop | v0.4.1 |
- 2018年頃に購入したPCです
- wsl2、Ubuntu22.04導入済み(今回は使わなかった)
- scoop導入済み
- 今回の作業を行う前にWindows11にアップデート、Docker(wsl)は再インストール、scoopは最新にアップデートしました
PC2(アプリケーション開発用)
詳細
項目 | 内容 |
---|---|
PC | HP Spectre x360 |
OS | Windows11 Pro |
CPU | i7-1165G7 |
メモリ | 16GB |
Docker Engine | 25.0.3 |
Docker Desktop | 4.28.0 |
docker compose | v2.24.6-desktop.1 |
Node.js | v20.13.1 |
npm | 10.5.2 |
- 2022年頃に購入したPCです
- wsl2、Ubuntu20.04導入済み
- wsl2にNode.jsを直インストール済み
$ curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
$ sudo apt-get install -y nodejs
その他
詳細
項目 | 内容 |
---|---|
無線LANルーター | Aterm WG2600HP4 |
サブネットマスク | 255.255.255.0 |
デフォルトゲートウェイ | 192.168.10.1 |
- 後の作業内容としてSupabase用PCのIPアドレスの固定化を行うので関係してそうな箇所を記載しました
セットアップ
以後、見出しにPC1と書いているものはSupabase用PCでの作業内容、PC2と書いているものはアプリケーション開発用PCでの作業内容となります
scoop から supabase CLI をインストール (PC1)
詳細
Windows用の supabase CLIをインストールします
> scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
> scoop install supabase
> scoop list
Installed apps:
Name Version Source Updated Info
---- ------- ------ ------- ----
7zip 23.01 main 2024-05-12 14:12:00
hadolint 2.10.0 main 2022-08-11 19:25:59
supabase 1.165.0 main 2024-05-12 14:12:01
- supabase CLIについて1.165.0というバージョンがインストールできました
- supabaseのインストールと併せて7zipがインストールされました(たぶん)
- hadolintは今回の記事の内容とは一切関係ありません
- ちなみに管理者として起動したコマンドプロンプトにて実行しました(不要かも)
supabaseのローカル環境起動 (PC1)
詳細
> cd /D C:\workspace_supabase
> mkdir example-app-backend
> cd example-app-backend
> supabase init
Generate VS Code settings for Deno? [y/N] N
Generate IntelliJ Settings for Deno? [y/N] N
Finished supabase init.
> dir supabase /S /B
C:\workspace_supabase\example-app-backend\supabase\config.toml
C:\workspace_supabase\example-app-backend\supabase\seed.sql
- 今回は
C:\workspace_supabase\example-app-backend
ディレクトリ内にsupabaseのプロジェクトの作成を行いました -
supabase init
コマンドを実行したディレクトリ内に1フォルダ、2ファイルが生成されました
続けてstartコマンドを実行
> supabase start
15.1.1.41: Pulling from supabase/postgres
17d0386c2fff: Pull complete
ec8061954605: Pull complete
e54d94900333: Pull complete
~~~省略~~~
Seeding data supabase\seed.sql...
2.8.1: Pulling from supabase/kong
213ec9aee27d: Already exists
~~~省略~~~
Started supabase local development setup.
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: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0
service_role key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU
S3 Access Key: 625729a08b95bf1b7ff351a663f3a23c
S3 Secret Key: 850181e4652dd023b7a98c58ae0d2d34bd487ee0cc3254aed6eda37307425907
S3 Region: local
- 初回はstartコマンド実行時にコンテナを起動するためのイメージのプルが行われるため数分掛かりました
- startコマンド実行時にコンソールに表示される各種情報はアプリケーション開発の際、外からsupabaseに接続するのに必要となります
- supabaseのローカルの情報は
supabase status
コマンドから再度確認できるみたいなので控えておかなくても大丈夫かも?
- supabaseのローカルの情報は
起動したコンテナについて確認しました
> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
48087ba9578d public.ecr.aws/supabase/studio:20240422-5cf8f30 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes (healthy) 0.0.0.0:54323->3000/tcp supabase_studio_example-app-backend
dfd206489b0b public.ecr.aws/supabase/postgres-meta:v0.80.0 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes (healthy) 8080/tcp supabase_pg_meta_example-app-backend
d0b516eb993a public.ecr.aws/supabase/edge-runtime:v1.45.2 "sh -c 'mkdir -p /ho…" 2 minutes ago Up 2 minutes 8081/tcp supabase_edge_runtime_example-app-backend
5ded325e82a4 public.ecr.aws/supabase/imgproxy:v3.8.0 "imgproxy" 2 minutes ago Up 2 minutes (healthy) 8080/tcp supabase_imgproxy_example-app-backend
fdec91fa0e1d public.ecr.aws/supabase/storage-api:v1.0.6 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes (healthy) 5000/tcp supabase_storage_example-app-backend
9eeca099c0be public.ecr.aws/supabase/postgrest:v12.0.1 "/bin/postgrest" 2 minutes ago Up 2 minutes 3000/tcp supabase_rest_example-app-backend
711583b04956 public.ecr.aws/supabase/realtime:v2.28.32 "/usr/bin/tini -s -g…" 2 minutes ago Up 2 minutes (healthy) 4000/tcp supabase_realtime_example-app-backend
f30fe6d1f89d public.ecr.aws/supabase/inbucket:3.0.3 "/start-inbucket.sh …" 2 minutes ago Up 2 minutes (healthy) 1100/tcp, 2500/tcp, 0.0.0.0:54324->9000/tcp supabase_inbucket_example-app-backend
966eb30b1803 public.ecr.aws/supabase/gotrue:v2.149.0 "auth" 2 minutes ago Up 2 minutes (healthy) 9999/tcp supabase_auth_example-app-backend
cf1802ff839a public.ecr.aws/supabase/kong:2.8.1 "sh -c 'cat <<'EOF' …" 2 minutes ago Up 2 minutes (healthy) 8001/tcp, 8443-8444/tcp, 0.0.0.0:54321->8000/tcp supabase_kong_example-app-backend
20c7522df8ba public.ecr.aws/supabase/postgres:15.1.1.41 "sh -c 'cat <<'EOF' …" 2 minutes ago Up 2 minutes (healthy) 0.0.0.0:54322->5432/tcp supabase_db_example-app-backend
ちなみにSupabaseのDocker環境は以下のコマンドから停止できます
> supabase stop
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=example-app-backend
- 環境を丸ごと削除したいときは
--no-backup
オプションをつけて実行することでボリュームを含むコンテナ環境の破棄ができます
IPアドレスを固定化 (PC1)
詳細
接続される側のローカルIPアドレスが変わってしまうと手間なのでおおよそ以下の手順で固定化しました。
ipconfig
で自動割り当て中の設定を確認
> ipconfig
Wireless LAN adapter Wi-Fi:
~~~省略~~~
IPv4 アドレス . . . . . . . . . . . .: 192.168.10.104
サブネット マスク . . . . . . . . . .: 255.255.255.0
デフォルト ゲートウェイ . . . . . . .: 192.168.10.1
設定 > ネットワークとインターネット > Wi-Fi > [Wi-FiのSSID名] と進み IP割り当ての「編集」をクリック
自動⇒手動に切り替え、IPv4のスイッチをオンに切り替える。
その後、事前に確認した内容を元に設定
項目 | 内容 |
---|---|
IPv4 | オン |
IPアドレス | 192.168.10.104 |
サブネットマスク | 255.255.255.0 |
ゲートウェイ | 192.168.10.1 |
優先DNS | 192.168.10.1 |
HTTPS経由のDNS | オフ |
IPv6 | オフ |
接続確認 (PC2)
詳細
ブラウザでSupabaseのStudioにアクセスしダッシュボードが表示されることを確認
- 具体的には http://192.168.10.104:54323/ にアクセスします
- PC1側で
supabase start
の完了時に表示されていたStudio URL
を基に、IPアドレス部分(127.0.0.1
)をPC1のローカルIP(192.168.10.104
)に書き換えています
- PC1側で
Inbucketというローカル環境用の仮想メールサーバーのGUIにアクセスできることを確認
- 具体的には http://192.168.10.104:54324/ にアクセスします
- PC1側で
supabase start
の完了時に表示されていたInbucket URL
を基に、IPアドレス部分(127.0.0.1
)をPC1のローカルIP(192.168.10.104
)に書き換えています
- PC1側で
続けてSQLクライアントソフト(今回はA5M2)で接続できることを確認します
こちらもsupabase start
の完了時に表示されていたDB URL
の情報を分解し、IPアドレス部分だけ書き換えることで接続できました
デモアプリ開発 (PC1,PC2)
- 今回は認証とサインアップとアプリ固有のテーブルを作る辺りが問題なく行えることを確認します
- 具体的にはNuxt3を使用したTODOリストを管理するアプリケーションを作成します
TODOリスト情報を管理するtasksテーブルを作成 (PC2)
詳細
StudioのTable Editor
画面を開き Create a new table
ボタンをクリック
右から出てくるサイドバーでtasksテーブルの情報を入力
-
Enable Row Level Security
はチェックを入れておく(デフォルトでチェックされてるかも)
同サイドバー内でカラム情報を入力
カラム名 | 型 | デフォルト | 備考 |
---|---|---|---|
id | int8 | null |
Primary とIs Identity にチェック入れる |
title | text | null |
Is Nullable にチェック入れる |
completed | bool | false | (NOT NULL) |
user | uuid | auth.uid() ※1 | (NOT NULL) |
created_at | timestamptz | now() | (NOT NULL) |
※1 auth.uid()
はauthスキーマのusersテーブルから認証中のユーザーIDを取得するというSupabaseが用意する関数です
外部キーの情報は特に入力せずに、Save
ボタンをクリック
tasksテーブルの作成が行えました
tasksテーブル横の「...」よりView Policies
をクリック
tasksテーブルに対して「RLSが有効化されているがポリシーが存在しない」というメッセージが表示されています
RLSは↑のポリシーの一覧画面からCreate a new policy
ボタンをクリックした先のGUIでも作成できますが、今回はSQL Editor
の画面でクエリをペーストしての設定を行います。サイドバーからSQL Editorページに遷移
以下のクエリをクエリ欄にペーストし、Run
ボタンをクリック
create policy "Individuals can create tasks." on tasks for
insert with check (auth.uid() = user);
create policy "Individuals can view their own tasks. " on tasks for
select using ((select auth.uid()) = user);
create policy "Individuals can update their own tasks." on tasks for
update using ((select auth.uid()) = user);
create policy "Individuals can delete their own tasks." on tasks for
delete using ((select auth.uid()) = user);
- エラーっぽいトーストメッセージが表示されいますが、クエリ自体は正しく実行できてそうなログが出ました
- ちなみに↑のクエリはINSERT、DELETE、UPDATE、SELECTのそれぞれについて認証中のユーザーの自身に紐づく情報のみ操作(登録、削除、更新、取得)可能とするRLSです
tasksテーブルのポリシーを確認するページに戻るとINSERT、DELETE、UPDATE、SELECTのそれぞれについてRLSが設定されていることが確認できます
A5M2の方からもpublicスキーマ内にtasksテーブルの存在を確認
Supabaseのダンプを取得 (PC1)
詳細
supabace CLIのdb dump
コマンドを使用して↑の手順で作成したtasksテーブルに関する定義を含むダンプを取得
> supabase db dump --local --file supabase/seed.sql
Dumping schemas from local database...
Dumped schema to supabase/seed.sql.
- PC2側でブラウザを経由して作成したtasksテーブルに関する情報を含むダンプが取得できることを確認できました
Nuxt3のアプリケーション作成1 (PC2)
- Nuxt3の新規プロジェクトを作成しプロジェクト内で利用するモジュールを導入するとこまで実施します
詳細
- Nuxt3からSupabaseを利用するためのモジュール(@nuxtjs/supabase)があるのでこちらを使用します
- 上記モジュールのデモとしてTODOリストを管理するアプリケーションのコードが公開されているのでこちらを参考にしつつ一部書き換えるなどしました
- UIを作るのにPrimeVueを使いたいので、Nuxt3向けのモジュール(nuxt-primevue)を利用します
- 併せてprimeflex、primeiconsもインストールします
- Dockerは使わずwsl2(Ubuntu)に直インストールしているNode.jsよりプロジェクトを作成します
$ cd ~/
$ mkdir example-app-frontend && cd $_
$ npx nuxi@latest init .
$ npm install -D @nuxtjs/supabase supabase
$ npm install -D nuxt-primevue primeflex primeicons sass
package.jsonの中身は以下の通りとなりました
{
"name": "nuxt-app",
"private": true,
"type": "module",
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"dependencies": {
"nuxt": "^3.11.2",
"vue": "^3.4.27",
"vue-router": "^4.3.2"
},
"devDependencies": {
"@nuxtjs/supabase": "^1.2.2",
"nuxt-primevue": "^0.3.1",
"primeflex": "^3.3.1",
"primeicons": "^7.0.0",
"sass": "^1.77.1",
"supabase": "^1.165.0"
}
}
プロジェクトのルートに.env
を作成
SUPABASE_URL="http://192.168.10.104:54321"
SUPABASE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0"
インストールしたモジュールの設定をnuxt.config.tsに追加
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
- devtools: { enabled: true }
+ devtools: { enabled: true },
+
+ modules: [
+ '@nuxtjs/supabase',
+ 'nuxt-primevue'
+ ],
+
+ supabase: {
+ redirectOptions: {
+ login: '/',
+ callback: '/confirm',
+ },
+ },
+
+ primevue: {
+ usePrimeVue: true,
+ components: {
+ include: '*',
+ },
+ directives: {
+ include: '*',
+ },
+ composables: {
+ include: '*',
+ },
+ },
+
+ css: [
+ 'primevue/resources/themes/mira/theme.css',
+ 'primeflex/primeflex.css',
+ 'primeicons/primeicons.css',
+ ],
})
- primevueに含まれるテーマCSS、primeflexとprimeiconsのcssも追加
Nuxt3の開発サーバーを起動
$ npm run dev
> dev
> nuxt dev
Nuxt 3.11.2 with Nitro 2.9.6 9:43:52 PM
9:43:53 PM
➜ Local: http://localhost:3000/
➜ Network: use --host to expose
➜ DevTools: press Shift + Alt + D in the browser (v1.3.1) 9:43:54 PM
ℹ Vite client warmed up in 2702ms 9:43:58 PM
ℹ Vite server warmed up in 3409ms 9:43:59 PM
✔ Nuxt Nitro server built in 2281 ms nitro 9:44:01 PM
ブラウザで http://localhost:3000/ にアクセス
- Nuxt3のWelcomeページが見れることを確認
- レイアウトが少し崩れてるのはPrimeVueのテーマCSSとかを読み込んでいることが関係しているかもしれません(このページは後の手順で消すので問題なし)
TypeScript用の型情報を生成 (PC2)
詳細
npmでインストールしたsupabase CLIのgen types typescript
コマンドよりTypeScript用の型情報を生成します
$ mkdir types
$ npx supabase gen types typescript --db-url postgresql://postgres:postgres@192.168.10.104:54322/postgres > types/database.types
Connecting to 192.168.10.104 54322
v0.80.0: Pulling from supabase/postgres-meta
~~~省略~~~
Status: Downloaded newer image for public.ecr.aws/supabase/postgres-meta:v0.80.0
(node:1) ExperimentalWarning: Importing JSON modules is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
- tasksテーブルに関する情報を含む型情報が生成されました
-
--db-url
オプションにはPostgreSQLへの接続文字列を指定します- PC1側で
supabase start
の完了時に表示されていたDB URL
を基に、IPアドレス部分(127.0.0.1
)をPC1のローカルIP(192.168.10.104
)に書き換えています
- PC1側で
(不要) TypeScript用の型情報をPC1側で生成 (PC1)
詳細
- 最初はPC1側で
--local
オプション付きで以下のようなコマンドを実行して型情報を生成し、USBメモリ経由でPC2側にコピーという方法をとっていました。
> mkdir types
> supabase gen types typescript --local > types\database.types.ts
Connecting to db 5432
(node:1) ExperimentalWarning: Importing JSON modules is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
- 実際には TypeScript用の型情報を生成 (PC2) に記載した通り
--db-url
オプション付きで実行することでPC2側でgen types typescript
コマンドを実行できるため不要な手順であることがわかりました。
Nuxt3のアプリケーション開発2 (PC2)
- 型情報の生成後の続きとして各画面の開発を実施します
詳細
app.vueを以下の通り書き換え
<template>
- <div>
- <NuxtWelcome />
- </div>
+ <ClientOnly>
+ <Toast />
+ </ClientOnly>
+ <Body class="m-0">
+ <div class="w-screen h-screen surface-ground">
+ <NuxtPage />
+ </div>
+ </Body>
</template>
ログイン画面を新規作成
<template>
<div class="flex align-items-center justify-content-center h-full flex-wrap">
<Card class="flex justify-content-center w-20rem">
<template #title>
<div class="text-center">
<SelectButton
v-model="state.authType"
:allow-empty="false"
:options="authTypes"
:pt="{
button: () => ({
class: 'w-7rem p-button-sm'
})
}"
/>
</div>
</template>
<template #content>
<Password v-model="state.dummyPassword" class="hidden"/>
<label class="block w-full">Email</label>
<InputText v-model="state.email" />
<label class="mt-2 block w-full">Password</label>
<Password v-model="state.password" />
</template>
<template #footer>
<Button
:label="state.authType === 'login' ? 'Login' : 'Signup'"
class="w-full"
:disabled="!state.email || !state.password"
@click="execLoginOrSignup"
/>
</template>
</Card>
</div>
</template>
<script setup lang="ts">
const toast = useToast()
const state = reactive<{
authType: 'login' | 'signup'
email: string
password: string
dummyPassword: string
}>({
authType: 'login',
email: '',
password: '',
dummyPassword: ''
})
const authTypes = ['login', 'signup']
const user = useSupabaseUser()
const { auth } = useSupabaseClient()
const execLoginOrSignup = async () => {
if (state.authType === 'login') {
const { error } = await auth.signInWithPassword({
email: state.email,
password: state.password,
})
if (error) {
toast.add({
severity: 'error',
summary: 'Login error',
detail: error.message,
life: 5000,
})
}
} else {
const { error } = await auth.signUp({
email: state.email,
password: state.password,
})
if (error) {
toast.add({
severity: 'error',
summary: 'Signup error',
detail: error.message,
life: 5000,
})
}
}
}
watchEffect(() => {
if (user.value) {
navigateTo('/tasks')
}
})
</script>
-
nuxt.config.ts
のsupabase.redirectOptions.login
で設定したログインページのパスと揃える必要があります
TODOリストの管理画面を作成
<template>
<div class="flex align-items-center justify-content-center w-full py-4 flex-wrap">
<Card class="flex justify-content-center w-30rem">
<template #title>
<div class="text-3xl">
Todo List.
</div>
</template>
<template #content>
<div class="grid">
<div class="col-12">
<div class="grid align-items-center">
<div class="col">
<InputText v-model="state.newTask" class="w-full" />
</div>
<div class="col-fixed">
<Button icon="pi pi-plus" label="Add" size="small" @click="addTask" />
</div>
</div>
</div>
<div class="col-12">
<template v-if="tasks">
<DataView :value="tasks" data-key="id">
<template #list="slotProps">
<div class="grid grid-nogutter">
<div v-for="(task, index) in slotProps.items" :key="index" class="col-12">
<div class="grid">
<div class="col">
{{ task.title }}
</div>
<div class="col-fixed">
<div class="flex align-items-center justify-content-between flex-wrap">
<div class="flex mr-2">
<InputSwitch v-model="task.completed" @change="completeTask(task as Task)" />
</div>
<div class="flex">
<Button icon="pi pi-trash" severity="danger" size="small" @click="removeTask(task as Task)" />
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<template #empty>
<div>
No tasks registered
</div>
</template>
</DataView>
</template>
</div>
</div>
</template>
</Card>
</div>
</template>
<script setup lang="ts">
import type { Database } from '~~/types/database.types'
interface Task {
id: number
title: string
completed: boolean
user?: string
created_at?: string
}
const client = useSupabaseClient<Database>()
const user = useSupabaseUser()
const state = reactive({
newTask: '',
loading: false
})
const { data: tasks } = await useAsyncData('tasks', async () => {
const { data } = await client.from('tasks').select('id, title, completed').eq('user', user.value!.id).order('created_at')
return data
})
async function addTask() {
if (state.newTask.trim().length === 0) return
state.loading = true
const { data } = await client.from('tasks')
.upsert({
user: user.value!.id,
title: state.newTask,
completed: false,
})
.select('id, title, completed')
.single()
tasks.value?.push(data!)
state.newTask = ''
state.loading = false
}
const completeTask = async (task: Task) => {
await client.from('tasks').update({
completed: task.completed,
}).match({
id: task.id,
})
}
const removeTask = async (task: Task) => {
tasks.value = tasks.value?.filter(t => t.id !== task.id) ?? []
await client.from('tasks').delete().match({
id: task.id,
})
}
</script>
- この画面は
nuxt.config.ts
のsupabase.redirectOptions.exclude
で除外URLとして設定していないため認証が必須として扱われます - 認証を済ませていない状態でpages/tasks.vueに直アクセスした場合、モジュール内のルートミドルウェア処理によって
supabase.redirectOptions.login
で指定したパスに遷移します
デモアプリの動作確認 (PC2)
詳細
nuxt dev
で起動する開発用のサーバーが起動している状態で http://localhost:3000/ にアクセス
pages/index.vueのログイン&サインアップ画面が表示できることを確認
存在しないユーザーを入力しログインを試みた状態でSupabaseの認証結果としてエラーを受け取り、トーストメッセージとして表示できることを確認
サインアップを実行 (Emailにtestuser@example.com
、Passwordにpassword
)と入力
StudioのAuthentication > Users
画面で登録したサインアップしたユーザーが存在することを確認
サインアップ成功後、ログイン&サインアップの画面コンポーネント内のwatchEffectの処理によりTODOリストの管理画面に遷移したことを確認
<script setup lang="ts">
const user = useSupabaseUser()
watchEffect(() => {
if (user.value) {
navigateTo('/tasks')
}
})
</script>
TODOリストの管理画面で1件のタスクを登録できることを確認
StudioのTable Editor
画面でtasksテーブルのデータとして登録した内容が閲覧できることを確認
TODOリストの管理画面で1件のタスクを更新できることを確認(スイッチをONにする)
TODOリストの管理画面で1件のタスクを削除できることを確認(ゴミ箱ボタンクリック)
Supabaseのバックアップを含まないプロジェクトの破棄 (PC1)
せっかくなので--no-backup
を付けたstopコマンドを実行してみました
再度Supabaseのローカル環境立ち上げ (PC1)
バックアップ済みのsupabase/seed.sql
を元にtasksテーブルとtasksテーブルのRLSポリシーが作成されることを確認します
詳細
> supabase start
Seeding data supabase\seed.sql...
Started supabase local development setup.
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: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0
service_role key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU
S3 Access Key: 625729a08b95bf1b7ff351a663f3a23c
S3 Secret Key: 850181e4652dd023b7a98c58ae0d2d34bd487ee0cc3254aed6eda37307425907
S3 Region: local
PC1側でブラウザからStudioのTable Editor
画面にアクセス
- tasksテーブルが出来上がっていることが確認できました
続けてRLSのポリシーを確認
- INSERT、DELETE、UPDATE、SELECTのそれぞれのRLSポリシーについて以前の状態が復元できていることを確認できました
まとめ
詳細
- SupabaseのDockerコンテナを利用したローカル環境の初歩的な部分について複数台のPCを使った環境でおおよそ問題なく使えることがわかりました。
- 実際にアプリケーションの開発を進めていくうえで必要となるSupabase本番とのプロジェクトのリンクやマイグレーション周りの動作確認は行えていません。。
この記事の中で紹介しているSupabase側と開発したアプリケーションのコードはそれぞれ以下のリポジトリで公開しています。
https://github.com/imo-tikuwa/nuxt-supabase-example-app-backend
https://github.com/imo-tikuwa/nuxt-supabase-example-app-frontend
参考リンク
-
Supabase CLI | Supabase Docs
- Supabase CLIに関するドキュメント
-
supabase/cli: Supabase CLI. Manage postgres migrations, run Supabase locally, deploy edge functions. Postgres backups. Generating types from your database schema.
- Supabase CLIのリポジトリ(GitHub)
- ↑のドキュメントとどちらかをざっくり読んでおくのが良いかも
-
Windows 11のIPアドレス(IPv4)を固定に設定する手順|Aterm Q&A|目的別で探す|Aterm(エーターム) サポートデスク
- IPアドレスの固定化をする際に見たページ