Cloudflare Workers + Digital Ocean Managed Postgres DB

Hello, im trying to setup a simple JS POC using Cloudflare workers. tl;dr the worker will query a Postgres DB on Digital Ocean. And i can not make it work at all. I have tried both pg and postgres javascript libraries node_compat is set to true
import { Client } from "pg";

const client = new Client({
connectionString: "postgresql://u:p@host:p/name",
ssl: {
cert: `a redacted cert`,
},
});

export default {
async fetch(
request,
env,
ctx
) {

await client.connect();

const resp = Response.json(/**some response */);
// Close the database connection, but don't block returning the response
ctx.waitUntil(client.end());
return resp;
},
};
import { Client } from "pg";

const client = new Client({
connectionString: "postgresql://u:p@host:p/name",
ssl: {
cert: `a redacted cert`,
},
});

export default {
async fetch(
request,
env,
ctx
) {

await client.connect();

const resp = Response.json(/**some response */);
// Close the database connection, but don't block returning the response
ctx.waitUntil(client.end());
return resp;
},
};
Just running client.connect here will make the worker freak out running when making a request to the endpoint. ( Starting the worker with wrangler deploy src/index.js ) Errors out with
Error
Connection terminated unexpectedly
Error
Connection terminated unexpectedly
I have tested everything ™️ . Not sure what im doing wrong. Anyone have any insight or guidance?
4 Replies
Jan Piotrowski (janpio)
Have you tried connecting inside the function? You can't reuse connections across requests, so maybe this to prevent you even trying that.
Gagan Suie
Gagan Suie7mo ago
i agree with @Jan Piotrowski. For MongoDB we're doing something like this in index and then sending db to each function: export async function handleRequest(request: Request, env: any) { const db = mongodb({ apiKey: env.MONGODB_DATA_API, apiUrl: https://data.mongodb-api.com/app/${env.MONGODB_APP_ID}/endpoint/data/v1, dataSource: env.MONGODB_DATASOURCE, database: env.MONGODB_DATABASE }) router.get('/channels', async () => await getChannels(request, db))
g1zmo
g1zmo7mo ago
I see. Let me test that. Thank you Jan and Gagan 🙏🏻 alright i have tested that as well. No luck. It results in:
✘ [ERROR] Error: Connection terminated unexpectedly
✘ [ERROR] Error: Connection terminated unexpectedly
This is a (redacted) reproduction of what i have currently: https://github.com/MartinL83/cf-ps-repro/blob/master/src/index.js
Shane
Shane4mo ago
@g1zmo did you ever resolve this? Also using a digital ocean db and although my local db client can easily connect to it, Cloudflare worker can’t. I’m going to try to create a hyperdrive connection to the db and have the worker connect to hyperdrive. Otherwise there has to be some networking issue preventing it internally in the cloud providers. Migrating away from Supabase, which was hosted in aws. I was using a similar connection string. The only variable is Cloudflare reaching out to digital ocean’s network. @g1zmo That tested out! Connecting to the digital ocean managed DB through hyperdrive worked great. npx wrangler hyperdrive create ${name} --connection-string${DO's provided connection string including the ?sslmode=require} I know I'm a little late to the game, but I was pulling my hair out on this and even if you've moved past, cloudflare syncs these discord chats to their online help docs, so maybe can help someone else down the line. The good news is, the connection pooling they offer is free, so if you don't want to incur additional expenses down the line when they start charging, just don't use query cacheing, which is what they're planning on charging for. Also, I have a digital ocean created connection pool I use for some node instances I run on DO, but I used the direct DB connection string for hyperdrive, not the connection pool string. No clue why just connecting to the DB directly in the worker through an environment variable didn't work though.