Nitro + Drizzleプロジェクトで使用していたPlanetScaleを、Dockerで構築したMySQL環境に移行する
こんにちは、合同会社Stegの @keigo です。今回は、Nitro + Drizzle + PlanetScaleの組み合わせで構築されたWebバックエンドアプリケーションのデータベースを、PlanetScaleの利用をやめてオンプレミスのMySQL環境へ移行した際の作業について紹介します。
なお、MySQL環境はDockerを利用して構築します。
背景
PlanetScaleは、2024/4/8をもって無料で使えるHobbyプランが廃止されます。
お金を払ってでも使いたいくらい素晴らしいサービスですが、立ち上げたばかりのプロジェクトであるということから、ランニングコストをなるべく抑える目的で、データベースは別の方法で構築することにします。
検討した移行先
マネージドサービス
- Supabase Database
- Cloudflare D1
- Vercel Postgres
- Neon
非マネージドサービス
- VPSやVM等にMySQLサーバを直接インストール
- VPSやVM等にDockerコンテナの形でMySQLサーバを構築
上記に挙げたマネージドサービスは全てPostgreSQL互換であったため、VPSやVM等にDockerコンテナの形でMySQLサーバを構築することにしました。
移行作業
移行前は、MySQLベースのPlanetScaleに対し、DrizzleというORMを使用して接続していました。DrizzleにはPlanetscale用のクライアント実装が用意されています。
接続設定のソースコードは以下の通りです。
// db/index.ts
import { connect } from "@planetscale/database";
import { drizzle } from "drizzle-orm/planetscale-serverless";
import * as schema from "./schema";
const runtimeConfig = useRuntimeConfig();
const conn = connect({
host: runtimeConfig.DATABASE_HOST,
username: runtimeConfig.DATABASE_USERNAME,
password: runtimeConfig.DATABASE_PASSWORD,
});
export const db = drizzle(conn, {schema});
接続設定はこの1つのファイルで完結しているため、この接続設定を変更するだけで、アプリケーションのコードを変更することなく移行作業を完了することができます。
MySQLの環境をDockerで構築し、接続先の情報を取得
compose.yamlを以下のように作成します。
version: '3.8'
services:
db:
image: mysql:8.3.0
container_name: database_container
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: example
MYSQL_USER: example
MYSQL_PASSWORD: example
ports:
- "3306:3306"
volumes:
- database_data:/var/lib/mysql
volumes:
database_data:
以下のコマンドで立ち上げれば、3306番ポートでMySQLサーバにアクセスできるようになります。
docker compose up
drizzle.config.tsファイルを作成
各設定項目は、プロジェクトのディレクトリ構造に合わせて適宜変更してください。
import 'dotenv/config';
import type { Config } from 'drizzle-kit';
export default {
schema: './db/schema.ts',
out: './drizzle',
driver: 'mysql2',
dbCredentials: {
host: 'localhost',
user: 'xxx',
password: 'xxx',
database: 'xxx',
port: 3306,
},
} satisfies Config;
接続部分のコードを修正する
これまでデータベースとの接続に@planetscale
ライブラリやdrizzle-orm/planetscale-serverless
を使用していましたが、これらをmysql2
クライアントを利用した接続に切り替えます。
import mysql, { type ConnectionOptions } from 'mysql2/promise';
import { drizzle } from "drizzle-orm/mysql2";
import * as schema from "./schema";
const connectionOptions: ConnectionOptions = {
host: 'localhost',
user: 'xxx',
password: 'xxx',
port: 3306,
database: 'xxx',
};
export const connection = await mysql.createConnection(connectionOptions);
export const db = drizzle(connection, {
schema: schema,
mode: 'default'
});
sqlファイルを生成する
schemaファイルをもとに、Migration用のsqlファイルを生成します。
npx drizzle-kit generate:mysql
Migrationを実行
生成したsqlファイルをもとに、Migrationを実行します。tsx
をインストールしていない場合は、インストールが要求されます。
npx tsx db/migrate.ts
実行が正常に完了すると、スキーマ情報に沿ってテーブルやカラムが作成されます。
Drizzle Studioで確認
Drizzle Studioを使用することで、ブラウザ上でデータベースの確認・編集が可能です。
画像は公式サイトから引用
以下のコマンドを使用してDrizzle Studioを起動します。
npx drizzle-kit studio
おわりに
Drizzleが提供するマイグレーション機能を用いることで、データベースの移行を簡単に完了することができました。
元々スキーマファイルが作成されており、移行前後で同じMySQLを使用していたため、作業はスムーズに進みました。
Discussion