🙄

Hasura を本番と開発環境で分けて作業する

2021/03/16に公開

やること

Hasura は GraphQL を用いたデータベースを簡単に構築できるサービスです。お試しなどでは Web 上でそのまま使用するのがとても簡単ですが、規模が大きくなってきたときに本番用と開発用で環境を分けたくなるはずです。

Hasura では Relationships や Permission の情報の Metadata と PostgreSQL への操作の情報である Migration で管理されています。今回はこの2つを完全に分離することを目標として色々試してみました。自分なりにうまくいった方法なので、最適ではないかもしれません。もっと良い方法があったらぜひ教えてほしいです。

バージョン

  • graphql-engine : v2.0.0-alpha.2.cloud.2

Docker を使う方法もありますが、今回は使わずに試しました。

Hasura Cloud でプロジェクトを作成

このページにて、Prod と Dev の2つのプロジェクトを作成します。名前は migrate-test-prodmigrate-test-dev にしました。

そしてプロジェクトをデータベースに接続します。今回は Heroku Database を使用します。

それぞれ別のデータベースが作成されるので、それぞれの名前はバラバラになっています。後々 Dev → Prod へ作業内容を適応することになるので、データベースの名前を統一しておかないと、後々都合が悪くなります。

そこで、一旦 Hasura からデータベースを削除し、再度 Create database から Connect existing database にてデータベースの接続を行います。初回のデータベース作成のタイミングで環境変数に HEROKU_DATABASE_URL が登録されるので、それを用いて URL を指定します。データベース名は default としました。これを Prod と Dev 両方に行います。

これによって、どちらのプロジェクトも default > public > ... にテーブルが作成されるようになります。

ローカルで作業

ここからはローカルで作業を行います。予め Hasura CLI をインストールしておいてください。

Hasura Cloud 上にある Dev プロジェクトをローカルにクローンします。

$ hasura init --endpoint https://開発用エンドポイント.hasura.app
Name of project directory : migrate-test
INFO directory created. execute the following commands to continue:

  cd migrate-test
  hasura console

ディレクトリを変更してコンソールを起動するように促されますが、アクセストークンを指定していないので Permission denied になるので env ファイルを作成します。ここで本番用と開発用の env を次のように作成しました。

├── env
│   ├── .dev.env
│   ├── .prod.env

それぞれの内容は次のようにしました。
プロジェクトにあった環境変数を指定してください。

HASURA_GRAPHQL_ENDPOINT=<YOUR ENDPOINT URL (https://xxxxxxx.hasura.app)>
HASURA_GRAPHQL_ADMIN_SECRET=<YOUR ADMIN SECRET>
HEROKU_DATABASE_URL=<YOUR DATABASE URL (postgres://xxxxxxx)>

config.yaml にも endpoint が存在しており、これは env ファイルと重複するので削除します。

これでコンソールが起動できるようになりました。次のコマンドでローカルで Hasura を起動することができます。起動すると http://localhost:xxxx/ にて Hasura Cloud と同様に操作することができるようになります。

$ hasura console --envfile env/.dev.env

開発環境での操作

users というテーブルを作成してみます。

そして作成したテーブルに Row を2つ追加してみました。ひとつは This is a migration にチェックを入れ、もうひとつはチェックを入れないでみました。この違いは後々見えてきます。

ここまでの作業を行うと、migrate-test/migtations には操作ごとの Migration が保存されていることが確認できます。 users というテーブルが作成されたこと、users に Row が追加されたことが Migration として記録されています。

├── migrations
│   └── default
│       ├── 1615886190534_create_table_public_users
│       │   ├── down.sql
│       │   └── up.sql
│       └── 1615886251074_insert_into_public_users
│           ├── down.sql
│           └── up.sql

これらの変更を本番環境に適応していきます。まずは Dev と Prod の差分を確認してみましょう。

$ hasura migrate status --envfile env/.prod.env --database-name default
VERSION        NAME                       SOURCE STATUS  DATABASE STATUS
1615886190534  create_table_public_users  Present        Not Present
1615886251074  insert_into_public_users   Present        Not Present

Prod では create_table_public_usersinsert_into_public_users の操作がまだ行われていないことが確認できます。

そして次のコマンドにより、これらの変更を本番環境に適応することができます。

$ hasura metadata apply --envfile env/.prod.env
INFO Metadata applied
$ hasura migrate apply --envfile env/.prod.env --database-name default
INFO migrations applied

本番環境に変更が適応したか確認

Hasura Cloud の本番用プロジェクトを確認してみると、ちゃんと users テーブルが作成され、 Row が追加されていることが確認できます。Insert Row の際に This is a migration にチェックを入れたものだけが反映されています。

Discussion