跳转到内容
搜索文档

使用 Workers VPC 连接私有数据库(推荐)

最后更新 查看 MarkdownAgent 设置

Workers VPC 提供一种将 Hyperdrive 连接到私有数据库的方式,无需配置 Cloudflare Access 应用或服务令牌。只需创建指向数据库的 TCP VPC Service,并将其服务 ID 传递给 Hyperdrive。

有关 Tunnel 和 Access 方式,请参阅使用 Tunnel 连接私有数据库。

工作原理

当数据库隔离在私有网络(如虚拟私有云 ↗或本地网络)中时,必须启用从网络到 Cloudflare 的安全连接。

  • 使用 Cloudflare Tunnel 从私有网络到 Cloudflare 建立安全出站连接。
  • 使用 VPC Service 将 Worker 的流量通过隧道路由到数据库,无需 Cloudflare Access 应用或服务令牌。

从 Cloudflare Worker 到源数据库的请求经过 Hyperdrive、VPC Service 和由 cloudflared 建立的 Cloudflare Tunnel。cloudflared 必须在可访问数据库的私有网络中运行。

flowchart LR
    A[Cloudflare Worker] --> B[Hyperdrive] --> C[VPC Service] --> D[Cloudflare Tunnel] --> E[Private Database]

开始之前

所有教程都假设你已经完成了快速入门指南,该指南帮助你设置 Cloudflare Workers 账户、C3 ↗ 和 Wrangler。

前提条件

  • 私有网络中的数据库,已配置使用 TLS/SSL。
  • 在与数据库相同网络中运行的 Cloudflare Tunnel。
  • Cloudflare 账户上的 Connectivity Directory Admin 角色,用于创建 VPC Service。

1. 设置 Cloudflare Tunnel

若在与数据库相同网络中尚未运行隧道,请创建一个。

  1. 转到 Workers VPC 仪表板 ↗,选择 Tunnels(隧道) 标签页。

  2. 选择 Create(创建) 以创建隧道。

  3. 输入隧道名称并选择 Save tunnel(保存隧道)。

  4. 选择您的操作系统和架构。仪表板将提供安装说明。

  5. 按照提供的命令下载、安装并使用您的唯一令牌运行 cloudflared。

隧道必须能够从私有网络内访问数据库主机和端口。

完整隧道文档请参阅 Workers VPC 的 Cloudflare Tunnel。

2. 创建 TCP VPC Service

创建类型为 tcp 的 VPC Service 指向数据库。设置 --app-protocol 标志为 postgresql 或 mysql,以便 Hyperdrive 优化连接。

npx wrangler vpc service create my-postgres-db \
  --type tcp \
  --tcp-port 5432 \
  --app-protocol postgresql \
  --tunnel-id <YOUR_TUNNEL_ID> \
  --ipv4 <YOUR_DATABASE_IP>
npx wrangler vpc service create my-mysql-db \
  --type tcp \
  --tcp-port 3306 \
  --app-protocol mysql \
  --tunnel-id <YOUR_TUNNEL_ID> \
  --ipv4 <YOUR_DATABASE_IP>

替换:

  • <YOUR_TUNNEL_ID> 为步骤 1 中的隧道 ID。
  • <YOUR_DATABASE_IP> 为数据库的私有 IP 地址(例如 10.0.0.5)。也可使用 --hostname 配合 DNS 名称代替 --ipv4。

命令将返回服务 ID。保存此值供下一步使用。

也可从 Workers VPC 仪表板 ↗ 创建 TCP VPC Service。所有配置选项请参阅 VPC Service。

TLS 证书验证

与 Hyperdrive 默认不验证源服务器证书不同,Workers VPC 默认为 verify_full——它验证证书链和主机名。若数据库使用自签名证书或私有证书颁发机构(CA)的证书,除非调整验证模式,否则 TLS 握手将失败。

