はじめに
Supabaseは、SaaSのデータベースです。中身はPostgreSQL。
無料でかなり使えるのですが、無料の場合は、しばらく使わないとデータベースの処理が停止 して、"currently paused"とか言われてしまいます。データは残してくれていますが。
停止は2段階 あって、7日間アクセスがないと①の段階になり、アクティベートせずさらに90日間放っておくと②になります。
① ブラウザでアクティベートできる冬眠状態
② backupファイルとして静的なデータになっているので、それをローカルに落としたりあれこれすれば作り直せる、仮死(ほぼ死)状態
①を起こす手間はそう大変ではないのですが、それでも忘れずに数日に一度アクセスし続けないといけないという運用はかなり無理があります。
②に至っては、もう復活させなくていいやと思うくらいめんどくさいです。
そこで、自動的にアクセス して延命させようというのが今回のお話。
概要
GitHub Actions を使って、数日に一度、SupabaseのテーブルへInsertし、Select します。Supabaseが何をもって"アクセスした"と判断するのかはわからないけど、データベースの超基本のこの2つの処理は主軸であることに間違いないので、2つやります。(作る手間も大したことないし😋)
手順
1. 準備(Supabaseで)
(1) テーブル作成
なんでもいいんですが、テーブルを作成します。
ここでは、activate_log
テーブルを作って、comment
という列になんか書くことにします。
テーブル作成はGUIでやったけど、作った後にdefinitionを見れたので貼っておきます。comment
列を追加しただけ。
create table public.activate_log (
id bigint generated by default as identity not null,
created_at timestamp with time zone not null default now(),
comment text null,
constraint activate_log_pkey primary key (id)
) TABLESPACE pg_default;
(2) RLS(Row Level Security)設定
Supabaseは、RLSの設定を厳しくできて、通常は外部から全然アクセスできません。(selectすると、エラーとかではなく静かに0件とか返すから、わかりづらい)
今回は、insertとselectをするので、どちらもOKに設定します。私は、anonキー(APIキー)を使ってアクセスしたときだけ、insertとselectができるように2つのポリシーを追加しました。
(詳細は割愛。GUIでできる。)
(3) 関数作成
selectの処理を、今回はstored procedureを使うので、登録します。
select count(*)
の結果をresult
に入れて、それを返すというだけの、count_activate_log
関数。
create function count_activate_log()
returns integer
language plpgsql
as $$
declare
result integer;
begin
select count(*) into result from activate_log;
return result;
end;
$$;
Supabaseの画面上では、Database>Functionsで作成できますね。
↑のクエリをSQL Editorで流しても当然できます。
2. GitHub Actionsの作成
GitHubのリポジトリのトップに、.github/workflows
というフォルダを作り、その中に適当なファイル名.ymlを作ってpushすれば、GitHub Actionsの完成です。簡単
name: Supabase API Access
on:
push:
branches: [main]
schedule:
- cron: '0 0 */2 * *'
workflow_dispatch:
jobs:
access-supabase-api:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Access Supabase API
run: |
curl -X POST 'https://${{ secrets.SUPABASE_PROJECT_ID }}.supabase.co/rest/v1/activate_log' \
-H "apikey: ${{ secrets.SUPABASE_API_KEY }}" \
-H "Authorization: Bearer ${{ secrets.SUPABASE_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{"comment": "activated by github actions"}'
- name: Check Activation Log Count
run: |
RESPONSE=$(curl -s -X POST \
'https://${{ secrets.SUPABASE_PROJECT_ID }}.supabase.co/rest/v1/rpc/count_activate_log' \
-H "apikey: ${{ secrets.SUPABASE_API_KEY }}" \
-H "Authorization: Bearer ${{ secrets.SUPABASE_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{}')
echo "ActivateLog count: $RESPONSE"
このスクリプトが一番のキモなので、ポイントをいくつか書いておきます。
- 7日アクセスしないとpausedになるので、2日に1回くらいアクセスすればいいかなーということで、
cron: '0 0 */2 * *'
。cronの引数の細かい点は割愛しますが、3つ目の引数に*/2
の指定で、毎月、1, 3, 5...日に起動します -
secrets.SUPABASE_PROJECT_ID
とsecrets.SUPABASE_API_KEY
は、GitHubに登録するシークレット情報。設定方法は次のセクションで説明します。ここでは設定されている前提で、利用しています - 1回目の
curl
はInsert。Rest APIを呼び出しています - 2回目の
curl
はSelect。Rest APIからrpcでcount_activate_log
関数を呼び出し、その結果を受け取るために$RESPONSE
で受けて、echo
してます-
curl
の戻り値は、オプションによって結構違うので注意。ここでは、登録した関数の戻り値、つまりselect count(*)
の件数が入ります
-
3. GitHubのシークレット情報の登録
GitHubでは、GitHub Actionsで利用するログイン情報などを、環境変数として登録しておくことができます。これによって、ソースにベタ書きしなくて済むので、ソースを公開しても安心というわけです。
設定方法
GitHubのリポジトリの設定>Secrets and variables>Actions>Repository secretsに、変数を追加。
SUPABASE_PROJECT_ID
を追加し、SupabaseのプロジェクトIDを設定。abcdefghijklmnopqrst
←これくらいの長さ、雰囲気の文字列。
また、SupabaseからProject Settings>API Keys>anonを入手して、SUPABASE_API_KEY
を追加します。おそらく209文字の記号を含む英数字。
4. 実行!
git push
すれば、Actionsから実行結果を得られます。
まぁ最初だけ見て、あとは見なくていいんですけど。
おわりに
頻繁に利用されるサービスだったらこんなことを考える必要はないのだけど、大半が考えないといけないサービスだと思います。誰かの一助になれば。
データベースって言っても、今回のようにSupabaseもデータベースだし、Google Spread Sheetsをデータベースとして見立てた方がいいよねとか、いろんなケースがあって、何を選べばいいのかが、意外と難しいですよね。データベースの設計から運用まで、今回のようなちょっと外れたことまで、私の得意かつ好きな範疇ですので、なにかご相談があればご遠慮なくお声がけください。
では、よきアクティベートライフを!