跳转到内容
搜索文档

使用 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 账户、C3Wrangler

前提条件

  • 私有网络中的数据库,已配置使用 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 标志为 postgresqlmysql,以便 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-postgrespg)发送测试查询。

安装 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 连接到私有数据库。

后续步骤

这篇文档对您有帮助吗?