-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Serverside Rendering on Vercel fails; missing GLIBC_2.29 #15
Comments
@Mause we're using the NodeJS client - we're not sure, but perhaps this is new in 0.7.1? |
Which version does it work with? We can check for changes |
As Vercel is running on AWS Lambda as far as I know, I'm having a hard time imagining that this has worked before, as Lambda environments are currently based on Amazon Linux 2, which uses GLIBC 2.26. See https://repost.aws/questions/QUrXOioL46RcCnFGyELJWKLw/glibc-2-27-on-amazon-linux-2 I guess you could download my DuckDB for Lambda layer, and extract the build artifacts: https://github.com/tobilg/duckdb-nodejs-layer#arns |
Experiencing similar error on Vercel with both node 18.x and 16.x. https://github.com/pgzmnk/openb |
I therefor created https://www.npmjs.com/package/duckdb-lambda-x86 which should solve the actual issue. |
@archiewood any updates? |
I've encountered the same problem as described. Specifically, I'm using Environment:
Steps to Reproduce: docker run --rm -it node:14 bash In node:14 container mkdir app && cd app
yarn init -y
yarn add [email protected]
cd node_modules/duckdb
npm test Are there any necessary packages that I need to install? Tranlated by ChatGPT. Sorry for my english is not good. I hope there's no offense. |
@hanshino the default |
Here's a wrapper over // lib/duckdb.ts
let _query: Promise<(query: string) => any>
_query = import("duckdb-async")
.then(duckdb => duckdb.Database)
.then(Database => Database.create(":memory:"))
.then((db: any) => ((query: string) => db.all(query)))
.catch(async error => {
console.log("duckdb init error:", error)
let duckdb = await import("duckdb-lambda-x86");
let Database: any = await duckdb.Database;
const db = new Database(":memory:")
const connection = db.connect()
return (query: string) => {
return new Promise((resolve, reject) => {
connection.all(query, (err: any, res: any) => {
if (err) reject(err);
resolve(res);
})
})
}
})
export { _query } Sample API endpoint that uses it: // /api/query.ts
import { _query } from "@/lib/duckdb"
import { NextApiRequest, NextApiResponse } from "next";
// Convert BigInts to numbers
function replacer(key: string, value: any) {
if (typeof value === 'bigint') {
return Number(value)
} else {
return value;
}
}
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
const { body: { path } } = req
const query = await _query
const rows = await query(`select * from read_parquet("${path}")`) // 🚨 unsafe / SQLi 🚨
res.status(200).send(JSON.stringify(rows, replacer))
} |
FYI for others who run into this. I ended up using @tobilg's |
@michaelwallabi Thank you for the tip - replacing the binary at build/deploy time was by far the most ergonomic solution (and the only one that I was able to work for my project). Ideally running duck db in a lambda should be easy out of the box as it is a great use case, so I look forward to future releases that don't require hacks/workarounds. |
Even with replacing the binaries, I am getting the following issue on version 1.0.0. (I am on Vercel, Nodejs 20) Unhandled Rejection: [Error: IO Error: Can't find the home directory at '' Setting a homedirectory does also result in an error: Can anyone help me please? Thank you! |
@Dev-rick this worked for me on aws lambda! |
Like @iku000888, I do the following when creating a DB, which seems to work: const db = Database.create(":memory:");
let tempDirectory = tmpdir() || '/tmp';
await (await db).exec(`
SET home_directory='${tempDirectory}';
.... other settings here
`);
``` |
@iku000888 and @michaelwallabi Thanks for the input! Unfortunately I am now getting the following error (on Vercel), on local everything works fine with the same env variables. Error: HTTP Error: HTTP GET error on 'https://XXX.s3.amazonaws.com/XXX.parquet' (HTTP 400)] { My code is: const S3_LAKE_BUCKET_NAME = process.env.S3_LAKE_BUCKET_NAME
const AWS_S3_ACCESS_KEY = process.env['AWS_S3_ACCESS_KEY']
const AWS_S3_SECRET_KEY = process.env['AWS_S3_SECRET_KEY']
const AWS_S3_REGION = process.env['AWS_S3_REGION']
const retrieveDataFromParquet = async ({
key,
sqlStatement,
tableName,
}: {
key: string
sqlStatement: string
tableName: string
}) => {
try {
// Create a new DuckDB database connection
const db = await Database.create(':memory:')
console.log('Setting home directory...')
await db.all(`SET home_directory='/tmp';`)
console.log('Installing and loading httpfs extension...')
await db.all(`
INSTALL httpfs;
LOAD httpfs;
`)
console.log('Setting S3 credentials...')
await db.all(`
SET s3_region='${AWS_S3_REGION}';
SET s3_access_key_id='${AWS_S3_ACCESS_KEY}';
SET s3_secret_access_key='${AWS_S3_SECRET_KEY}';
`)
// Test S3 access
console.log('Testing S3 access...')
try {
const testResult = await db.all(`
SELECT * FROM parquet_metadata('s3://${S3_LAKE_BUCKET_NAME}/${key}');
`)
console.log('S3 access test result successfully loaded:')
} catch (s3Error) {
console.error('Error testing S3 access:', s3Error)
throw s3Error // Rethrow the error to stop execution
}
// Try to read file info without actually reading the file
console.log('Checking file info...')
try {
const fileInfo = await db.all(`
SELECT * FROM parquet_scan('s3://${S3_LAKE_BUCKET_NAME}/${key}') LIMIT 0;
`)
console.log('File info loaded')
} catch (fileError) {
console.error('Error checking file info:', fileError)
}
// If everything above works, try creating the table
console.log('Creating table...')
await db.all(
`CREATE TABLE ${tableName} AS SELECT * FROM parquet_scan('s3://${S3_LAKE_BUCKET_NAME}/${key}');`,
)
console.log('Table created successfully')
// Execute the query
const result = db.all(sqlStatement)
// Close the database connection
db.close()
// Send the result
return result as unknown as Promise<{ [k: string]: any }[]>
} catch (error) {
console.error('Error:', error)
return null
}
} |
Have a look at my implementation at https://github.com/tobilg/serverless-duckdb/blob/main/src/lib/awsSecret.ts and triggering https://github.com/tobilg/serverless-duckdb/blob/main/src/functions/queryS3Express.ts#L95 before any access to S3. Hint: IMO you also need to pass the I'm wondering why you're seeing a 400 status (invalid request), and not a 403 status though. |
Thank you, appreciate the feedback!
This is honestly not a "fault" from DuckDB, but from AWS using very outdated GLIBC versions in any Node runtimes before Node 20 (see https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html#runtimes-supported), as Node 20 now uses AL 2023 which has a updated GLIBC that should work with the normal |
Oh hm that is interesting. |
What happens?
When attempting to deploy some Javascript project to Vercel that leverages SSR and DuckDB; the build fails.
The error message being presented by DuckDB is
/lib64/libm.so.6: version 'GLIBC_2.29' not found (required by /vercel/path0/node_modules/duckdb/lib/binding/duckdb.node
.This has worked previously.
To Reproduce
This repo has a simple reproduction of the issue; simply create a vercel project based on this (or a fork), and the build will fail with the error message
https://github.com/ItsMeBrianD/duckdb-vercel-repro
OS:
Vercel
DuckDB Version:
0.7.1
DuckDB Client:
node
Full Name:
Brian Donald
Affiliation:
Evidence
Have you tried this on the latest
master
branch?Have you tried the steps to reproduce? Do they include all relevant data and configuration? Does the issue you report still appear there?
The text was updated successfully, but these errors were encountered: