AstroのSSRでDrizzle経由でCloudflare D1にアクセスする手順
本文書はall in one WebフレームワークのAstroにSSR(Server Side Rendering)を設定した場合にどこにどのようにデプロイすることでインターネット上に公開することができるのかという疑問に答えるために行った動作確認を記事にしています。同じように考えている人がいればぜひ参考にしてください。
利用するプロダクトやサービスは以下の通りです。
- Astro
- Cloudflare Pages
- Cloudflare Workers(Page Functions)
- Cloudflare D1
- Drizzle
最終的にはCloudflare PagesにアクセスしたAstroからDrizzleを経由してCloudflare D1にアクセスを行いD1から取得したデータをブラウザ上に表示するという内容になっています。
Cloudflare D1, Drizzle ORMもどちらも現在開発が活発に進めれている注目度の高いツールなのでこれから耳にする機会も増えることが予想されます。
それぞれの個別の機能については本サイトでも公開済みなので参考にしてみてください。
Astroについてはこちらの記事を参考にしてください。
Drizzle ORMの基本的な機能についてはこちらの記事を参考にしてください。
Cloudflareのアカウントの作成などはこちらの記事を参考にしてください。
目次
Cloudflare D1とは
Cloudflara D1はCloudflareが提供するSeverlessのデータベースです。2024年4月に正式にリリースされました。中身はSQLiteデータベースが利用されています。本文書では”alpha”、”beta”とステータスが更新される度にリライトを行っています。現在正式版での動作確認を行っています。
Cloudflare Pagesとは
Cloudflare Pagesにファイルをアップするだけでインターネット上に簡単にコンテンツを公開することができるサービスです。Cloudflare Pagesでは静的なhtmlファイルのみの利用だけではなくReact, VueなどのSPAやNext.js, Remix, Nuxtなどフルスタックフレームワークも動かすことができます。JavaScriptの実行はCloudflareのPage Functions(SeverlessのJavaScriptプラットフォーム)を利用して行われています。
Cloudflare D1もCloudflare PagesもどちらもServerlessなサービスなのでサーバを運用/管理する必要なく構築したサービスを公開することができます。
環境の構築
これから動作確認を行うための環境の構築を行いますがCloudflare Pages, Cloudflare D1を利用するためにはCloudflareのアカウントの作成が必要になります。アカウントの取得が完了しているという前提で進めていきます。
Astroのインストール
“npm create astro@latest”コマンドを利用してAstroのプロジェクトを作成します。コマンドを実行するといくつか質問がありますがプロジェクト名にastro-ssr-cloudflareを設定し、その他のシステムについてはデフォルトを選択しています。
% npm create astro@latest
astro Launch sequence initiated.
dir Where should we create your new project?
./astro-ssr-cloudflare
tmpl How would you like to start your new project?
Empty
██████ Template copying...
deps Install dependencies?
Yes
██████ Installing dependencies with npm...
ts Do you plan to write TypeScript?
Yes
use How strict should TypeScript be?
Strict
██████ TypeScript customizing...
git Initialize a new git repository?
Yes
██████ Git initializing...
next Liftoff confirmed. Explore your project!
Enter your project directory using cd ./astro-ssr
Run npm run dev to start the dev server. CTRL+C to stop.
Add frameworks like react or tailwind using astro add.
Stuck? Join us at https://astro.build/chat
╭──🎁─╮ Houston:
│ ◠ ◡ ◠ Good luck out there, astronaut! 🚀
Cloudeflare Adapterのインストール
AstroのSSRの機能はデフォルトでは有効になっていないので有効化する必要があります。SSRを利用するためには Adapter が必要となるためインストールを行います。AdapterはAstroで構築したアプリケーションをデプロイするサービスによって異なるため適切な Adapter をインストールする必要があります。Cloudflareを利用するのでCloudflare Adapterをインストールします。
% npx astro add cloudflare
Astro will make the following changes to your config file:
╭ astro.config.mjs ──────────────────────────────╮
│ import { defineConfig } from 'astro/config'; │
│ │
│ import cloudflare from "@astrojs/cloudflare"; │
│ │
│ // https://astro.build/config │
│ export default defineConfig({ │
│ output: "server", │
│ adapter: cloudflare() │
│ }); │
╰────────────────────────────────────────────────╯
For complete deployment options, visit
https://docs.astro.build/en/guides/deploy/
インストールが完了するとメッセージにあるようにAstroの設定ファイルであるastro.config.mjsにSSRの設定が追加されます。
import { defineConfig } from 'astro/config';
import cloudflare from "@astrojs/cloudflare";
// https://astro.build/config
export default defineConfig({
output: "server",
adapter: cloudflare()
});
Wranglerのインストール
Cloudflareを操作するために利用するコマンドラインツールのWranglerのインストールを行います。Cloudflareの開発サーバの起動やデータベースの作成、PagesへのデプロイはWranglerコマンドを利用して行います。デプロイの方法にはWranglerだけではなくGitの利用や管理画面上から直接ファイルをアップロードすることでも行うこともできます。
% npm install wrangler
インストールが完了するとwranglerコマンドでバージョンを確認することができます。本文書では wranglerのバージョン 3.22.1を利用します。
% npx wrangler --version
⛅️ wrangler 3.22.1
Drizzle ORMのインストール
データベースを操作するために利用するDrizzle ORMに関係するパッケージのインストールを行います。better-sqlite3は開発時にDrizzleで利用できるGUIのデータベース管理ツールのDrizzle Studioを利用してローカルのDBにアクセスする際に利用します。D1はSQLiteなのでSQLiteのDriverを利用してアクセスすることができます。
% npm install drizzle-orm better-sqlite3
drizzle-kitは定義したスキーマファイルを利用してテーブルを作成/更新するために必要なマイグレーションファイルを作成するためのツールです。
% npm install -D drizzle-kit
package.jsonファイルでここまでにインストールしたパッケージの情報を確認しておきます。
{
"name": "astro-ssr-cloudflare",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/check": "^0.3.4",
"@astrojs/cloudflare": "^8.0.1",
"astro": "^4.0.8",
"better-sqlite3": "^9.2.2",
"drizzle-orm": "^0.29.2",
"typescript": "^5.3.3",
"wrangler": "^3.22.1"
},
"devDependencies": {
"drizzle-kit": "^0.20.9"
}
}
Cloudflare D1のデータベース設定
Cloudflareの管理画面にアクセスを行い現在のD1の画面を確認します。何もデータベースが表示されていないので以下のような画面になります。
データベースの作成はwranglerコマンドを利用して行うことができますcreateの後に設定しているのはデータベースの名前で任意の名前をつけることができます。ここではastro_dbという名前をつけています。はじめてwranglerを実行すると認証画面が表示されます。
% npx wrangler d1 create astro_db
✅ Successfully created DB 'astro_db' in region APAC
Created your database using D1's new storage backend. The new storage backend is not yet recommended for production workloads,
but backs up your data via point-in-time restore.
[[d1_databases]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "astro_db"
database_id = "d507d648-6750-40cf-8237-612b127649e3"
実行後に表示されている情報をプロジェクトフォルダ直下に wrangler.toml ファイルを作成して保存します。wrangler.tomlファイルではnameにはプロジェクトの名前, mainにはastroをビルドした際に作成されるwoker.jsファイルのパス、compatibility_dateは設定日を指定しています。その設定に続いてデータベース作成時に表示されたメッセージの最後のデータベースの情報を追加します。
[[d1_databases]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "astro_db"
database_id = "d507d648-6750-40cf-8237-612b127649e3"
preview_database_id = "DB"
ブラウザからCloudflareのD1の情報を確認するとastro_dbが作成されていることが確認できます。
データベースをCloudflare上に作成することができたので、動作確認用にローカルにデータベースファイルとテーブルを作成していきます。
Drizzleによる設定
データベースのテーブルを作成する際に利用するsql文を作成するためにsrcフォルダの中にdbフォルダを作成しテーブルのスキーマ情報を記述したschema.tsファイルを作成します。
import { text, integer, sqliteTable } from 'drizzle-orm/sqlite-core';
export const todos = sqliteTable('todos', {
id: integer('id', { mode: 'number' }).primaryKey({ autoIncrement: true }),
name: text('name'),
isCompleted: integer('isCompleted'),
});
テーブルの名前は todos で id, name と isCompleted で構成されています。
drizzle-kit を利用することで schema.ts ファイルに記述した内容を元にマイグレーションファイルの作成することができます。
% npx drizzle-kit generate:sqlite --schema=./src/db/schema.ts
drizzle-kit: v0.20.9
drizzle-orm: v0.29.2
1 tables
todos 3 columns 0 indexes 0 fks
[✓] Your SQL migration file ➜ drizzle/0000_sparkling_iron_monger.sql 🚀
コマンドを実行するとプロジェクトフォルダ直下に drizzle フォルダが作成され中身は DDL(Data Definition Language)が記述された sql ファイルが作成されます。ファイル名は自動で付与されるので実行する度に異なる名前が付けられます。schema.ts ファイルのスキーマ情報を元に SQLite 用の DDL が作成されています。
CREATE TABLE `todos` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`name` text,
`isCompleted` integer
);
todos テーブルの作成
drizzle-kit によって生成された sql ファイルを利用してローカルにデータベースファイルとテーブルを作成します。
データベースとテーブルの作成にはwrangelerコマンドを利用します。オプションのファイルにはdrizzle-kitで作成したsqlファイルを指定しています。
% npx wrangler d1 execute astro_db --local --file=./drizzle/0000_sparkling_iron_monger.sql
🌀 Mapping SQL input into an array of statements
🌀 Executing on local database astro_db (49f92cbf-926c-429c-ba7e-35f7b1993e3d) from .wrangler/state/v3/d1:
.wrangler/state/v3/d1/miniflare-D1DatabaseObject/ディレクトリにSQLite のデータベースファイルに関するファイルが3つ作成されていることが確認できます。
データベースの作成が完了したらDrizzle Studioを利用して作成したデータベースへのアクセスを行います。
Drizzle Studioを利用してデータベースにアクセスするためにDrizzleの設定を行う必要があるためプロジェクトディレクトリの直下にdrizzle.config.tsファイルを作成します。driverには最初にdrizzleとインストイールしたbetter-sqliteを設定しています。各自の環境に合わせて設定を行う必要があります。特にurlは長いので間違えないように注意してください。
import type { Config } from 'drizzle-kit';
import * as dotenv from 'dotenv';
dotenv.config();
export default {
schema: './src/db/schema.ts',
out: './drizzle',
driver: 'better-sqlite',
dbCredentials: {
url: '.wrangler/state/v3/d1/miniflare-D1DatabaseObject/0a5485f987b9f0dae55c988914c46780e9e66a8a2fdd6ed5422c5dddc13755f4.sqlite',
},
} satisfies Config;
Drizzle Studioは”npx drizzle-kit studio”で起動します。
% npx drizzle-kit studio
drizzle-kit: v0.20.9
drizzle-orm: v0.29.2
No config path provided, using default path
Reading config file '/Users/mac/Desktop/agreeable-accretion/drizzle.config.ts'
[Warning] Drizzle Studio is currently in Beta. If you find anything that is not working as expected or should be improved, feel free to create an issue on GitHub: https://github.com/drizzle-team/drizzle-kit-mirror/issues/new or write to us on Discord: https://discord.gg/WcRKz2FFxN
Drizzle Studio is up and running on https://local.drizzle.studio
データベースに作成済みのテーブル一覧が表示されます。
テーブル一覧からtodosをクリックするとtodosテーブルの中身を確認することができます。
データ挿入の確認
wrangler コマンドを利用して todos テーブルの中にデータを挿入します。
% npx wrangler d1 execute astro_db --local --command="insert into todos (name,isCompleted) values('Learn D1',false)"
🌀 Mapping SQL input into an array of statements
🌀 Executing on local database astro_db (d507d648-6750-40cf-8237-612b127649e3) from .wrangler/state/v3/d1:
データが挿入されたか確認するために select 文を利用してデータを取得します。
% npx wrangler d1 execute astro_db --local --command='SELECT * FROM todos'
🌀 Mapping SQL input into an array of statements
🌀 Executing on local database astro_db (d507d648-6750-40cf-8237-612b127649e3) from .wrangler/state/v3/d1:
┌────┬──────────┬─────────────┐
│ id │ name │ isCompleted │
├────┼──────────┼─────────────┤
│ 1 │ Learn D1 │ 0 │
└────┴──────────┴─────────────┘
上記のように表示されれば問題なくデータの挿入が行われています。
Drizzle Studioでもデータの追加が反映されています。
wrangler コマンドからデータの挿入や取得が行えることが確認できました。
toml ファイルがない場合のエラー
cloudflare にデータベースを作成した際に wrangler.toml ファイルを作成しましたが wrangeler.toml ファイルが存在しない場合に wrangler コマンドを実行すると下記のエラーメッセージが表示されます。wrangler.toml ファイルに記述した内容が必須であることがわかります。
✘ [ERROR] Can't find a DB with name/binding 'astro_db' in local config. Check info in wrangler.toml...
AstroからDrizzleを利用した場合
wranglerコマンドを利用してデータベースへのアクセス方法は確認できたのでAstroのコンポーネントファイルからDrizzleを利用してデータベースのアクセスを行います。
Astro.localsからの環境変数へのアクセス
Drizzleのマニュアルを確認するとDrizzleからのCloudflareへのD1への接続例としてWorkersでのコードが記述されています。drizzleからD1にアクセスするためにはenvの情報が必要であることがわかります。
import { drizzle } from 'drizzle-orm/d1';
export interface Env {
<BINDING_NAME>: D1Database;
}
export default {
async fetch(request: Request, env: Env) {
const db = drizzle(env.<BINDING_NAME>);
const result = await db.select().from(users).all()
return Response.json(results);
},
};
AstroのドキュメントにはAstro.localsからのruntimeのアクセスされたに環境変数(env)へのアクセス方法が記述されています。
---
const runtime = Astro.locals.runtime;
---
<pre>{JSON.stringify(runtime.env)}</pre>
pagesフォルダのindex.astroでAstro.localsからruntimeにアクセスが可能なのか確認を行います。
---
console.log(Astro.locals.runtime)
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Todo一覧</h1>
</body>
</html>
env.d.tsファイルに型情報を追加する必要があります。
/// <reference types="astro/client" />
type Runtime = import("@astrojs/cloudflare").AdvancedRuntime<ENV>;
declare namespace App {
interface Locals extends Runtime {}
}
“npm run dev”コマンドを実行して localhost:4321 にアクセスするとターミナルには”undefined”が表示されます。
開発サーバの起動
環境変数の値を取得するためにはCloudflare Worker用の開発サーバを起動する必要があります。開発サーバを起動するために先にビルドを行なっておく必要があります。
% npm run build
実行するとImage Optimizationについての警告メッセージが表示されます。CloudFlareではAstroのビルトインのImage Optimizationをサンポートしていないためです。CloudflareのCloudflare Image Resizingは利用することができます。
[WARN] [@astrojs/cloudflare] The current configuration does not support image optimization. To allow your project to build with the original, unoptimized images, the image service has been automatically switched to the 'noop' option. See https://docs.astro.build/en/reference/configuration-reference/#imageservice
Cloudflare Image Resizingを利用しない場合はastro.confijg.mjsでimageServiceの値をpassthroughに変更することでエラーメッセージは表示されなくなります。
import { defineConfig, passthroughImageService } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';
// https://astro.build/config
export default defineConfig({
output: 'server',
adapter: cloudflare(),
image: {
service: passthroughImageService(),
},
});
ビルドを実行するとdistディレクトリが作成され、_router.json, _workder.js, favicon.svgファイルの3が作成されます。
ビルド後は開発サーバを起動するために”wrangler pages dev”コマンドを実行します。
% npx wrangler pages dev ./dist
//略
Your worker has access to the following bindings:
- D1 Databases:
- DB: astro_db (d507d648-6750-40cf-8237-612b127649e3)
⎔ Starting local server...
[wrangler:inf] Ready on http://localhost:8788
実行するメッセージの中にデータベースの情報も表示されています。http://localhost:8788で開発サーバが起動するのでブラウザからhttp://localhost:8788にアクセスするとTodo一覧の文字列がブラウザ上に表示されコマンドを実行したターミナルにはruntimeオブジェクトの値が表示されます。その中にenvの情報を確認することができます。
env: { ASSETS: Fetcher {}, DB: D1Database { fetcher: [Fetcher] } },
runtime.env に含まれるDBをdrizzle関数の引数に設定してtodosテーブルにアクセスしてデータを取得します。
---
import { drizzle } from "drizzle-orm/d1";
import { todos } from "../db/schema";
const db = drizzle(Astro.locals.runtime.env.DB);
const result = await db.select().from(todos).get();
console.log(result)
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Todo一覧</h1>
</body>
</html>
envの型情報がanyになっているのでenv.d.tsファイルに環境変数の型情報を追加します。
/// <reference types="astro/client" />
type D1Database = import("@cloudflare/workers-types").D1Database;
type ENV = {
DB: D1Database;
};
type Runtime = import('@astrojs/cloudflare').AdvancedRuntime;
declare namespace App {
interface Locals extends Runtime {}
}
設定変更後は再度ビルド(npm run build)コマンドを実行して”wrangler pages dev”を実行します。
開発サーバにアクセスするとコマンドを実行したターミナルにtodosテーブルの中身が表示されます。
{ id: 1, name: 'Learn D1', isCompleted: 0 }
ブラウザ上でのデータ表示
ブラウザ上にデータベースから取得したデータが表示できるようにdrizzle経由でtodos内に保存されたすべてのデータをallメソッドで取得してmap関数で展開して表示させます。
---
import { drizzle } from "drizzle-orm/d1";
import { todos } from "../db/schema";
const db = drizzle(Astro.locals.runtime.env.DB);
const result = await db.select().from(todos).all();
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Todo一覧</h1>
<ul>
{result.map((todo) => <li>{todo.name}</li>)}
</ul>
</body>
</html>
更新が完了したら”npm bun build && npx wrangler pages dev ./dist”を実行します。
開発環境ですが SQLite のデータベースに保存されたデータをブラウザ上に表示することができました。
Server Endpoints での動作確認
Astro コンポーネント上からデータベースへのアクセスを確認しましたが、Server Endpoints(API Routes)からのデータベースへのアクセスの設定も確認しておきます。
pagesディレクトリにtodos.ts ファイルを作成します。GET関数の引数から受け取ったlocalsに含まれる環境変数を利用することができます。その他のコードは Astro コンポーネントの時と変わりません。
import type { APIContext } from "astro";
import { drizzle } from "drizzle-orm/d1";
import { todos } from "..//db/schema";
export async function GET({ locals }: APIContext) {
const db = drizzle(locals.runtime.env.DB);
const result = await db.select().from(todos).all();
return new Response(JSON.stringify(result), {
status: 200,
headers: {
"Content-Type": "application/json",
},
});
}
ビルドと開発サーバを起動(“npm bun build && npx wrangler pages dev ./dist”)させてブラウザから直接http://localhost:8788/todosにアクセスするとブラウザ上にはtodsテーブルに保存されていた内容が表示されます。
[{"id":1,"name":"Learn D1","isCompleted":0}]
Astroの開発環境でDrizzle ORMを経由してCloudflareのD1にアクセスする方法を理解することができました。
しかしここでローカル環境でも必ず”npm run build”を毎回実行する必要があるのかと疑問に思った人もいると思います。次の章では”npm run dev”コマンドで環境変数envにアクセスする方法を確認していきます。
ローカル環境(npm run dev)での環境変数へのアクセス
astro.config.mjsファイルのruntimeの設定でmodeを”local”に設定します。”local”に設定することでローカル環境でもruntimeにアクセスすることが可能になります。
index.astroを先ほどのコードのまま”npm run dev”コマンドを実行します。
---
import { drizzle } from "drizzle-orm/d1";
import { todos } from "../db/schema";
const db = drizzle(Astro.locals.runtime.env.DB);
const result = await db.select().from(todos).all();
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Todo一覧</h1>
<ul>
{result.map((todo) => <li>{todo.name}</li>)}
</ul>
</body>
</html>
“npm run dev”コマンドを実行するとhttp://localhost:4321で開発サーバが起動します。
% npm run dev
> astro-ssr-cloudflare@0.0.1 dev
> astro dev
astro v4.0.8 ready in 424 ms
┃ Local http://localhost:4321/
┃ Network use --host to expose
ブラウザからhttp://localhost:4321にアクセスするとターミナルには”[ERROR] D1_ERROR: no such table: todos”のエラーが表示されます。ローカル環境でもruntime.envから環境変数を取得してデータベースへの接続が行われていることがわかります。その証拠に.wranger/stat/v3/d1/miniflare-D1DatabaseObjectの下に新たに別のファイルが作成されています。
drizzle.config.tsファイルのdbCredentialsのurlの値を新しく作成されたファイルのパスに変更してDrizzle Studioからアクセスするとアクセスできますがテーブルが存在してない状態です。
テーブルを作成するために先ほど利用したテーブル作成のコマンドを実行します。table ‘todos”が存在するとエラーが発生します。
% npx wrangler d1 execute astro_db --local --file=./drizzle/0000_ambitious_cammi.sql
🌀 Mapping SQL input into an array of statements
🌀 Executing on local database astro_db (d507d648-6750-40cf-8237-612b127649e3) from .wrangler/state/v3/d1:
✘ [ERROR] table `todos` already exists
wrangler.tomlファイルにpreview_database_idを追加します。
[[d1_databases]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "astro_db"
database_id = "d507d648-6750-40cf-8237-612b127649e3"
preview_database_id = "DB"
再度実行するとtodosテーブルが作成されます。
% npx wrangler d1 execute astro_db --local --file=./drizzle/0000_ambitious_cammi.sql
🌀 Mapping SQL input into an array of statements
🌀 Executing on local database astro_db (DB) from .wrangler/state/v3/d1:
“npm run dev”コマンドを実行すると”[ERROR] D1_ERROR: no such table: todos”のエラーが表示されなくなります。
テーブルに行を追加します。
% npx wrangler d1 execute astro_db --local --command="insert into todos (name,isCompleted) values('Learn D1 dev',false)"
追加にブラウザにアクセスすると”Learn D1 dev”が表示されます。
先ほどのエラーとは別に下記のメッセージが表示されているので.dev.varsファイルをプロジェクトディレクトリの直下に作成して環境変数を設定するとlocals.runtime.envからアクセス可能となります。
[@astrojs/cloudflare] There is no `.dev.vars` file in the root directory, if you have encrypted secrets or environmental variables you Cloudflare recommends to put them in this file
この後、”npm run build && npx wrangler pages dev ./dist”を実行してlocalhost:8788にアクセスすると先ほど追加した”Learn D1 dev”がブラウザ上に表示されます。
“npm run build”を実行しなくても”npm run dev”でデータベースに保存されたデータにアクセスできるようになりました。
デプロイ
テーブルの作成
開発環境ではなく本番環境の Cloudflare の D1 にテーブルを作成します。開発環境で実行した wrangler コマンドから—local を削除して実行します。
% npx wrangler d1 execute astro_db --file=./drizzle/0000_sparkling_iron_monger.sql
🌀 Mapping SQL input into an array of statements
🌀 Parsing 1 statements
🌀 Executing on remote database astro_db (49f92cbf-926c-429c-ba7e-35f7b1993e3d):
🌀 To execute on your local development database, pass the --local flag to 'wrangler d1 execute'
🚣 Executed 1 commands in 0.8099ms
Cloudflare の管理画面から astro_db の中身を確認すると todos テーブルが作成されていることが確認できます。
データの挿入
Cloudflare D1 上にデータの挿入を行います。wrangler コマンドを利用しますが開発環境で実行したコマンドから—local をなくしています。
% npx wrangler d1 execute astro_db --command="insert into todos (name,isCompleted) values('Learn D1',false)"
🌀 Mapping SQL input into an array of statements
🌀 Parsing 1 statements
🌀 Executing on remote database astro_db (49f92cbf-926c-429c-ba7e-35f7b1993e3d):
🌀 To execute on your local development database, pass the --local flag to 'wrangler d1 execute'
🚣 Executed 1 commands in 0.1632ms
Cloudflare の管理画面上から挿入したデータを確認することができます。
デプロイの実行
Astro のビルドデータを Cloudflare にデプロイするためにビルドコマンドを実行します。
% npm run build
ビルドが完了したら wrangler pages deploy コマンドを利用してビルド後に作成された dist フォルダの中身を Cloudflare にデプロイ(アップロード)します。最初のデプロイではプロジェクトの名前などを聞かれるので設定を行ってください。
% npx wrangler pages deploy dist
✔ Enter the name of your new project: … astro-ssr
✔ Enter the production branch name: … master
✨ Successfully created the 'astro-ssr' project.
▲ [WARNING] Warning: Your working directory is a git repo and has uncommitted changes
To silence this warning, pass in --commit-dirty=true
🌎 Uploading... (2/2)
✨ Success! Uploaded 2 files (1.54 sec)
✨ Compiled Worker successfully
✨ Uploading Worker bundle
✨ Uploading _routes.json
✨ Deployment complete! Take a peek over at https://ab994531.astro-ssr-1iv.pages.dev
デプロイは問題なく完了しましたが表示されたURLにアクセスすると”このページは動作していません”というエラーが表示されます。
DB の Binding 設定
Pages にアップしたファイルからデータベースへのアクセスを行うためにはD1 database bindingsの設定を追加する必要があります。複数のDBが登録されている場合にPagesがどのデータベースを利用していいのかわからないため環境変数を通して設定するだけです。Workers&PagesのOverviewの画面からプロジェクトの名前をクリックして上部のタブにある Settings をクリックして左側のメニューからFunctionsをクリックします。
表示されているFunctionsの画面をスクロールをしていくとD1 database bindingsの設定項目があるので下記のように設定を行います。
設定後、再度ビルドを行ってデプロイを実行してください。
% npm run build
% npx wrangler pages deploy dist
デプロイが完了すると先ほどとは異なりデータベースのテーブルに保存した内容が表示されます。
Server Endpoint で設定した/api/todos にアクセスしてもテーブルに保存した内容が表示されます。
データの追加
Cloudflare の管理画面上からデータベースのtodosテーブルにデータを追加します。
左側のメニューから D1 をクリックして表示されるastro_dbデータベースをクリックします。テーブルの一覧が表示されるのでtodosをクリックするとtodosテーブルに保存されている内容が表示されます。右上にある”Add data”をクリックしてデータの追加を行います。
テーブルにデータを追加すると追加したデータが表示されます。
再度デプロイを行った URL にアクセスします。SSR の設定なのでアクセスの度にデータベースへのアクセスが行われるため追加したデータが表示されます。
本番環境でも動作することが確認できました。
ここまでの設定で Astro + Drizzle ORM + CloudFlare D1 + CloudFlare Pages の環境で動作することが確認できました。
静的ファイルの追加
/aboutページはSSRではなく静的ファイルとして作成しておきたい場合はpagesディレクトにabout.astroファイルを作成してprerenderの値をtrueにします。
---
export const prerender = true;
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>About</h1>
</body>
</html>
ビルドを実行します(npm run build)。distディレクトリを確認するとaboutディレクトリの中にindex.htmlファイルが作成されていることが確認できます。このように静的ファイルの場合はhtmlファイルが作成されます。デプロイするとブラウザ上には”About”が表示されます。
C3 (create-cloudflare-cli)コマンド
Astro プロジェクトの作成は npm create cloudflare コマンドでも実行することができます。npm create cloudflare コマンドを利用することで Astro, Cloudflare Adapter, Wrangler を一緒にインストールすることができます。さらに package.json ファイルにはいくつかのコマンドが含まれているので開発サーバの起動やデプロイを簡単に行うことができます。
{
"name": "quiet-wave-0d5d",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro",
"pages:dev": "wrangler pages dev --compatibility-date=2023-06-15 --proxy 3000 -- astro dev",
"pages:deploy": "astro build && wrangler pages publish ./dist"
},
"dependencies": {
"@astrojs/cloudflare": "^6.5.0",
"astro": "^2.6.4"
},
"devDependencies": {
"wrangler": "^3.1.0"
}
}
npm create cloudflare では Astro 以外の Web フレークワークにも対応しています。
- Angular
- Astro
- Docusaurus
- Gatsby
- Hono
- Next
- Nuxt
- Qwik
- React
- Remix
- Solid
- Svelte
- Vue
フレームワークの選択は”npm create cloudflare”コマンドを実行後に”What type of application do you want to create?”を聞かれるので”Website or web app”を選択すると選択できるフレームワーク一覧が表示されるのでこれから構築したいフレームワークを選択してください。