Hasura を本番と開発環境で分けて作業する
やること
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-prod
と migrate-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_users
と insert_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