Render.com に PostgreSQL を使った Web アプリを載せるには ~環境変数, set, export~
プログラム自学案内の 37 回目です。今回は、PostgreSQL を使った Web アプリを、Render.com を使って公開します。 これまでの記事はこちら。
これまでの記事のおさらい
これまでの記事では、Web 技術および DB 技術、その連携の方法を紹介してきました。 なかなかいいものが出来たはずなのですが、これを自分のパソコンでしか動かせない※のが寂しいところです。 (※ ただし、以前の記事で紹介した方法で、同じWifi に接続するパソコンやマシンからなら、動きを見ることができます。)
今回の記事では、いよいよこの連載のひとつの到達点として、PostgreSQL を用いた Web アプリを、ネットに公開して全世界のどこからでもさわれるようにします。例によって無料で使える render.com を利用します。
render.com への Web アプリのデプロイのしかたは以前の記事で紹介していますので、render.com のアカウントをすでに持っている(利用者登録が済んでいる)前提でこの記事はすすめます。
render.com に PostgreSQL DB を作る
DB を作る
まずは render.com にログインし、PostgreSQL DB をつくってみます。直感的な操作で簡単に作れるはずですので、あんまり手取り足取りは説明しません。
Regionは WebアプリをデプロイするWebサーバーと同じ場所を選びます。また、PostgreSQL Version は自分のPCに入っている PostgreSQLのバージョンと同じものを選ぶのが、まちがいないでしょう。
赤い線で示した通り、無料版ですと、残念ながら 90 日経つと DB が消されてしまいますので覚えておいてください。まあ、勉強やお遊びのためなら、十分でしょう。
Create Databaseボタンを押せば、PostgreSQLがあっけなく作られるはずです。
DB につないでみる
作られた DB には、psql からアクセスできます。接続するために必要な情報は画面ですぐに見つかるはずです。
Mac であれば 「PSQL Command」 をコピーし、ターミナルにそのまま貼りつければつながるはずです。
Windows の場合は、こんなかんじで PSQL Command のうちパスワードの部分を抜いたコマンドを実行し、パスワードが求められたら Password をコピペすればいけます。
psql -h xxxxxxxx.singapore-postgres.render.com -U watanabe mydb_rglk
DB に接続できたでしょうか。
DB を操作してみる
DBに接続できたいまの状況を確認してみましょう。いま、自分のパソコンにあるデータベースクライアントのpsqlと、render.comにある PostgreSQL が接続されています。いまから、render.com の DBを操作します、すなわち、この節でやろうとしているのは、こういうことです。
コマンドラインシェルで作業するときに、パソコンはこの絵を見せてくれません。
ですが、コマンドラインシェルの出力が「どこで何が起きている」ことを示すのか、コマンドラインシェルで与える指示が「どこの何に対する」指示なのか、常に上の絵のようなイメージをしながら作業するようにしましょう。そうしないと、後でこんがらがってきます。
では、アプリが利用する磯野家テーブルを作ってしまいましょう。 こちらの記事で紹介した磯野家SQL をそのままpsqlにコピペします。 また、自分でさらにSQL文を追加実行しても構いません。
クラウドの PostgreSQL DB にアプリをつなげる
つぎに、前回まで作ってきたExpress.jsアプリの接続先を変えて動かしてみましょう。DBの接続情報をrender.comに変えます。すなわち、やろうとするのはこういうことです。
コード例を次に示します。
db/index.js
const pool = new pg.Pool({
// Render.comのDBの接続情報に変える
database: "mydb_rglk",
user: "watanabe",
password: "xxxxxxxxxxxxxxxxxxxxxxxx",
host: "xxxxx.singapore-postgres.render.com",
// Render.comのDBではSSLが求められる
ssl: {
rejectUnauthorized: false, // 証明書の検証はいったん無しで
},
max: 10,
});
ちょっと面倒くさい話ですが、render.comのPostgreSQLは SSLを要求するので、上のコード例のように、追加でSSL設定が必要になります。
うまく繋がりましたか?これがうまく繋がれば、あとはこのExpress.jsアプリを Render.com に公開すれば終わりです。そのやりかたは、以前の記事で紹介したとおりです。と言いたいところですが、ちょっと待ってください!
Programmatic Connecting の弱点
const pool = new pg.Pool({
database: "mydb_rglk",
user: "watanabe",
password: "xxxxxxxxxxxxxxxxxxxxxxxx",
host: "xxxxx.singapore-postgres.render.com",
ssl: {
rejectUnauthorized: false
},
max: 10,
});
この接続の方法は node-postgresのマニュアルでは "Programmatic Connecting" として紹介されています。私はこの方法を以前、 node-postgres の紹介記事で、一番手っ取り早い素人向けの方法 として紹介しました。その素人向けの方法の弱点がいま、露わになろうとしています。
弱点1 自分の PC で動かす用と、Render.com で動かす用、別々のプログラムを準備しなければならない
さきほどは試しに自分のPCにあるアプリからRender.comのDBにつなぎましたが、多くの場合は、自分のパソコンのDBに読み書きするプログラムと、Render.comのDBにに読み書きするプログラムを、それぞれ別に動かしたくなることがほとんどです。
そういうとき、プログラムの場所ごとに、DBの接続先を変えるのが一般的です。
自分の PC で動かすために、自分の PC で動いている DB につながるプログラムを書く。render.com で動かすために、render.com にある DB につながるプログラムを書く。これって、動かす場所の数だけ、それぞれ別のプログラムが必要になるということになります。
これ、プログラムの管理が大変です。バグがみつかったら、全部のプログラムを直さなければいけない。これはウンザリするようなはなしですね。
また、それぞれ別のプログラムになるので、各プログラムの正しさは、それぞれの場所で動かしてみない限り、検証できないというのもヤッカイな点です。
弱点2 下手するとDB接続パスワードが GitHub で公開されてしまう
上のコード例では、 password: "xxxxxxxxxxxxxxxxxxxxxxxx", とパスワードをマスクして紹介しましたが、実際にはここには本物のパスワードを書くことになります。そして、render.comでこのプログラムを動かすには、パスワードが書かれたプログラムのソースコードをGitHubに載せることになります。
パスワードをGitHubに載せることは極めて危険です。 Privateリポジトリなら良いのでしょうか? 良いのかもしれませんが、ソフトウェアを公開できなくなってしまうというのは、これはこれで大きな制約です。
さて、どうすればよいでしょう? 弱点1 の解決策が、そのまま 弱点2 の解決策にもなります。その解決策が 環境変数による環境設定 を用いるやりかたです。
環境設定という考え方
動かす場所の数だけプログラムを書く?
弱点1 をおさらいしましょう。動かす場所の数だけ、それぞれ別のプログラムが必要になるというのが欠点でした。
プログラムA「僕は自分の PC で動くためのプログラム。localhost のポスグレを読みに行くぞ!」
プログラムB「僕は render.com で動くためのプログラム。render.com のポスグレを読みに行くぞ!」
動かす場所の数だけ、プログラムの代わりに環境設定を書く
この鬱陶しさを解決するのが「環境設定」とか「環境依存設定」とかいうやりかたです。
「郷に入りては郷に従え」ということばがありますが、この教訓を仕組み化してプログラムに持たせたものが環境設定です。プログラムは「環境」に耳を傾けて、自分の振る舞いを決めます。
~ある環境では~
プログラム「僕は郷に入りては郷に従うプログラム。ねえねえ、環境設定くん。いま僕のいる環境では、つなぎ先の DB ってどこにあるんだろ?」
環境設定A「それはね。DB の hostname は localhost。port は 5432。DB 名は mydb で password は P@ssw0rd1234 だよ!」
プログラム「よっしゃわかった! そのポスグレにコネクションを作るぞ!」
~また別の環境では~
プログラム「僕は郷に入りては郷に従うプログラム。ねえねえ、環境設定くん。いま僕のいる環境では、つなぎ先の DB ってどこにあるんだろ?」
環境設定B「それはね。DB の hostname は asdfcasde.render.com。port は 5432。DB 名は mydb_abcd で password は Xca4e3iSpoe だよ!」
プログラム「よっしゃわかった! そのポスグレにコネクションを作るぞ!」
環境設定というやり方は何を解決するか
環境設定というやり方は、各環境の数だけ「環境設定」を準備しなければいけなません。また、それぞれの場所で動かしてみない限り、ちゃんと動くかどうかは分からない点は同じです。
ただ、そこで検証されるのは プログラムの正しさではなくて各環境設定の正しさになります。これがだいぶラクなのですね。弱点1 は解決してしまうのです。
また、環境設定にはパスワードなどのおおっぴらに公開したくない情報をすべて含めることができます。これをGitHubなどで共有するソースコードから外せるため、弱点2 も解決してしまうのです。
環境変数による方法
環境設定の方法はさまざまありますが、ここでは 環境変数(Environment Variable) を用いるやり方を紹介します。
なぜなら、node-postgres や psql には、その機能がすでに備わっているからです。「いま僕のいる実行環境」に PGUSER、PGHOST、PGPASSWORD、PGDATABASE、PGPORT という名前の環境変数があると、node-postgres はその環境変数を用いて接続先 DB を決めます。
プログラム例
PGUSER、PGHOST、PGPASSWORD、PGDATABASE、PGPORT 以外に、SSL通信の有無も切り替えなければいけないのがちょっと厄介ですが、こんな感じになります。
db/index.js
const isDbLocal = ((process.env.PGHOST || "localhost") === "localhost");
function getConfig() {
if (isDbLocal) {
return {
max: 10
};
} else {
return {
max: 10,
ssl: {
rejectUnauthorized: false,
}
};
}
}
const pool = new pg.Pool(getConfig());
上に示したコードのほとんどは、SSL通信の有無を切り替える処理です。node-postgres は環境変数から接続先DBの情報を読むため、プログラムから接続先DBの情報が無くなりました。
ただしその代わりに、環境ごとに環境変数を設定する必要がでてきます。
自分の PC で 環境変数を設定する
環境変数の設定のしかたは、ググると色んなやり方がヒットすると思いますが、私がChatGPTに訊いて得た回答 (https://chat.openai.com/share/66aaf227-390d-4b08-ad62-c2d2e8f2ca19) が、もっともよくまとまっていると思います。
この記事では 一例として Mac の場合を紹介します。ターミナルで以下を実行し各環境変数を設定すると、以降ターミナルを閉じるまで、そのターミナルから実行されたプログラムなら、設定された環境変数を読み取れるようになります。
export PGUSER=dbuser
export PGHOST=database.server.com
export PGPASSWORD=secretpassword
export PGDATABASE=mydb
export PGPORT=3211
render.com で環境変数を設定する
Render.comのWebサービスに環境変数を設定する方法は、画面ですぐに分かるはずです。
Webサービス作成時には、「Advanced」を広げることで設定できます。
あとから環境変数を設定することもできます。
以上、同じプログラムを使って、環境変数により接続先のDBを変えるやり方を紹介しました。
あとは、Express.jsアプリを Render.com に公開すれば終わりです。そのやりかたは、再三申し上げた通り、以前の記事で紹介しました。
ぜひチャレンジしてみてください!
まとめと次回予告
今回の記事では、PostgreSQL を使った Web アプリを、Render.com を使って公開することを通じて、環境設定という考え方や、環境変数について紹介しました。
今回の記事はこれまでの長い連載での一つの到達点と言えると思います。Web アプリを開発するための技術は概ね一通り案内しきりました。ただし、認証認可を除いて。
次回予告です。Web アプリでは避けて通れない、認証認可について案内を始めます。これまた、けっこうウンザリする面倒な話なので、 記事は 3 回くらいに渡ると思います。
#コラム #プログラミング #JavaScript #node -postgres #render .com