对于使用自签名证书的数据库,创建 VPC Service 时添加 --cert-verification-mode:

  • verify_ca — 验证证书链但跳过主机名验证。当数据库拥有由你控制的 CA 签名的证书但主机名与证书不匹配时使用。
  • disabled — 完全跳过证书验证。仅用于开发或测试。

例如,为使用自签名证书的 PostgreSQL 数据库创建 VPC Service:

npx wrangler vpc service create my-postgres-db \
  --type tcp \
  --tcp-port 5432 \
  --app-protocol postgresql \
  --tunnel-id <YOUR_TUNNEL_ID> \
  --ipv4 <YOUR_DATABASE_IP> \
  --cert-verification-mode verify_ca

要更新现有 VPC Service,使用 wrangler vpc service update 并带上相同标志。

完整验证模式列表请参阅 TLS 证书验证模式。

3. 创建 Hyperdrive 配置

使用 --service-id 标志将 Hyperdrive 指向创建的 VPC Service。使用 --service-id 时,不提供 --origin-host、--origin-port 或 --connection-string。Hyperdrive 通过 VPC Service 路由流量。

npx wrangler hyperdrive create <YOUR_CONFIG_NAME> \
  --service-id <YOUR_VPC_SERVICE_ID> \
  --database <DATABASE_NAME> \
  --user <DATABASE_USER> \
  --password <DATABASE_PASSWORD> \
  --scheme postgresql
npx wrangler hyperdrive create <YOUR_CONFIG_NAME> \
  --service-id <YOUR_VPC_SERVICE_ID> \
  --database <DATABASE_NAME> \
  --user <DATABASE_USER> \
  --password <DATABASE_PASSWORD> \
  --scheme mysql

替换:

  • <YOUR_VPC_SERVICE_ID> 为步骤 2 中的服务 ID。
  • <DATABASE_NAME> 为数据库名称。
  • <DATABASE_USER> 和 <DATABASE_PASSWORD> 为数据库凭据。

若成功,命令将输出包含 id 字段的 Hyperdrive 配置。复制此 ID 供下一步使用。

4. 将 Hyperdrive 绑定到 Worker

你必须在 Wrangler 配置文件 中创建绑定,Worker 才能连接 Hyperdrive 配置。绑定(binding) 使 Worker 能够访问 Cloudflare 开发者平台上的资源(如 Hyperdrive)。

要将 Hyperdrive 配置绑定到 Worker,请在 Wrangler 文件末尾添加以下内容:

{
	"hyperdrive": [
		{
			"binding": "HYPERDRIVE",
			"id": "<YOUR_DATABASE_ID>" // the ID associated with the Hyperdrive you just created
		}
	]
}
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "<YOUR_DATABASE_ID>"

具体说明:

  • 为 binding(绑定名称)设置的值(字符串)将在 Worker 中引用此数据库。本教程中将绑定命名为 HYPERDRIVE。
  • 绑定必须是有效的 JavaScript 变量名 ↗。例如 binding = "hyperdrive" 或 binding = "productionDB" 均为有效名称。
  • 绑定在 Worker 中可通过 env.<BINDING_NAME> 访问。

若开发时使用本地数据库,可在 Hyperdrive 配置中添加 localConnectionString,填入数据库连接字符串:

{
	"hyperdrive": [
		{
			"binding": "HYPERDRIVE",
			"id": "<YOUR_DATABASE_ID>", // the ID associated with the Hyperdrive you just created
			"localConnectionString": "<LOCAL_DATABASE_CONNECTION_URI>"
		}
	]
}
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "<YOUR_DATABASE_ID>"
localConnectionString = "<LOCAL_DATABASE_CONNECTION_URI>"

5. 查询数据库

使用 node-postgres ↗(pg)发送测试查询。

安装 node-postgres 驱动:

npm i pg@>8.16.3

若使用 TypeScript,安装类型包:

npm i -D @types/pg

在 wrangler.jsonc 中添加所需的 Node.js 兼容性标志和 Hyperdrive 绑定:

