> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-vortex-format.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloudflare Workers で ClickHouse Managed Postgres を使用する

> Hyperdrive 経由で Cloudflare Worker から ClickHouse Managed Postgres にクエリを実行する方法を、node-postgres の使用、TLS 証明書の検証、ローカル開発、workers.dev へのデプロイまで含めて説明します

export const BetaBadge = ({link, galaxyTrack, galaxyEvent}) => {
  if (link) {
    return <a href={link} target="_blank" rel="noopener noreferrer" className="betaBadge" onClick={galaxyTrack && galaxyEvent ? galaxyOnClick(galaxyEvent) : undefined}>
                <span>ベータ</span>
            </a>;
  }
  return <a href="https://clickhouse.com/docs/reference/settings/beta-and-experimental-features#beta-features" className="betaBadge">
            <span>ベータ機能</span>
        </a>;
};

<BetaBadge link="https://clickhouse.com/cloud/postgres" galaxyTrack={true} galaxyEvent="docs.managed-postgres.guides-cloudflare-workers-beta" />

[Cloudflare Workers](https://developers.cloudflare.com/workers/) はコードを Cloudflare のネットワーク上で実行します。また、[Hyperdrive](https://developers.cloudflare.com/hyperdrive/) はそのネットワークからデータベースへの接続 pool を維持するため、リクエストのたびに TCP および TLS ハンドシェイクを新たに行うコストが発生しません。このガイドでは、インスタンスの証明書を検証する Hyperdrive 設定を作成し、[`node-postgres`](https://node-postgres.com/) (`pg`) を使って行の作成と読み取りを行う TypeScript Worker をビルドします。その後、`wrangler dev` でローカル実行し、`workers.dev` にデプロイします。

<h2 id="prerequisites">
  前提条件
</h2>

* [Cloudflare アカウント](https://dash.cloudflare.com/sign-up)。Hyperdrive は Workers の Free プランと Paid プランのどちらでも利用できます。
* [Node.js](https://nodejs.org/) 20 以降。本ガイドは Node.js 24.21.0、Wrangler 4.145.0、`create-cloudflare` 2.73.1、`pg` 8.23.1、Postgres 18 で動作確認しています。
* ClickHouse Cloud アカウント。
* データベースとテーブルの作成に使用する [`psql`](https://www.postgresql.org/download/)。SQL ステートメントは [SQL コンソール](/ja/integrations/connectors/sql-clients/sql-console) で実行することもできます。

<h2 id="create-service">
  ClickHouse Managed Postgres サービスを作成する
</h2>

ClickHouse Cloud コンソールで **New service** をクリックし、**Postgres** を選択します。インスタンスは数分で利用可能になります。詳しい手順については、[クイックスタート](/ja/products/managed-postgres/quickstart)を参照してください。

<h2 id="connection-details">
  接続情報を取得する
</h2>

サービスの左サイドバーで **Connect** をクリックします。**Directly** を選択したまま、**Use SSL** をオンにします。URL の末尾が `sslmode=verify-full&sslrootcert=<service-name>-ca-certificate.pem` に変わります。**Download CA certificate** をクリックして、インスタンスの CA 証明書をダウンロードします。**Settings → CA Certificate** からもダウンロードできます。

このガイドでは、Hyperdrive の接続先として、ポート `6432` の同梱 PgBouncer ではなく、ポート `5432` の **direct** 接続を指定します。理由は次のとおりです。

* Hyperdrive 自体が、トランザクションモードで動作する接続プーラーです。データベースへの少数の長時間接続を pool として維持し、すべての Worker リクエストで共有します。これは本来 PgBouncer が担う役割です。Cloudflare も、Hyperdrive には pool 経由ではなく直接接続の接続文字列を指定することを推奨しています。
* Hyperdrive の接続先をポート `6432` にしても動作はしますが、トランザクションプーラーを 2 段につなぐと、ネットワークホップが 1 つ増え、pool サイズの調整箇所も 2 か所になるだけで、処理能力は向上しません。
* Hyperdrive が開く接続数は、1 つの設定あたり Workers Free プランで最大約 20、Paid プランで最大約 100 です。これはデフォルトの `max_connections` である 500 の範囲内に収まります。同じインスタンスに複数の Hyperdrive 設定や他のクライアントが接続する場合は、それらの接続数を合計したうえで、必要に応じて [設定](/ja/products/managed-postgres/settings) で `max_connections` を調整するか、Hyperdrive 側でオリジンの接続数上限を調整してください。

<Note>
  [IP アクセスリスト](/ja/products/managed-postgres/security) を使用している場合、Hyperdrive は [Cloudflare の IP 範囲](https://www.cloudflare.com/ips/) から接続するため、これらの範囲を許可しておく必要があります。
</Note>

<h2 id="create-database">
  データベースを作成する
</h2>

ダウンロードした証明書の名前を `ca-certificate.pem` に変更します。次に、データベースと `notes` テーブルを作成します。`<PASSWORD>` とホストは、**Connect** モーダルに表示される値に置き換えてください。

```bash theme={null}
psql "postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:5432/postgres?sslmode=verify-full&sslrootcert=ca-certificate.pem" -c "CREATE DATABASE guide_cloudflare;"
```

```bash theme={null}
psql "postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:5432/guide_cloudflare?sslmode=verify-full&sslrootcert=ca-certificate.pem" -c "CREATE TABLE notes (id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, content text NOT NULL, created_at timestamptz NOT NULL DEFAULT now());"
```

```text theme={null}
CREATE TABLE
```

<h2 id="create-project">
  Worker プロジェクトを作成する
</h2>

`create-cloudflare` を使用して "Hello World" テンプレートから TypeScript の Worker を作成し、`pg` をインストールします。

```bash theme={null}
npm create cloudflare@latest -- hyperdrive-notes --type=hello-world --lang=ts --no-deploy
cd hyperdrive-notes
npm install pg
npm install -D @types/pg
```

<Tip>
  **既存のアプリに追加する場合**

  `npm create cloudflare` は不要です。Worker プロジェクト内で `npm install pg` と `npm install -D @types/pg` を実行したら、[Hyperdrive 設定を作成する](#create-hyperdrive) (Hyperdrive バインディングを追加します) と [Worker を設定する](#configure-worker) (`nodejs_compat` を有効にします) の手順に進んでください。
</Tip>

`ca-certificate.pem` をプロジェクトディレクトリに移動します。Wrangler を初めて使う場合は、`npx wrangler login` を実行し、Cloudflare アカウントで Wrangler を認可してください。

<h2 id="create-hyperdrive">
  Hyperdrive の設定を作成する
</h2>

Hyperdrive はデータベースへの接続を常に暗号化しますが、デフォルトでは証明書をインスタンスの CA で検証しません。`sslmode=verify-full` と同等の検証を行うには、まず CA 証明書を Cloudflare アカウントにアップロードします。

```bash theme={null}
npx wrangler cert upload certificate-authority --ca-cert ca-certificate.pem --name managed-postgres-ca
```

```text theme={null}
Success! Uploaded CA Certificate managed-postgres-ca
ID: <CA_CERTIFICATE_ID>
```

出力に含まれる `ID` を使用して、Hyperdrive の設定を作成します。接続文字列ではポート `5432` と `guide_cloudflare` データベースを指定し、SSL パラメータは含めません。TLS は代わりに `--sslmode` と `--ca-certificate-id` で設定します:

```bash theme={null}
npx wrangler hyperdrive create managed-postgres \
  --connection-string="postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:5432/guide_cloudflare" \
  --ca-certificate-id <CA_CERTIFICATE_ID> \
  --sslmode verify-full \
  --caching-disabled \
  --binding HYPERDRIVE \
  --update-config
```

```text theme={null}
✅ Created new Hyperdrive PostgreSQL config: <HYPERDRIVE_ID>
```

Hyperdriveは、設定の作成時にデータベースへ接続します。`--sslmode verify-full` を指定すると、サーバー証明書がアップロードしたCAによって署名されているか、またホスト名と一致するかを確認します。いずれかのチェックに失敗すると、コマンドは `cert verification failed - unable to get local issuer certificate` などのエラーで失敗し、設定は作成されません。パスワードはプロジェクト内ではなく、Cloudflareアカウント内のHyperdrive設定に保存されます。

`--binding HYPERDRIVE --update-config` を指定すると設定が `wrangler.jsonc` に追加され、Workerから `env.HYPERDRIVE` として参照できるようになります。プロジェクトで `wrangler.toml` を使用している場合、Wranglerはファイルを変更しないため、コマンドが出力する `[[hyperdrive]]` スニペットをファイルに貼り付けてください。

<Tip>
  **クエリキャッシュ**

  Hyperdriveは読み取りクエリの結果をキャッシュできます(デフォルトは60秒)。本ガイドでは `--caching-disabled` を指定してキャッシュを無効にしているため、書き込み直後に読み取ると新しい行が返されます。多少古い結果でも問題ない読み取り中心のクエリには、キャッシュを有効にした2つ目の設定を作成し、両方をバインドすることもできます。詳しくは [Query caching](https://developers.cloudflare.com/hyperdrive/concepts/query-caching/) を参照してください。
</Tip>

<h2 id="configure-worker">
  Worker を設定する
</h2>

`pg` を使用するには Node.js 互換レイヤーが必要です。`wrangler.jsonc` を開き、`compatibility_date` の横に `nodejs_compat` フラグを追加してください。追加後、ファイルの該当部分は次のようになります。

```jsonc title="wrangler.jsonc" theme={null}
{
	"name": "hyperdrive-notes",
	"main": "src/index.ts",
	"compatibility_date": "2026-09-26",
	"compatibility_flags": ["nodejs_compat"],
	"hyperdrive": [
		{
			"binding": "HYPERDRIVE",
			"id": "<HYPERDRIVE_ID>"
		}
	]
}
```

`wrangler.toml` ファイルを使用している場合は、代わりに `compatibility_date` の下に `compatibility_flags = ["nodejs_compat"]` を追加してください。ファイルにすでに `compatibility_flags` がある場合は、そのリストに `nodejs_compat` を追加してください。

`env.HYPERDRIVE` に型が付くように、TypeScript の型定義を再生成します:

```bash theme={null}
npx wrangler types
```

プロジェクトでまだ `@cloudflare/workers-types` パッケージを使用している場合は、`wrangler types` を実行すると、生成された型に切り替える手順が表示されます。

<h2 id="query">
  データベースにクエリを実行する
</h2>

`src/index.ts` を、`POST /notes` でノートを作成し、`GET /notes` ですべてのノートを一覧表示する Worker に置き換えます。既存の Worker を使用している場合は、代わりに `fetch` ハンドラーに同様の `/notes` の処理を追加してください。

```ts title="src/index.ts" theme={null}
import { Client } from "pg";

export default {
	async fetch(request, env, ctx): Promise<Response> {
		const url = new URL(request.url);
		if (url.pathname !== "/notes") {
			return new Response("Not found", { status: 404 });
		}

		// Hyperdrive keeps the connections to Postgres, so a new client per request is cheap.
		const client = new Client({ connectionString: env.HYPERDRIVE.connectionString });
		await client.connect();

		try {
			if (request.method === "POST") {
				// Create
				const { content } = await request.json<{ content: string }>();
				const { rows } = await client.query(
					"INSERT INTO notes (content) VALUES ($1) RETURNING id, content, created_at",
					[content],
				);
				return Response.json(rows[0], { status: 201 });
			}

			// Read
			const { rows } = await client.query("SELECT id, content, created_at FROM notes ORDER BY id");
			return Response.json(rows);
		} finally {
			// Close the client after the response is sent.
			ctx.waitUntil(client.end());
		}
	},
} satisfies ExportedHandler<Env>;
```

`env.HYPERDRIVE.connectionString` が指しているのは Hyperdrive であり、お使いのインスタンスではありません。Worker と Hyperdrive 間の通信は Cloudflare 内部で完結するため、SSL パラメータは不要です。Postgres への検証済みの TLS 接続は Hyperdrive が担います。

<Note>
  Hyperdrive は PgBouncer と同様にトランザクションモードで動作するため、トランザクションごとに Postgres への異なる接続が使われる場合があります。`pg` のパラメータ化クエリ、トランザクション、名前付きプリペアドステートメントはいずれも利用できます。ただし、セッションレベルの `SET` などのセッション状態がクエリ間で保持されることを前提にしないでください。代わりに、トランザクション内で `SET LOCAL` を使用してください。
</Note>

<h2 id="local-development">
  ローカルで実行する
</h2>

`wrangler dev` を使うと、Worker を手元のマシン上で実行できます。ローカル環境では Hyperdrive は接続をプールせず、バインディングは `CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_<BINDING>` で指定されたデータベースに直接接続します。この変数に、`sslmode=verify-full` と CA 証明書のパスを含む直接接続用の接続文字列を設定してから、Worker を起動します。

```bash theme={null}
export CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE="postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:5432/guide_cloudflare?sslmode=verify-full&sslrootcert=ca-certificate.pem"
npx wrangler dev --port 3108
```

```text theme={null}
Found a non-empty CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE variable for binding. Hyperdrive will connect to this database during local development.
...
Ready on http://localhost:3108
```

Wrangler はローカル接続の TLS を処理します。`sslrootcert` は、`wrangler dev` を実行したディレクトリからの相対パスとして解決されます。

<Warning>
  `sslmode` を省略すると、ローカル接続は**暗号化されません**。`sslmode=require` を指定すると暗号化はされますが、証明書は検証されません。必ず `sslmode=verify-full` を `sslrootcert` と組み合わせて使用してください。CA が見つからない、または正しくない場合、リクエストは `Connection terminated unexpectedly` で失敗します。
</Warning>

別の端末を開き、ノートを作成します。

```bash theme={null}
curl -X POST http://localhost:3108/notes -H "Content-Type: application/json" -d '{"content": "Hello from wrangler dev"}'
```

```json theme={null}
{"id":"1","content":"Hello from wrangler dev","created_at":"2026-09-30T16:58:16.232Z"}
```

ノートの一覧を表示します：

```bash theme={null}
curl http://localhost:3108/notes
```

```json theme={null}
[{"id":"1","content":"Hello from wrangler dev","created_at":"2026-09-30T16:58:16.232Z"}]
```

`pg` は `bigint` カラムを文字列として返すため、`id` は `1` ではなく `"1"` になります。

<h2 id="deploy">
  デプロイ
</h2>

Worker をデプロイします。

```bash theme={null}
npx wrangler deploy
```

```text theme={null}
Your Worker has access to the following bindings:
Binding                                   Resource
env.HYPERDRIVE (<HYPERDRIVE_ID>)          Hyperdrive Config

Uploaded hyperdrive-notes (2.35 sec)
Deployed hyperdrive-notes triggers (0.76 sec)
  https://hyperdrive-notes.<your-subdomain>.workers.dev
```

初めて Worker をデプロイする場合は、Wrangler から `workers.dev` サブドメインの登録を求められます。デプロイした Worker を使ってノートを作成します。

```bash theme={null}
curl -X POST https://hyperdrive-notes.<your-subdomain>.workers.dev/notes -H "Content-Type: application/json" -d '{"content": "Hello from Hyperdrive"}'
```

```json theme={null}
{"id":"2","content":"Hello from Hyperdrive","created_at":"2026-09-30T16:58:39.733Z"}
```

ブラウザで `https://hyperdrive-notes.<your-subdomain>.workers.dev/notes` を開くと、2 件のノートが両方表示されます。レスポンスは次のようになります。

```json theme={null}
[{"id":"1","content":"Hello from wrangler dev","created_at":"2026-09-30T16:58:16.232Z"},{"id":"2","content":"Hello from Hyperdrive","created_at":"2026-09-30T16:58:39.733Z"}]
```

<h2 id="verify">
  コンソールで確認する
</h2>

サービスの左サイドバーで **SQL コンソール** を開き、`guide_cloudflare`、`public` の順に展開して、`notes` テーブルをクリックします。2 件のノートが両方とも表示されます。

| id | content | created\_at |
| - | - | - |
| 1 | Hello from wrangler dev | 2026-09-30 16:58:16.232466+00 |
| 2 | Hello from Hyperdrive | 2026-09-30 16:58:39.733203+00 |

<h2 id="clean-up">
  クリーンアップ
</h2>

Cloudflare アカウントで作成したリソースを削除するには、Worker、Hyperdrive の設定、CA 証明書を削除してください。

```bash theme={null}
npx wrangler delete
npx wrangler hyperdrive delete <HYPERDRIVE_ID>
npx wrangler cert delete --name managed-postgres-ca
```

`wrangler cert delete` の実行時に `Certificate cannot be deleted while in use` というエラーが表示された場合は、Hyperdrive の設定を削除してから 1 分ほど待ち、再度実行してください。

<h2 id="next-steps">
  次のステップ
</h2>

* [接続](/ja/products/managed-postgres/connection): 接続文字列、PgBouncer、TLS
* [設定](/ja/products/managed-postgres/settings): `max_connections` などの Postgres パラメータ
* [読み取りレプリカ](/ja/products/managed-postgres/read-replicas): 読み取りトラフィックのスケーリング
* [Hyperdrive ドキュメント](https://developers.cloudflare.com/hyperdrive/): クエリキャッシュ、接続 pool のチューニング、オブザーバビリティ
