Deployment
Redwoodを作り始めたのは、Jamstack上でフルスタックのWebアプリを簡単に構築してデプロイできるようにするためでした。技術的には前のセクションですでにデプロイしていますが、実際にはまだ動作していません。それを修正しましょう。
Git
チュートリアルの冒頭で、git を使いたくなければ 本当に 使わなくてもいいと言ったのを覚えていますか?しかし、このデプロイについて行きたいのであれば、今すぐ使い始めなければなりません。すみません!チュートリアルを続けたい場合は、変更をコミットして GitHub や GitLab、Bitbucket にプッシュしてください。gitの入門書が必要ですか?私たちが知る中で最も簡単な方法は、GitHub で新しいリポジトリを作成することです。ローカルコードをコミットしてプッシュするために必要なコマンドのリストが表示されます:
ただし git add README.md
ではなく git add .
すれば、コードベース全体が使えるようになります。
The Database
データを保存するために、インターネット上のどこかにデータベースが必要です。これまでローカルで SQLite を使ってきましたが、これから行うデプロイメントでは、SQLite のファイルベースのデータベースを置くことができる永続的なディスクストアはありません。そこで、このチュートリアルのこの部分については、Postgresを使用することにします(Prismaは現在、SQLite、Postgres、MySQL、SQL Serverをサポートしています)。Postgresに慣れていなくても心配ありません。Prismaが重い仕事をすべてやってくれます。私たちは、アプリからアクセスできるように、外部からデータベースを利用できるようにするだけです。
Prismaは一度に1つのデータベースプロバイダしかサポートしておらず、実稼働環境ではSQLiteを使用できずPostgresまたはMySQLに切り替え なければならない ため、この変更を行った後はローカルの開発環境でも同じようにデータベースを変更する必要があります。 ローカル Postgres セットアップ ガイドを参照し、開始してください。
Postgresのインスタンスをすぐに立ち上げることができるホスティングプロバイダがいくつかあります:
ここでは Railway を使います。それは a) 無料で、 b) 超簡単に始められるからで、私達が知る限り一番簡単です。ログインすら不要です!唯一の制限は、アカウントを作成 しない 場合、データベースは1日後に削除されることです。もし、24時間以内にやるべきことをすべて終わらせられると思うのであれば、ぜひやってみてください!そうでなければ、まずアカウントを作成してください。
Railwayのサイトに移動して Start a New Project をクリックします:
そして PostgreSQL をプロビジョニングします:
信じられないかもしれませんが、これで終わりです!接続URLを知りたいので、左側の PostgreSQL をクリックし、次に Connect タブをクリックします。 postgresql://
で始まる Postgres Connection URL をコピーします:
Change Database Provider
私達は Prisma に、これからは SQLite のかわりに Postgres を使うことを伝えないとなりません。 schema.prisma
の provider
を更新します:
provider = "postgresql"
Recreate Migrations
データベースの migration を Postgres互換に再作成しなければなりません。まず Prisma に新しいデータベースの接続先を伝えて、開発環境から接続できるようにします。 .env
ファイルを開いて DATABASE_URL
変数のコメントアウトを解除し、 Railway からコピーした接続URLを貼り付けて、ファイルを保存します。
.env
はデフォルトで git にチェックインされず、どんな状況でもチェックインすべきではありません!このファイルは(データベースの接続URLや、APIキーのような)公開してはいけない機密情報を含みがちです。もしあなたがこのファイルをリポジトリにチェックインし、リポジトリがpublicになると、インターネット上で誰もがあなたの機密情報を知ることができてしまいます!
.env.defaults
ファイルは、一般の人が見ても安全なその他の環境変数(ライブラリやログレベルなどの非センシティブな設定オプションなど)のためのもので、リポジトリにチェックインして他の開発者と共有することを意図しています。
次に api/db/migrations
ディレクトリを完全に削除します。
最後に、実行します:
yarn rw prisma migrate dev
私たちが行ったすべての変更は、1つの新しいマイグレーションファイルに統合され、Railwayデータベースインスタンスに適用されます。このファイルには、 "initial schema" (初期スキーマ) のような名前を付けることができます。
これでデータベースのセットアップは完了です!あとは Netlify に知らせるだけです。
Netlify
というわけで、データベースは決まったのですが、実際にコードをインターネットのどこかに置いておく必要があります。そこで Netlify です。
Netlify をセットアップする前に、 setup コマンドでコードをセットアップする必要があります。セットアップ!
yarn rw setup deploy netlify
これはプロジェクトのルートに netlify.toml
という設定ファイルを追加するもので、そのままでも良いですが、アプリの成長に合わせて微調整することができます(ファイル上部のコメントにある、カスタマイズに関するリソースへのリンクを見てみてください)。これらのコードの変更をコミットして、自分のリポジトリにプッシュするのをお忘れなく。
これで、 Netlify 自体のセットアップが完了しました。
Netlify CLI コマンドを使って、ローカルのプロジェクトディレクトリから直接プロジェクトを build と deploy したくなるかもしれませんが、そうすると デプロイ時や関数実行時のエラーにつながります 。例えば GraphQL サーバに必要な関数においても、他のサーバレス関数でもエラーが発生します。
その主な理由は、これらの Netlify CLI コマンドは単にビルドとデプロイを行うだけだからです -- ローカルでプロジェクトをビルドし、distフォルダをプッシュします。
どういうことかというと、RedwoodJSのプロジェクトをビルドする際、Prismaクライアントはビルド時のOSにマッチしたバイナリで生成される のです -- それはNetlify上で関数を動作させるための OS互換性 があるわけではないのです。Prismaクライアントのエンジンは、OSXなら darwin
、Windowsなら windows
になりますが、 debian-openssl-1.1.x
または rhel-openssl-1.1.x
でなければならないのです。クライアントが非互換の場合、関数実行は失敗します。
そのため、以下の手順で GitHub(または互換性のあるソースコード管理サービス)のリポジトリを Netlify と同期し、CI/CDでデプロイを管理できるようにしてください。
Signup
もしまだであれば Create a Netlify account で Netlify のアカウントを作成してください。サインアップとメールアドレス検証が完了したら、右上の New site from Git ボタンをクリックしてください:
Netlify があなたの git ホスティングプロバイダに接続し、あなたのリポジトリを見つけることを承認してください。デプロイ設定が表示されたら、すべてデフォルトのまま、 Deploy site をクリックします。
Netlify がアプリのビルドを開始し、最終的にデプロイに失敗します。なぜでしょうか?まだデータベースがどこにあるか教えていないからです!
Environment Variables
メインサイトページに戻り、上部の Site settings から Environment Variables に進みます。
Add a Variable をクリックし、ここに Railway から取得したデータベース接続URIを貼り付けます( Key は "DATABASE_URL" です)。
値を貼り付けたら、末尾に ?connection_limit=1
を追加してください。
URIはこのような形式になります: postgresql://<user>:<pass>@<url>/<db>?connection_limit=1
ScopesとValuesはデフォルト値のままでOKです。
Create variable をクリックして次に進みます。
この接続数制限設定は、サーバレス環境でリレーショナルデータベースを利用する際に Prismaが推奨している ものです。
もう一つ環境変数を追加する必要があります。 SESSION_SECRET
は、dbAuth のセッションクッキーを暗号化するための大きな長い文字列です。これは dbAuth をインストールしたときに開発環境に含まれていたものですが、今度は Netlify にそれを伝える必要があります。 .env
ファイルを見ると、一番下にありますが、デプロイ先の環境ごとに一意のものを作りたいです(開発者もそれぞれ一が意の値を持つ必要があります)。新しいものを作成するためのCLIコマンドがありましたね:
yarn rw g secret
それを DATABASE_URL
と一緒に Netlify にコピーします:
Save ボタンをクリックするのを忘れずに。
IT'S ALIVE
ではトップナビから Deploys に移動し、右側の Trigger deploy ドロップダウンを開き、最後に Deploy site を選択します:
運が良ければ(科学的には)成功します! デプロイログページの上部にある Preview ボタンをクリックするか、戻って上部にあるあなたの Netlify サイトのURLをクリックできます。
Preview ボタンでデプロイを表示すると、URLの中に最新のコミットハッシュが含まれていることにがわかります。
Netlify は main
にプッシュするたびにこれらを作成しますが、この正確なコミットしか示さないので、もう一度デプロイして更新しても、何も変化がないでしょう。
あなたのサイトの実際のURL(Netlify のサイトのホームページから得られるもの)は、常に最新の成功したデプロイを表示します。
詳しくは下の Branch Deploys を見てください。
うまくいきましたか?もし About と Concact リンクの下に "Empty" と表示されていれば、うまくいきました!やったー! "Empty" と表示されているのは、新しいデータベース内に何もブログ記事がないからなので、 /admin/posts
に移動していくつかブログ記事を作成し、ホームページに戻って表示されるか見てみましょう。
デプロイに失敗した場合、Netlify のログ出力をチェックして、エラーの意味がわかるか確認してください。デプロイは成功したが、サイトが立ち上がらない場合、Webインスペクタを開いて、エラーを探してみてください。Postgresの接続URLをすべて正しく貼り付けましたか?もし、本当に、本当に困っているのなら、Redwood Community に行って、助けを求めてみてください。
Custom Subdomain
Site Settings > Domain Management > Domains > Custom Domains からサイトが公開されるサブドメインをカスタマイズできます(誰が agitated-mongoose-849e99.netlify.app
を見に行きたがるでしょうか?)。 Options メニューを開き、 Edit site name を選択します。あなたのサイトはすぐに新しいサブドメイン( redwood-tutorial.netlify.app
はもっと素敵です)で利用できるようになるはずです。
サブドメインは Netlify 全体でユニークでなければならないので、blog.netlify.app
恐らくすでに使われていことに注意してください!完全なカスタムドメインを接続することもできます: Add custom domain ボタンをクリックしてください。
Branch Deploys
Netlify のもう一つの素晴らしい機能は Branch Deploys です。ブランチを作成し、それをリポジトリにプッシュすると、Netlify はそのブランチをユニークな URL でビルドし、メインサイトはそのままで変更をテストできるようにします。
あなたのブランチが main
にマージされると、メインサイトへのデプロイが実行され、あなたの変更が世界に公開されるのです。
Branch Deploys を有効にするには、Site settings > Build & deploy > Continuous Deployment に行き、Branches セクションで Edit settings をクリックして Branch deploys を "All" に変更します。また、Deploy previews を有効にすると、あなたのリポジトリに対するプルリクエストに対してプレビューを作成することができます。
また main
ブランチを "lock" することで、プッシュのたびに自動的にデプロイされないようにすることもできます -- この場合はNetlifyのサイトか Netlify CLI から、手動で最新版をデプロイしなければなりません。
Database Concerns
Connections
このチュートリアルでは、サーバレス関数はPostgresデータベースに直接接続します。Postgres は同時に受け付ける接続数に制限があるため、これはスケールしません -- あなたのサイトにトラフィックが殺到して、サーバレス関数の呼び出しが100倍になった場合を想像してみてください。Netlifyは(裏ではAWSは)100以上のサーバレスLambdaインスタンスをスピンアップして、トラフィックを処理します。問題は、それぞれが個別にデータベースに接続し、利用可能な接続の数を使い果たす可能性があることです。適切な解決策は、Postgresの前にコネクションプーリングサービスを置き、Lambdaからそれに接続することです。その方法については、Connection Pooling ガイドを参照してください。
Security
サーバレス関数が実行されるとき、どのようなIPアドレスを持っているか分からないので、データベースは世界に公開する必要があります。ホスティングプロバイダが持っているすべてのIPアドレスのCIDRブロックを取得し、そのリストからの接続のみを許可することはではしますが、これらは通常時間の経過と共に変化するので、それらを同期し続けるのは手間のかかることです。DBのユーザ名とパスワードを安全に保つ限りは安全ですが、これが理想的な解決策でないことは理解しています。
このようなフルスタックJamstackが注目されるようになり、データベースプロバイダがこれらの問題を解決する、より堅牢で安全なソリューションを提供することが期待されます。私たちのチームは、いくつかのプロバイダと密接に協力しており、近い将来、良い知らせをお届けできると思います!
The Signup Problem
セキュリティといえば、私たちのビルドに顕著なセキュリティホールがあることにお気づきかもしれません:誰でも新しいアカウントにサインアップして、ブログの記事を作成することができるのです!これは理想的ではありません。手っ取り早く簡単な解決策は、自分のアカウントを作成した後に signup
ルートを削除することです:そうすれば、サインアップページに誰もアクセスできなくなり、普通の人なら諦めるでしょう。しかし、邪悪なハッカーはどうでしょうか?
dbAuth は、クライアントが呼び出し方を知っているサインアップとログインの API を提供しますが、もし誰かが十分に狡猾であれば、同じエンドポイントに独自の API 呼び出しを行い、サインアップページがなくても新しいユーザを作成することができます!ああああああああ!この長い(でも楽しい!)チュートリアルをようやく終えたので、ちょっと一休みして足を上げませんか?残念なことに、悪者との戦いは決して終わりません。
この穴を塞ぐには、api/src/functions/auth.js
をチェックしてください。ここに dbAuth の設定があります。 signupOptions
オブジェクト、特に handler()
関数をよく見てください。これはサインアップフォームで送信されたユーザデータをどのように扱うかを定義します。もしこの関数がユーザを作成する代わりに false
を返すようにすれば、APIサインアップハックのドアを効果的に閉じられます。
変更をコミットしてリポジトリにプッシュすると、Netlify がサイトを再デプロイしてくれます。ハッキングしている snollygosters のみなさん、お疲れさまでした!