在 wrangler.jsonc 中添加 Node.js 兼容性标志和 Hyperdrive 绑定(binding):

{
	// required for database drivers to function
	"compatibility_flags": [
		"nodejs_compat"
	],
	// Set this to today's date
	"compatibility_date": "2026-08-17",
	"hyperdrive": [
		{
			"binding": "HYPERDRIVE",
			"id": "<your-hyperdrive-id-here>"
		}
	]
}
compatibility_flags = [ "nodejs_compat" ]
# Set this to today's date
compatibility_date = "2026-08-17"

[[hyperdrive]]
binding = "HYPERDRIVE"
id = "<your-hyperdrive-id-here>"

创建新的 Client 实例并传入 Hyperdrive connectionString:

// filepath: src/index.ts
import { Client } from "pg";

export default {
	async fetch(
		request: Request,
		env: Env,
		ctx: ExecutionContext,
	): Promise<Response> {
		// Create a new client instance for each request. Hyperdrive maintains the
		// underlying database connection pool, so creating a new client is fast.
		const client = new Client({
			connectionString: env.HYPERDRIVE.connectionString,
		});

		try {
			// Connect to the database
			await client.connect();

			// Perform a simple query
			const result = await client.query("SELECT * FROM pg_tables");

			return Response.json({
				success: true,
				result: result.rows,
			});
		} catch (error: any) {
			console.error("Database error:", error.message);

			return new Response("Internal error occurred", { status: 500 });
		}
	},
};

部署 Worker:

npx wrangler deploy

若访问已部署的 Worker 时收到数据库的 pg_tables 列表,说明 Hyperdrive 已通过 Workers VPC 连接到私有数据库。

使用 mysql2 ↗ 发送测试查询。

安装 mysql2 ↗ 驱动:

npm i mysql2@>3.13.0

在 wrangler.jsonc 中添加所需的 Node.js 兼容性标志和 Hyperdrive 绑定:

在 wrangler.jsonc 中添加 Node.js 兼容性标志和 Hyperdrive 绑定(binding):

{
	// required for database drivers to function
	"compatibility_flags": [
		"nodejs_compat"
	],
	// Set this to today's date
	"compatibility_date": "2026-08-17",
	"hyperdrive": [
		{
			"binding": "HYPERDRIVE",
			"id": "<your-hyperdrive-id-here>"
		}
	]
}
compatibility_flags = [ "nodejs_compat" ]
# Set this to today's date
compatibility_date = "2026-08-17"

[[hyperdrive]]
binding = "HYPERDRIVE"
id = "<your-hyperdrive-id-here>"

创建新的 connection 实例并传入 Hyperdrive 参数:

// mysql2 v3.13.0 or later is required
import { createConnection } from "mysql2/promise";

export default {
	async fetch(request, env, ctx): Promise<Response> {
		// Create a new connection on each request. Hyperdrive maintains the underlying
		// database connection pool, so creating a new connection is fast.
		const connection = await createConnection({
			host: env.HYPERDRIVE.host,
			user: env.HYPERDRIVE.user,
			password: env.HYPERDRIVE.password,
			database: env.HYPERDRIVE.database,
			port: env.HYPERDRIVE.port,

			// Required to enable mysql2 compatibility for Workers
			disableEval: true,
		});

		try {
			// Sample query
			const [results, fields] = await connection.query("SHOW tables;");

			// Return result rows as JSON
			return Response.json({ results, fields });
		} catch (e) {
			console.error(e);
			return Response.json(
				{ error: e instanceof Error ? e.message : e },
				{ status: 500 },
			);
		}
	},
} satisfies ExportedHandler<Env>;

部署 Worker:

npx wrangler deploy

若访问已部署的 Worker 时收到数据库的表列表,说明 Hyperdrive 已通过 Workers VPC 连接到私有数据库。

后续步骤

这篇文档对您有帮助吗?