レンタルサーバー(たとえば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にコードを書かせてエンジニアはコードレビューだけする」みたいな時代が来るんでしょうね確実に。すごい時代だぜ・・・。
おわり
コメント