🙆
remix で hyperdrive(PostgreSQL) でローカル開発まで
要約
remix on Cloudflareにて、hyperdrive(PostgreSQL)を使用したローカル開発までのクイックスタートになります。
remixプロジェクトとローカルにPostgreSQLの準備
remixプロジェクトの作成
公式でコマンドが用意されているのでそちらを使用して作成します。
npm create cloudflare@latest -- my-react-router-app --framework=react-router
npm run dev にて起動の確認ができれば完了です。
PostgreSQLの準備
docker-compose.yml を作成していきます。
docker-compose.yaml
version: '3'
services:
postgres:
container_name: sample-db
image: postgres:16.1
ports:
- "5432:5432"
environment:
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "postgres"
docker compose up にて起動しておきます。
drizzleのインストール
ライブラリのインストール
必要なライブラリのインストールを行います。
npm i drizzle-orm postgres dotenv
npm i -D drizzle-kit tsx @types/node
.envの作成
DATABASE_URL='postgresql://postgres:postgres@localhost:5432/postgres'
drizzleのスキーマとconfigの作成
/db/schema.ts
import { pgTable, serial, varchar, timestamp } from "drizzle-orm/pg-core";
export const users = pgTable("users", {
id: serial("id").primaryKey(),
name: varchar("name", { length: 255 }).notNull(),
email: varchar("email", { length: 255 }).notNull().unique(),
createdAt: timestamp("created_at").defaultNow(),
});
/drizzle.config.ts
import type { Config } from "drizzle-kit"
export default {
out: "./drizzle",
schema: "./db/schema.ts",
dialect: "postgresql",
dbCredentials: {
url: process.env.DATABASE_URL!,
},
} satisfies Config
DBへのアクセスのための値は、環境変数から渡せるようにしています。
tsconfig.node.json の、includeに drizzle.config.ts 追加することで環境変数を読めるようにします。
hyperdriveの設定
wrangler.jsoncの修正
今回のdocker-composeの設定に合わせて、localConnectionStringを追加しています。
wrangler.jsonc
{
"compatibility_flags": [
"nodejs_compat"
],
"compatibility_date": "2024-09-23",
"hyperdrive": [
{
"binding": "HYPERDRIVE",
"id": "<your-hyperdrive-id-here>",
"localConnectionString": "postgresql://postgres:postgres@localhost:5432/postgres"
},
],
}
以下のコマンドを実行し、追加したhyperdrive関連の型を生成します。
npm run cf-typegen
マイグレーション等
あとは以下のコマンドを叩くと、マイグレーションまで行われます。
npx drizzle-kit generate
npx drizzle-kit migrate
初期データの投入
好きなクライアントで、初期データの投入を行なってください。
DBアクセスの処理の作成
インポート系のエラーを解決するために、tsconfig.cloudflare.json のincludeに"db/*"を追加しておきます。
以下のようにhome.tsxにDBへの問い合わせの処理を書きます。
home.tsx
import type { Route } from "./+types/home";
import { Welcome } from "../welcome/welcome";
import postgres from "postgres";
import { drizzle } from "drizzle-orm/postgres-js";
import { users } from "db/schema";
export function meta({}: Route.MetaArgs) {
return [
{ title: "New React Router App" },
{ name: "description", content: "Welcome to React Router!" },
];
}
export async function loader({ context }: Route.LoaderArgs) {
const sql = postgres(context.cloudflare.env.HYPERDRIVE.connectionString, {
max: 5,
fetch_types: false,
})
const db = drizzle(sql)
const allUsers = await db.select().from(users)
console.log(allUsers)
return { message: context.cloudflare.env.VALUE_FROM_CLOUDFLARE };
}
export default function Home({ loaderData }: Route.ComponentProps) {
return <Welcome message={loaderData.message} />;
}
18:41:56 [vite] server restarted.
[
{
id: 1,
name: 'asc',
email: 'asc',
createdAt: 2025-10-25T18:38:03.106Z
},
{
id: 4,
name: 'sc',
email: 'ccc',
createdAt: 2025-10-25T18:38:10.696Z
},
{
id: 5,
name: 'cc',
email: 'sc',
createdAt: 2025-10-25T18:38:10.700Z
},
{
id: 6,
name: 'ccc',
email: 'bb',
createdAt: 2025-10-25T18:38:10.702Z
}
]
ページにアクセスすると、コンソールに表示されましたお疲れ様でした。
参考
Discussion