レンタルサーバー(たとえばXサーバー)のMySQLに、他サーバーにデプロイしたNode.jsアプリから接続する方法についてメモ。
前知識
基本的に、どのレンタルサーバーも外部から直接MySQLに接続することは許可していないらしい。
たとえば、ローカルのPCから
mysql -u username -p -h ホスト名 --port 3306 データベース名
みたいなコマンドで直接続することはできません。
おそらく、セキュリティのために以下の設定をしているためだと思われます。
- ファイアウォールでポートを開放していない
- MySQLの設定ファイル(mysqld.cnf)でbind-addressが設定されている
なのでこのような場合、SSH接続してSSH経由でポートフォワーディングしてMySQLの3306番に接続する・・・という手順を踏むと接続できるぽいです。ポートフォワーディングというのは「このポートにアクセスがきたら、このポートに転送してね!」みたいなやつです。
sshコマンドで言うと、以下のとおりです。
ssh -L 3306:localhost:3306 {ユーザー名}@{接続先ホスト} -i {秘密鍵ファイル}
これをNode.jsのプロセス上で実行させたい・・・というのがこの記事の内容です。
tunnel-sshでポートフォワーディング
いろいろ方法はあるっぽいのですが、以下のライブラリを使うと手軽っぽいです。
TypeScriptを使う場合は、以下のDefinitelyTypedが用意されていますが、これは最新版のtunnel-sshに対応していないぽいので使えません。
これを使う場合は古いバージョンを使う必要があります。
ただ、tunnel-sshのissueを見ると、有志の人が「型定義(.d.ts)作ったよ」なコメントしてくれてたので、これを利用します。
作成するファイル
上のissueの内容をもとに型定義ファイルをつくります。
つぎに以下の2つのファイルをつくります。
createSSHTunnelToMySQLPort.ts
import { createTunnel } from "tunnel-ssh"; import fs from "fs"; export async function createSSHTunnelToMySQLPort() { const PORT = 3306; //MySQLのポート番号 const TUNNEL_OPTION = { autoClose: true, }; const SERVER_ONTION = { port: PORT, }; const SSH_OPTION = { username: "SSH接続に必要なユーザー名", host: "SSH接続に必要なホスト名",//Xサーバーの場合は「sv○○.xserver.jp」みたいなやつ, port: "SSH接続に必要なポート名", //Xサーバーの場合は10022 privateKey: fs.readFileSync("src/backend/秘密鍵.key"), }; const FORWARD_OPTION = { srcAddr: "localhost", srcPort: PORT, dstAddr: "localhost", dstPort: PORT, }; await createTunnel(TUNNEL_OPTION, SERVER_ONTION, SSH_OPTION, FORWARD_OPTION); }
index.ts
import mysql from "mysql2/promise"; import { createSSHTunnelToMySQLPort } from "src/backend/createSSHTunnelToMySQLPort"; (async () => { await createSSHTunnelToMySQLPort(); const connection = await mysql.createConnection({ host: "localhost", user: "レンタルサーバーのMySQLのユーザー名", password: "レンタルサーバーのMySQLのパスワード", database: "接続するデータベース名", }); const sql = "SELECT * FROM `hoge`"; try { const [result] = await connection.query(sql); console.log(result); connection.destroy(); } catch (error) { console.log("データベースでなんらかのエラー") } })();
そして、レンタルサーバーのMySQL上でhogeというテーブルを作ります。
ここでは以下のようなテーブルにしました(idカラムがあるだけのテーブル)。
CREATE TABLE IF NOT EXISTS `hoge` ( `id` int(40) unsigned DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
そしてレコードも適当にいくつか挿入します。
INSERT INTO `hoge`(`id`) VALUES (1); INSERT INTO `hoge`(`id`) VALUES (2);
この状態で、ローカルでts-node index.ts
を実行すると、以下のような結果になります。
これで、Node.jsからレンタルサーバー上のMySQLにアクセスできたことが確認できました。
余談:ChatGPTに書かせてみた
ChatGPTで、以下のように質問したらすごく良い感じのコードを書いてくれました。
動くかどうかは試してないですが、ザッと見た感じ
- 間違っていたとしても微修正すれば動きそうですし、
- 関数もとてもキレイにかかれてるし、
ChatGPTすげえええええええええってなりました。関数の説明も簡潔で分かりやすいですし、マジですごすぎる。
わざわざ自分で書く必要なかった説・・・。
というか今の時点でこれだけ精度が高いのなら、近いうちに「AIにコードを書かせてエンジニアはコードレビューだけする」みたいな時代が来るんでしょうね確実に。すごい時代だぜ・・・。
おわり
コメント