VS Code の Remote Containers を使って Supabase を簡単にローカル開発する

2022.08.15

💻
TECH

VS Code の Remote Containers を使って Supabase を簡単にローカル開発する

ほぼ一年前に Supabase を使ったサンプルアプリ作成の記事を投稿しました。

それ以降ほとんど Supabase を触る機会がなく放置していましたが、

Realtime 機能の Postgres RLS 対応とか、いつの間にか出ていた Edge Funtction とか、

進化した CLI とか色々変化があったようなので、改めて記事を書いていきたいと思います。


今回のコンセプト

今回は VSCode の拡張機能「Remote - Containers」の中で Supabase を起動してローカルで開発できるようにする方法を試してみます。


Prerequisites

以下をインストールしてください

  • Docker
  • Vs Code
  • Vs Code の拡張機能 Remote - Containers


Next.js アプリの作成

Next.js でアプリケーションを作成していきます。

また、TypeScript を利用するのでオプションつきで以下のようにコマンドを実行します。

npx create-next-app@latest --typescript

プロジェクト名の入力を求められますが、なんでも構いません。


Remote - Containers の設定

Remote Containers の設定を行なっていきます。

VS Code を開き[Ctrl (Mac は Cmd) + Shift + P]でコマンドパレットを開き、

remote containers add と入力して以下の画像の項目を選択

5b358686002d16b9f2c27991e47572e0.png

Show All Definitions...を選択

bcd3b93d3a878b1f23fd795fc5908d88.png

Node.js & TypeScript を選択

a61377dc22199d2a578586bb34bd4e82.png

default (16-bullseye) を選択

96d7ad09afd5bf8bd25196b6706035f2.png

Docker-in-Docker と Git を選択

e53dced184ad28b5508dfbb66db1e1ae.png

Docker Engine と Git のバージョンは latest を選択

225c0e8b14db0d340b0bb92deaf3463d.png
b5f754a2ce4b67e9b25b507267d62560.png

全て選択して OK を押すと.devcontainer フォルダが作成されます。


Remote Container の設定に Post Create Command を追加

次に Supabase CLI をインストールできるように Post Create Command の設定を行います。

こちらに手動でインストールする場合の方法がありますのでこれを参考にします。

.devcontainer フォルダにpostCreateCommand.sh というファイルを作成して次の内容を貼り付けてください。

./.devcontainer/postCreateCommand.sh

#!/bin/sh

set -ex

# Supabase CLI
# Select a package that is suitable for your environment from <https://github.com/supabase/cli/releases>
# The package below is for the Apple Silicon Mac.
curl -LO https://github.com/supabase/cli/releases/download/v0.39.3/supabase_0.39.3_linux_arm64.deb

sudo dpkg -i ./supabase_0.39.3_linux_arm64.deb

rm -rf supabase_0.39.3_linux_arm64.deb

supabase init

# NPM
npm install

echo "Done!"

このページによると Dev Containers typescript-node のコンテナ OS は Debian ですので、curl でダウンロードするのは Debian 用のパッケージです。

私の PC は M1 Macbook Air なので、arm64 を選択していますが、

こちらのリリース一覧からご自身の環境にあったものを選択するようにしてください。


次にこのスクリプトを呼び出せるように設定します。

.devcontainer/devcontainer.jsonを開き以下を追加します。

{
  "postCreateCommand": "chmod +x ./.devcontainer/postCreateCommand.sh && ./.devcontainer/postCreateCommand.sh"
}

以上が設定できたら、画面左下のこのマーク

db63cdeb5f4dc7819a4ffc1ea5dc5564.png

をクリックして、Reopen in Container を選択し開発環境のコンテナを起動します。

暫く時間がかかりますが、エラーなく立ち上がれば OK です!


Supabase のローカル起動

Dev Container の設定がうまくいっていれば、

Supabase をローカルで起動する環境が整っていると思います。

次のコマンドを実行して、Supabase をローカル起動します。

supabase start

今後、Dev Container を起動し直した場合にはsupabase startをし直してください。

supabase startして暫くすると、以下のように Supabase が起動します。

Started supabase local development setup.

API URL: http://localhost:54321
DB URL: postgresql://postgres:postgres@localhost:54322/postgres
Studio URL: http://localhost:54323
Inbucket URL: http://localhost:54324
anon key: eyJhbGci...
service_role key: eyJhbGci...

それぞれの項目の意味ですが、

  • API URL: Supabase URL
  • DB URL: Postgres Database の URL
  • Studio: Studio URL(<app.supabase.com>と同じような GUI ツール)
  • Inbucket: Emailbox(メール送信)
  • anon key: Supabase の API を呼び出すためのキー。ブラウザで使っても良い。
  • service_role key: Supabase の API を呼び出すためのキー。ブラウザで使ってはいけない。

といった内容です。


anon key と service_role key は本番環境では上記のように使い分ける必要があります。

service_role key を使うと全て管理者権限で実行されるイメージですので注意が必要です。

今回はローカル開発なので特に気にする必要はありません。


また、localhost:54323をブラウザで開くと Studio というものにアクセスでき、

以下の画像のように<app.supabase.com>と同じような GUI でプロジェクト管理を行えます。

19abf65b2ae23bccb7701a2bec93d5d8.png


Supabase を停止する場合は

supabase stop

を実行してください。


Next.js アプリケーションの作成

環境が整いましたので、実際にアプリケーションを作成していきます。

まず、環境変数を設定します。

.env.local

NEXT_PUBLIC_SUPABASE_URL=http://localhost:54321
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOi...

