見出し画像

Render.com に PostgreSQL を使った Web アプリを載せるには ~環境変数, set, export~

プログラム自学案内の 37 回目です。今回は、PostgreSQL を使った Web アプリを、Render.com を使って公開します。 これまでの記事はこちら。


これまでの記事のおさらい

これまでの記事では、Web 技術および DB 技術、その連携の方法を紹介してきました。 なかなかいいものが出来たはずなのですが、これを自分のパソコンでしか動かせないのが寂しいところです。 (※ ただし、以前の記事で紹介した方法で、同じWifi に接続するパソコンやマシンからなら、動きを見ることができます。)

自分のパソコンでWebアプリを動かすことはできた

今回の記事では、いよいよこの連載のひとつの到達点として、PostgreSQL を用いた Web アプリを、ネットに公開して全世界のどこからでもさわれるようにします。例によって無料で使える render.com を利用します。

Webアプリをネットに公開して、どこからでも使えるようにする

render.com への Web アプリのデプロイのしかたは以前の記事で紹介していますので、render.com のアカウントをすでに持っている(利用者登録が済んでいる)前提でこの記事はすすめます。

render.com に PostgreSQL DB を作る

DB を作る

まずは render.com にログインし、PostgreSQL DB をつくってみます。直感的な操作で簡単に作れるはずですので、あんまり手取り足取りは説明しません。

New ボタンを押すとPostgreSQLがメニューに現れる
PostgreSQLの基本設定を入力(1/2)

Regionは WebアプリをデプロイするWebサーバーと同じ場所を選びます。また、PostgreSQL Version は自分のPCに入っている PostgreSQLのバージョンと同じものを選ぶのが、まちがいないでしょう。

PostgreSQLの基本設定を入力(2/2)

赤い線で示した通り、無料版ですと、残念ながら 90 日経つと DB が消されてしまいますので覚えておいてください。まあ、勉強やお遊びのためなら、十分でしょう。

Create Databaseボタンを押せば、PostgreSQLがあっけなく作られるはずです。

DB につないでみる

作られた DB には、psql からアクセスできます。接続するために必要な情報は画面ですぐに見つかるはずです。

DBに接続するための情報

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を操作します、すなわち、この節でやろうとしているのは、こういうことです。

自分のパソコンのpsqlから、render.comのPostgreSQLにむけてSQLを発行する

コマンドラインシェルで作業するときに、パソコンはこの絵を見せてくれません。

ですが、コマンドラインシェルの出力が「どこで何が起きている」ことを示すのか、コマンドラインシェルで与える指示が「どこの何に対する」指示なのか、常に上の絵のようなイメージをしながら作業するようにしましょう。そうしないと、後でこんがらがってきます。

では、アプリが利用する磯野家テーブルを作ってしまいましょう。 こちらの記事で紹介した磯野家SQL をそのままpsqlにコピペします。 また、自分でさらにSQL文を追加実行しても構いません。

クラウドの PostgreSQL DB にアプリをつなげる

つぎに、前回まで作ってきたExpress.jsアプリの接続先を変えて動かしてみましょう。DBの接続情報をrender.comに変えます。すなわち、やろうとするのはこういうことです。

自分のPCで動くアプリが、render.comのDBに接続

コード例を次に示します。

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の接続先を変えるのが一般的です。

アプリの動く場所ごとに、アプリは別の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 を決めます。

Express.jsアプリが使う node-postgres は環境変数を参照する

プログラム例

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」を広げることで設定できます。

環境変数を設定しているところ(Webサービス作成時)

あとから環境変数を設定することもできます。

あとから環境変数を設定しているところ

以上、同じプログラムを使って、環境変数により接続先のDBを変えるやり方を紹介しました。

あとは、Express.jsアプリを Render.com に公開すれば終わりです。そのやりかたは、再三申し上げた通り、以前の記事で紹介しました。

ぜひチャレンジしてみてください!

render.comに公開した磯野家プログラム

まとめと次回予告

今回の記事では、PostgreSQL を使った Web アプリを、Render.com を使って公開することを通じて、環境設定という考え方や、環境変数について紹介しました。

今回の記事はこれまでの長い連載での一つの到達点と言えると思います。Web アプリを開発するための技術は概ね一通り案内しきりました。ただし、認証認可を除いて。

次回予告です。Web アプリでは避けて通れない、認証認可について案内を始めます。これまた、けっこうウンザリする面倒な話なので、 記事は 3 回くらいに渡ると思います。

#コラム #プログラミング #JavaScript #node -postgres #render .com

この記事が気に入ったらサポートをしてみませんか?