NEXT_PUBLIC_SUPABASE_URLにはsupabase startを実行したときに表示されたAPI URLの値を、
NEXT_PUBLIC_SUPABASE_ANON_KEYにはanon keyの値を設定してください。


次に、必要なモジュールをインストールします。

npm install @supabase/supabase-js

ここで、一度 Dev Server を起動しておきます。

次のコマンドを実行してください。

npm run dev

このような画面が表示されれば OK です。

9cff187f009199cf24dbeb8598e0e875.png


Supabase client の作成

では、Next.js を編集していきます。

まず、Supabase client を作成するためのヘルパーモジュールを定義します。

./utils/supabaseClient.ts

import { createClient } from "@supabase/supabase-js";

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL || "";
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || "";

export const supabase = createClient(supabaseUrl, supabaseAnonKey);


Components の作成

次に表示するコンポーネントを作成します。

ログインを行うAuthコンポーネントと
ログイン後に表示する画面Dashboardコンポーネントを作成します。

./components/Auth.tsx

import React, { useState } from "react";
import { supabase } from "../utils/supabaseClient"; // ①

export const Auth: React.FC = () => {
  const [loading, setLoading] = useState(false);
  const [email, setEmail] = useState("");

  const handleLogin = async (email: string) => {
    try {
      setLoading(true);
      const { error } = await supabase.auth.signIn({ email }); // ②
      if (error) throw error;
      alert("Check your email for the login link!");
    } catch (error) {
      if (error instanceof Error) {
        alert(error.message);
      }
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <h1>Sign in</h1>
      <div>
        <input
          type="email"
          placeholder="Your email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
        />
      </div>
      <div>
        <button
          onClick={(e) => {
            e.preventDefault();
            handleLogin(email);
          }}
          disabled={loading}
        >
          <span>{loading ? "Loading" : "Send magic link"}</span>
        </button>
      </div>
    </div>
  );
};

① で先ほど作った Supabase Client をインポートし、② で email にログインリンクが送られるようにしています。

./components/Dashboard.tsx

import React from "react";
import { Session } from "@supabase/supabase-js";

type Props = {
  session: Session;
};

export const Dashboard: React.FC<Props> = ({ session }) => {
  return (
    <div>
      <h1>Hello, {session.user?.email}</h1>
      Dashboard
    </div>
  );
};

Supabase のログインセッションをプロパティとして受け取るようにしています。

このコンポーネントはひとまずメールアドレスを表示するだけです。


アプリケーションの起動

では最後にコンポーネントを表示できるように設定し、アプリケーションを起動します。

./pages/index.tsx

import type { NextPage } from "next";
import Head from "next/head";
import { useEffect, useState } from "react";
import styles from "../styles/Home.module.css";
import { Session } from "@supabase/supabase-js";
import { supabase } from "../utils/supabaseClient";
import { Auth } from "../components/Auth";
import { Dashboard } from "../components/Dashboard";

const Home: NextPage = () => {
  const [session, setSession] = useState<Session | null>();

  useEffect(() => {
    setSession(supabase.auth.session());

    supabase.auth.onAuthStateChange((_event, session) => {
      setSession(session);
    });
  }, []);

  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <div>{!session ? <Auth /> : <Dashboard session={session} />}</div>
      </main>
    </div>
  );
};

export default Home;

これで完成です。

先ほど開発サーバーは起動しているので、ページをリロードしてください。

(起動していない場合はnpm run devを実行)


すると以下のような Sign In 画面が表示されるはずです。

0f0bb6ef40b3d94e9d2c5c4c34c7eff2.png

何かメールアドレス(test@example.comなど存在しないアドレスも可)を入力して、

Send magic linkボタンをクリックします。


すると画面上部にCheck your email for the login link!と書かれたアラートが表示されます。

これでログイン用のマジックリンクが送信されているはずですので、メールボックスを確認します。


ここで開くのは Gmail などではなく、supabase startを実行した時に表示された、Inbucket URLのリンクです。

設定を特に変えていなければhttp://localhost:54324のはずです。


以下のような画面が開くので、右上の入力ボックスに先ほどのメールアドレスを入力すると、

受信メールの一覧が開きます。

275c02e5f22538897903cadc4b18d8d7.png

このメールに記載された、Log inリンクをクリックし、以下のように Dashboard が表示されれば成功です。

ebfaea2b6ef2388077d321aa33b853af.png


Studio を確認する

ユーザーデータができているか確認します。

supabase startを実行した際に表示された、Studio URLを開きます。

設定を変えていなければ、http://localhost:54323のはずです。


Studio が表示されたら、Default Project を選択し、

左のドロワーから Authentication をクリックすると以下のようにユーザーが登録されているのが確認できます。

654f8e0fd433e23df8e5ce2ba5f4bdf8.png


まとめ

今回は VS Code の Remote Containers 拡張機能を利用して、コンテナ内で Supabase アプリを作成してみました。

Remote Container を利用すると、チームメンバー間で開発環境を揃えるのが簡単になったり、

マシンの環境を汚さずに環境構築ができたりと利点が大きいですね!

Supabase が Remote Container で動かせることがわかったので、

今後個人で簡単なアプリケーションを作るのも捗りそうです。

今回は環境構築のみでしたが、次回以降はこの環境で Realtime や Edge Function の機能も試してみる予定です。



Homeへ戻る
profile picture

Kosuke Kihara

I'm a Web Developer👑 who shares tips on Tech, Productivity, Design, and much more!

Kohsuk11KOHSUKkohsuk.tech@gmail.com